diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 225a2a7..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-.idea
-.vscode
-__pycache__
-test
-
-*.log
-.env*
\ No newline at end of file
diff --git a/.idea/shelf/___.xml b/.idea/shelf/___.xml
new file mode 100644
index 0000000..51670f5
--- /dev/null
+++ b/.idea/shelf/___.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git "a/.idea/shelf/\345\234\250\345\217\230\345\237\272\344\271\213\345\211\215\346\234\252\346\217\220\344\272\244\347\232\204\346\233\264\346\224\271_[\346\233\264\346\224\271]/shelved.patch" "b/.idea/shelf/\345\234\250\345\217\230\345\237\272\344\271\213\345\211\215\346\234\252\346\217\220\344\272\244\347\232\204\346\233\264\346\224\271_[\346\233\264\346\224\271]/shelved.patch"
new file mode 100644
index 0000000..aa80353
--- /dev/null
+++ "b/.idea/shelf/\345\234\250\345\217\230\345\237\272\344\271\213\345\211\215\346\234\252\346\217\220\344\272\244\347\232\204\346\233\264\346\224\271_[\346\233\264\346\224\271]/shelved.patch"
@@ -0,0 +1,1902 @@
+Index: core/computer/screen/__init__.py
+===================================================================
+diff --git a/core/computer/screen/__init__.py b/core/computer/screen/__init__.py
+deleted file mode 100644
+--- a/core/computer/screen/__init__.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,6 +0,0 @@
+-from .screen import Screen
+-
+-
+-__all__ = [Screen]
+-
+-__version__ = '1.0.0'
+\ No newline at end of file
+Index: core/computer/keyboard/__init__.py
+===================================================================
+diff --git a/core/computer/keyboard/__init__.py b/core/computer/keyboard/__init__.py
+deleted file mode 100644
+--- a/core/computer/keyboard/__init__.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,47 +0,0 @@
+-"""
+-键盘操作包
+-"""
+-from .keyboard import (
+- Keyboard,
+- type_text,
+- press,
+- hotkey,
+- key_down,
+- key_up,
+- hold_key,
+- copy,
+- paste,
+- cut,
+- select_all,
+- undo,
+- redo,
+- save,
+- find,
+- new_tab,
+- close_tab,
+- refresh,
+- switch_window
+-)
+-
+-__all__ = [
+- # Keyboard类和函数
+- 'Keyboard',
+- 'type_text',
+- 'press',
+- 'hotkey',
+- 'key_down',
+- 'key_up',
+- 'hold_key',
+- 'copy',
+- 'paste',
+- 'cut',
+- 'select_all',
+- 'undo',
+- 'redo',
+- 'save',
+- 'find',
+- 'new_tab',
+- 'close_tab',
+- 'refresh',
+- 'switch_window',
+-]
+Index: core/computer/code/languages/powershell.py
+===================================================================
+diff --git a/core/computer/code/languages/powershell.py b/core/computer/code/languages/powershell.py
+deleted file mode 100644
+--- a/core/computer/code/languages/powershell.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,64 +0,0 @@
+-import queue
+-import shutil
+-import subprocess
+-import threading
+-import time
+-
+-from ..base_language import BaseLanguage
+-
+-
+-class PowerShellLanguage(BaseLanguage):
+- def __init__(self):
+- super().__init__()
+- self.process = None
+-
+- def is_available(self):
+- return shutil.which("powershell") is not None or shutil.which("pwsh") is not None
+-
+- def run(self, code: str):
+- message = queue.Queue()
+- execution_thread = threading.Thread(target=self._execute, args=(code, message))
+- execution_thread.daemon = True
+- execution_thread.start()
+- return message
+-
+- def _execute(self, code: str, message: queue.Queue):
+- self.is_running = True
+- self.start_time = time.time()
+- self.should_stop = False
+-
+- executable = "pwsh" if shutil.which("pwsh") else "powershell"
+-
+- try:
+- # -Command - tells powershell to read command from stdin
+- self.process = subprocess.Popen(
+- [executable, "-NoProfile", "-Command", code],
+- stdout=subprocess.PIPE,
+- stderr=subprocess.STDOUT,
+- text=True,
+- bufsize=1,
+- universal_newlines=True
+- )
+-
+- for line in self.process.stdout:
+- if self.should_stop:
+- break
+- message.put({"type": "text", "content": line})
+-
+- return_code = self.process.wait()
+- message.put({"type": "text", "content": f"Return code: {return_code}"})
+-
+- except Exception as e:
+- message.put({"type": "error", "content": f"[PowerShellLanguage]Error: {e}"})
+- finally:
+- self.is_running = False
+- self.process = None
+-
+- def interrupt(self):
+- super().interrupt()
+- if self.process:
+- self.process.terminate()
+- try:
+- self.process.wait(timeout=2)
+- except subprocess.TimeoutExpired:
+- self.process.kill()
+Index: core/computer/mouse/mouse.py
+===================================================================
+diff --git a/core/computer/mouse/mouse.py b/core/computer/mouse/mouse.py
+deleted file mode 100644
+--- a/core/computer/mouse/mouse.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,368 +0,0 @@
+-import pyautogui
+-import time
+-from typing import Tuple, Optional, Union
+-
+-
+-class Mouse:
+- """鼠标操作类,提供各种鼠标控制功能"""
+-
+- def __init__(self):
+- """初始化鼠标模块"""
+- # 设置PyAutoGUI的安全特性
+- pyautogui.FAILSAFE = True # 移动鼠标到屏幕左上角会触发异常
+- pyautogui.PAUSE = 0.1 # 每次操作后暂停0.1秒
+-
+- def click(self, x: Optional[int] = None, y: Optional[int] = None,
+- clicks: int = 1, interval: float = 0.0,
+- button: str = 'left', duration: float = 0.0) -> dict:
+- """
+- 鼠标点击操作
+-
+- Args:
+- x: X坐标,None表示当前位置
+- y: Y坐标,None表示当前位置
+- clicks: 点击次数,默认1次
+- interval: 多次点击之间的间隔(秒)
+- button: 鼠标按键 'left'/'right'/'middle'
+- duration: 移动到目标位置的持续时间(秒)
+-
+- Returns:
+- 包含操作结果的字典
+-
+- Examples:
+- >>> mouse.click(100, 200) # 点击坐标(100, 200)
+- >>> mouse.click() # 点击当前位置
+- >>> mouse.click(button='right') # 右键点击当前位置
+- """
+- try:
+- if x is not None and y is not None:
+- pyautogui.click(x, y, clicks=clicks, interval=interval,
+- button=button, duration=duration)
+- else:
+- pyautogui.click(clicks=clicks, interval=interval, button=button)
+-
+- current_pos = pyautogui.position()
+- return {
+- 'success': True,
+- 'action': 'click',
+- 'position': (current_pos.x, current_pos.y),
+- 'button': button,
+- 'clicks': clicks
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'action': 'click',
+- 'error': str(e)
+- }
+-
+- def double_click(self, x: Optional[int] = None, y: Optional[int] = None,
+- button: str = 'left', duration: float = 0.0) -> dict:
+- """
+- 鼠标双击操作
+-
+- Args:
+- x: X坐标,None表示当前位置
+- y: Y坐标,None表示当前位置
+- button: 鼠标按键 'left'/'right'/'middle'
+- duration: 移动到目标位置的持续时间(秒)
+-
+- Returns:
+- 包含操作结果的字典
+-
+- Examples:
+- >>> mouse.double_click(300, 400) # 双击坐标(300, 400)
+- """
+- return self.click(x, y, clicks=2, button=button, duration=duration)
+-
+- def right_click(self, x: Optional[int] = None, y: Optional[int] = None,
+- duration: float = 0.0) -> dict:
+- """
+- 鼠标右键点击
+-
+- Args:
+- x: X坐标,None表示当前位置
+- y: Y坐标,None表示当前位置
+- duration: 移动到目标位置的持续时间(秒)
+-
+- Returns:
+- 包含操作结果的字典
+-
+- Examples:
+- >>> mouse.right_click(500, 300) # 右键点击坐标(500, 300)
+- """
+- return self.click(x, y, button='right', duration=duration)
+-
+- def move(self, x: int, y: int, duration: float = 0.0) -> dict:
+- """
+- 移动鼠标到指定位置
+-
+- Args:
+- x: 目标X坐标
+- y: 目标Y坐标
+- duration: 移动持续时间(秒),0表示立即移动
+-
+- Returns:
+- 包含操作结果的字典
+-
+- Examples:
+- >>> mouse.move(800, 600) # 立即移动到(800, 600)
+- >>> mouse.move(800, 600, duration=1.0) # 用1秒时间移动到(800, 600)
+- """
+- try:
+- pyautogui.moveTo(x, y, duration=duration)
+- current_pos = pyautogui.position()
+- return {
+- 'success': True,
+- 'action': 'move',
+- 'position': (current_pos.x, current_pos.y),
+- 'duration': duration
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'action': 'move',
+- 'error': str(e)
+- }
+-
+- def move_rel(self, x_offset: int, y_offset: int, duration: float = 0.0) -> dict:
+- """
+- 相对移动鼠标(从当前位置偏移)
+-
+- Args:
+- x_offset: X轴偏移量
+- y_offset: Y轴偏移量
+- duration: 移动持续时间(秒)
+-
+- Returns:
+- 包含操作结果的字典
+-
+- Examples:
+- >>> mouse.move_rel(100, 0) # 向右移动100像素
+- """
+- try:
+- pyautogui.moveRel(x_offset, y_offset, duration=duration)
+- current_pos = pyautogui.position()
+- return {
+- 'success': True,
+- 'action': 'move_rel',
+- 'position': (current_pos.x, current_pos.y),
+- 'offset': (x_offset, y_offset),
+- 'duration': duration
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'action': 'move_rel',
+- 'error': str(e)
+- }
+-
+- def drag(self, x: int, y: int, duration: float = 0.5,
+- button: str = 'left') -> dict:
+- """
+- 拖拽鼠标到指定位置
+-
+- Args:
+- x: 目标X坐标
+- y: 目标Y坐标
+- duration: 拖拽持续时间(秒)
+- button: 使用的鼠标按键
+-
+- Returns:
+- 包含操作结果的字典
+-
+- Examples:
+- >>> mouse.drag(500, 500, duration=1.0) # 拖拽到(500, 500)
+- """
+- try:
+- pyautogui.drag(x, y, duration=duration, button=button)
+- current_pos = pyautogui.position()
+- return {
+- 'success': True,
+- 'action': 'drag',
+- 'position': (current_pos.x, current_pos.y),
+- 'button': button,
+- 'duration': duration
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'action': 'drag',
+- 'error': str(e)
+- }
+-
+- def drag_rel(self, x_offset: int, y_offset: int, duration: float = 0.5,
+- button: str = 'left') -> dict:
+- """
+- 相对拖拽(从当前位置偏移)
+-
+- Args:
+- x_offset: X轴偏移量
+- y_offset: Y轴偏移量
+- duration: 拖拽持续时间(秒)
+- button: 使用的鼠标按键
+-
+- Returns:
+- 包含操作结果的字典
+-
+- Examples:
+- >>> mouse.drag_rel(100, 50) # 向右下拖拽
+- """
+- try:
+- pyautogui.dragRel(x_offset, y_offset, duration=duration, button=button)
+- current_pos = pyautogui.position()
+- return {
+- 'success': True,
+- 'action': 'drag_rel',
+- 'position': (current_pos.x, current_pos.y),
+- 'offset': (x_offset, y_offset),
+- 'button': button,
+- 'duration': duration
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'action': 'drag_rel',
+- 'error': str(e)
+- }
+-
+- def scroll(self, clicks: int, x: Optional[int] = None,
+- y: Optional[int] = None) -> dict:
+- """
+- 滚动鼠标滚轮
+-
+- Args:
+- clicks: 滚动单位数,正数向上滚动,负数向下滚动
+- x: 在指定位置滚动的X坐标(可选)
+- y: 在指定位置滚动的Y坐标(可选)
+-
+- Returns:
+- 包含操作结果的字典
+-
+- Examples:
+- >>> mouse.scroll(5) # 向上滚动5个单位
+- >>> mouse.scroll(-3) # 向下滚动3个单位
+- >>> mouse.scroll(5, 500, 500) # 在(500, 500)位置向上滚动
+- """
+- try:
+- if x is not None and y is not None:
+- pyautogui.scroll(clicks, x, y)
+- else:
+- pyautogui.scroll(clicks)
+-
+- return {
+- 'success': True,
+- 'action': 'scroll',
+- 'clicks': clicks,
+- 'position': (x, y) if x and y else 'current'
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'action': 'scroll',
+- 'error': str(e)
+- }
+-
+- def get_position(self) -> dict:
+- """
+- 获取当前鼠标位置
+-
+- Returns:
+- 包含鼠标位置的字典
+-
+- Examples:
+- >>> pos = mouse.get_position()
+- >>> print(f"鼠标位置: ({pos['x']}, {pos['y']})")
+- """
+- try:
+- pos = pyautogui.position()
+- return {
+- 'success': True,
+- 'x': pos.x,
+- 'y': pos.y,
+- 'position': (pos.x, pos.y)
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'error': str(e)
+- }
+-
+- def mouse_down(self, x: Optional[int] = None, y: Optional[int] = None,
+- button: str = 'left') -> dict:
+- """
+- 按下鼠标按键(不释放)
+-
+- Args:
+- x: X坐标(可选)
+- y: Y坐标(可选)
+- button: 鼠标按键
+-
+- Returns:
+- 包含操作结果的字典
+- """
+- try:
+- if x is not None and y is not None:
+- pyautogui.mouseDown(x, y, button=button)
+- else:
+- pyautogui.mouseDown(button=button)
+-
+- return {
+- 'success': True,
+- 'action': 'mouse_down',
+- 'button': button
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'action': 'mouse_down',
+- 'error': str(e)
+- }
+-
+- def mouse_up(self, x: Optional[int] = None, y: Optional[int] = None,
+- button: str = 'left') -> dict:
+- """
+- 释放鼠标按键
+-
+- Args:
+- x: X坐标(可选)
+- y: Y坐标(可选)
+- button: 鼠标按键
+-
+- Returns:
+- 包含操作结果的字典
+- """
+- try:
+- if x is not None and y is not None:
+- pyautogui.mouseUp(x, y, button=button)
+- else:
+- pyautogui.mouseUp(button=button)
+-
+- return {
+- 'success': True,
+- 'action': 'mouse_up',
+- 'button': button
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'action': 'mouse_up',
+- 'error': str(e)
+- }
+-
+-
+-# 创建全局实例,支持直接调用
+-_mouse_instance = Mouse()
+-
+-# 导出便捷函数
+-click = _mouse_instance.click
+-double_click = _mouse_instance.double_click
+-right_click = _mouse_instance.right_click
+-move = _mouse_instance.move
+-move_rel = _mouse_instance.move_rel
+-drag = _mouse_instance.drag
+-drag_rel = _mouse_instance.drag_rel
+-scroll = _mouse_instance.scroll
+-get_position = _mouse_instance.get_position
+-mouse_down = _mouse_instance.mouse_down
+-mouse_up = _mouse_instance.mouse_up
+\ No newline at end of file
+Index: core/llm/code/agent.py
+===================================================================
+diff --git a/core/llm/code/agent.py b/core/llm/code/agent.py
+deleted file mode 100644
+--- a/core/llm/code/agent.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,202 +0,0 @@
+-import logging
+-import os
+-import time
+-import queue
+-import threading
+-from queue import Queue
+-from dotenv import load_dotenv
+-from litellm import completion
+-from core.computer.code import Code
+-from .default_prompt import default_prompt, default_prompt_end
+-from .code_parser import CodeParser
+-
+-dotenv_path = os.path.join(os.path.dirname(__file__), ".env")
+-load_dotenv(dotenv_path)
+-
+-class CodeAgent:
+- def __init__(self):
+- self.code_executer = Code()
+- self.SYSTEM_PROMPT = default_prompt.format(language=str(self.code_executer.language_list))
+- logging.info("[CodeAgent]"+self.SYSTEM_PROMPT)
+- self.SYSTEM_PROMPT_END = default_prompt_end
+- self.loop_breakers = ["The task is done.", "The task is impossible."]
+- self.model = os.getenv("CodeAgent_MODEL")
+- self.api_base = os.getenv("CodeAgent_API_BASE")
+- self.api_key = os.getenv("CodeAgent_API_KEY")
+- self.stop_code = False
+- self.stop_agent = False
+- self.permission = None
+-
+- def _listener(self, message_from_client: Queue):
+- """
+- 监听来自客户端的信息
+- :param message_from_client:
+- :return:
+- """
+- while True:
+- try:
+- message = message_from_client.get(timeout=0.5)
+- except queue.Empty:
+- continue
+- print("get client message")
+- # 不是发给CodeAgent的信息,放回
+- if message["name"] != "CodeAgent":
+- message_from_client.put(message)
+- continue
+- # 允许执行代码
+- if message["type"] == "request":
+- if message["content"] == "deny":
+- self.permission = False
+- logging.info("[CodeAgent]User denied execution")
+- elif message["content"] == "approve":
+- self.permission = True
+- logging.info("[CodeAgent]User approved execution")
+- # 停止相关
+- elif message["content"] == "stop_agent":
+- self.stop_agent = True
+- logging.info("[CodeAgent]User stopped agent")
+- elif message["content"] == "stop_code":
+- self.stop_code = True
+- logging.info("[CodeAgent]User stopped code execution")
+-
+- def _should_stop(self, ai_content: str = None):
+- if ai_content:
+- for loop_breaker in self.loop_breakers:
+- if loop_breaker in ai_content:
+- return True
+- return False
+-
+- def task(self, description: str, message_from_client: Queue, message_to_client: Queue):
+- self.stop_agent = False
+- messages = [
+- {"role": "system", "content": self.SYSTEM_PROMPT},
+- {"role": "user", "content": description}]
+- listener_thread = threading.Thread(target=self._listener, args=(message_from_client,))
+- listener_thread.daemon = True
+- listener_thread.start()
+- logging.info("[CodeAgent][START]")
+- message_to_client.put({"name": "CodeAgent", "type": "status", "content": "[START]"})
+-
+- while not self.stop_agent:
+- # 请求ai对话
+- response = completion(
+- model=self.model,
+- api_base=self.api_base,
+- api_key=self.api_key,
+- messages=messages,
+- stream=True,
+- )
+- # 流式返回
+- message_to_client.put({"name": "CodeAgent", "type": "ai_content", "content": "[BEGIN]"})
+- ai_content = ""
+- for chunk in response:
+- # 检查是否需要停止
+- if self.stop_agent:
+- logging.info("[CodeAgent][STOP]: User stop")
+- message_to_client.put({"name": "CodeAgent", "type": "status", "content": "[STOP]"})
+- return
+- if chunk.choices[0].delta.content:
+- delta = chunk.choices[0].delta.content
+- message_to_client.put({"name": "CodeAgent", "type": "ai_content", "content": delta})
+- ai_content += delta
+- message_to_client.put({"name": "CodeAgent", "type": "ai_content", "content": "[END]"})
+- messages.append({"role": "assistant", "content": ai_content})
+-
+- # 检查ai是否想要停止
+- if self._should_stop(ai_content):
+- break
+-
+- # TODO: If the context is too long, use RAG or other methods to handle it
+- # if len(messages) > 10:
+- # messages = [messages[0]] + messages[-5:]
+-
+- # 获取模型返回的代码
+- codes = CodeParser(ai_content)
+- if not codes:
+- messages.append({"role": "user", "content": "No code blocks found. Skip execution. " + self.SYSTEM_PROMPT_END})
+- continue
+-
+- # 依次执行代码
+- logging.info(f"Find {len(codes)} code blocks. Executing...")
+- for i in range(len(codes)):
+-
+- logging.info(f"Executing code block {i}..., code: {codes[i]}")
+- code = codes[i]
+- self.permission = None
+- message_to_client.put({"name": "CodeAgent", "type": "status", "content": f"[BLOCK{i}]"})
+- message_to_client.put({"name": "CodeAgent", "type": "request", "content": f"[BLOCK{i}]need_permission"})
+-
+- # 阻塞等待客户端返回允许结果
+- print("wtf???")
+- while self.permission is None:
+- logging.info("waiting permission")
+- print("waiting permission")
+- # 检查是否需要停止
+- time.sleep(0.5)
+- if self.stop_agent:
+- logging.info("[CodeAgent][STOP]: User stop")
+- message_to_client.put({"name": "CodeAgent", "type": "status", "content": "[STOP]"})
+- return
+- if not self.permission:
+- logging.info(f"User rejected to excecute code block{i}")
+- messages.append({"role": "user", "content": f"User rejected to excecute code block{i}"})
+- continue
+-
+- logging.info(f"User approved to excecute code block {i}, start executing")
+- results = self.code_executer.run(lang=code["lang"], code=code["code"]) # 正确解包
+- code_output_content = [{"type": "text", "text": f"Code block{i} is executed, and the output is as follows:"}]
+-
+- self.stop_code = False
+- while self.code_executer.is_running() or not results.empty():
+- logging.info(f"[CodeAgent]: Code block{i} is running, code_executer:{self.code_executer.is_running()}, results.empty():{results.empty()}")
+- # 检查是否需要停止
+- if self.stop_code or self.stop_agent:
+- self.code_executer.interrupt()
+- break
+-
+- try:
+- delta = results.get(timeout=0.2)
+- except queue.Empty:
+- continue
+-
+- # TODO: 有bug,图片先不返回
+- if delta["type"] == "image/png" or delta["type"] == "image/jpeg":
+- # pass
+- message_to_client.put({"name": "CodeAgent", **delta})
+- code_output_content.append(
+- {
+- "type": "image_url",
+- "image_url": {
+- "url": f"data:{delta["type"]};base64,{delta["content"]}"
+- }
+- }
+- )
+- else: # 暂时把其他所有内容转为text
+- message_to_client.put({"name": "CodeAgent", "type": "text", "content": delta["content"]})
+- code_output_content.append(
+- {
+- "type": "text",
+- "text": delta["content"]
+- }
+- )
+-
+- logging.info(f"Finish executing code block {i}")
+- messages.append({"role": "user", "content": code_output_content})
+-
+- messages.append({"role": "user", "content": "All code blocks are executed. " + self.SYSTEM_PROMPT_END})
+-
+- logging.info("[CodeAgent][STOP]: task finished")
+- message_to_client.put({"name": "CodeAgent", "type": "status", "content": "[STOP]"})
+- return messages[-1]["content"]
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+Index: core/computer/code/code.py
+===================================================================
+diff --git a/core/computer/code/code.py b/core/computer/code/code.py
+deleted file mode 100644
+--- a/core/computer/code/code.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,74 +0,0 @@
+-import queue
+-
+-from .languages import PythonLanguage, BashLanguage, PowerShellLanguage
+-
+-
+-class Code:
+- def __init__(self):
+- self.python = PythonLanguage()
+- # self.cmd = CMDLanguage()
+- self.bash = BashLanguage()
+- self.powershell = PowerShellLanguage()
+- self.current_language = None
+- self.language_map = {
+- "python": self.python,
+- # "cmd": self.cmd,
+- "powershell": self.powershell,
+- "pwsh": self.powershell, # PowerShell Core别名
+- "bash": self.bash,
+- "sh": self.bash, # Shell别名
+- }
+- self.language_list = []
+- for lang, lang_obj in self.language_map.items():
+- if hasattr(lang_obj, 'is_available'):
+- if lang_obj.is_available():
+- self.language_list.append(lang)
+- else:
+- # Python总是可用的
+- self.language_list.append(lang)
+-
+- # def language_list(self):
+- # available = []
+-
+- def run(self, lang: str, code: str):
+- """
+- 运行代码
+-
+- :param lang: 要运行的代码语言
+- :type lang: str
+- :param code: 要运行的代码
+- :type code: str
+- """
+- lang = lang.lower()
+- if lang in self.language_list:
+- self.current_language = self.language_map[lang]
+- return self.current_language.run(code)
+- else:
+- message = queue.Queue()
+- message.put({"type": "error", "content": f"[Code]Unsupported language:{lang}"})
+- return message
+-
+- def interrupt(self):
+- """
+- 中断执行中的代码
+- """
+- message = queue.Queue()
+- if self.current_language and self.current_language.is_running:
+- self.current_language.interrupt()
+- message.put({"type": "text", "content": "Code execution interrupted"})
+- else:
+- message.put({"type": "text", "content": "No code is running"})
+- return message
+-
+- def get_elapsed_time(self):
+- """
+- 获取代码已运行时间
+- """
+- if self.current_language:
+- return self.current_language.get_elapsed_time()
+-
+- def is_running(self):
+- """
+- 代码是否正在运行
+- """
+- return self.current_language and self.current_language.is_running
+\ No newline at end of file
+Index: core/computer/code/languages/__init__.py
+===================================================================
+diff --git a/core/computer/code/languages/__init__.py b/core/computer/code/languages/__init__.py
+deleted file mode 100644
+--- a/core/computer/code/languages/__init__.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,12 +0,0 @@
+-"""
+-
+-"""
+-
+-
+-from .bash import BashLanguage
+-from .powershell import PowerShellLanguage
+-from .python import PythonLanguage
+-
+-__all__ = ['PythonLanguage', 'BashLanguage', 'PowerShellLanguage']
+-
+-__version__ = '1.0.0'
+\ No newline at end of file
+Index: core/llm/code/消息设计.md
+===================================================================
+diff --git a/core/llm/code/消息设计.md b/core/llm/code/消息设计.md
+deleted file mode 100644
+--- a/core/llm/code/消息设计.md (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,83 +0,0 @@
+-# 消息设计 (Message Design)
+-
+-Agent 与客户端(UI)之间通过 `Queue` 进行通信,消息格式为 JSON 字典。
+-
+-## 1. 客户端 -> Agent (Client to Agent)
+-客户端发送的消息主要用于控制 Agent 的行为和响应权限请求。
+-
+-**基本格式:**
+-```json
+-{
+- "name": "CodeAgent", // 给谁发送就填谁
+- "type": "request",
+- "content": "指令内容"
+-}
+-```
+-
+-**指令内容 (content):**
+-- `approve`: 允许执行当前代码块。
+-- `deny`: 拒绝执行当前代码块。
+-- `stop_agent`: 停止整个 Agent 任务。
+-- `stop_code`: 停止当前正在执行的代码(中断执行)。
+-
+-## 3. Agent -> 客户端 (Agent to Client)
+-Agent 发送的消息用于更新状态、流式传输 AI 回复、请求权限以及展示代码执行结果。
+-
+-**基本格式:**
+-```json
+-{
+- "name": "CodeAgent",
+- "type": "消息类型",
+- "content": "消息内容"
+-}
+-```
+-
+-### 3.1 状态消息 (type: "status")
+-用于通知 UI 当前 Agent 的工作阶段。
+-- `[START]`: 任务开始。
+-- `[STOP]`: 任务结束(完成或被用户停止)。
+-- `[BLOCK{i}]`: 正在处理第 `i` 个代码块(准备执行)。
+-
+-### 3.2 AI 内容流 (type: "ai_content")
+-用于流式展示 LLM 的思考和回复过程。
+-- `[BEGIN]`: 开始生成内容。
+-- `[END]`: 内容生成结束。
+-- ``: AI 生成的文本片段(增量更新)。
+-
+-### 3.3 权限请求 (type: "request")
+-当 Agent 解析出代码块并准备执行时,向 UI 请求权限。
+-- `[BLOCK{i}]need_permission`: 请求执行第 `i` 个代码块的权限。
+- - UI 收到此消息后应显示“批准/拒绝”按钮。
+-
+-### 3.4 代码执行输出 (type: "text" / "image/png" 等)
+-展示代码执行的实时输出。
+-
+-- **文本输出 (type: "text"):**
+- - `content`: 标准输出 (stdout) 或标准错误 (stderr) 的文本内容。
+-
+-- **图片输出 (type: "image/png" / "image/jpeg"):**
+- - *注意: 目前 `agent.py` 中图片处理逻辑被注释/跳过,需要修复才能正常接收图片。*
+- - `content`: Base64 编码的图片数据。
+-
+-- **其他类型:**
+- - `html`: HTML 内容。
+- - `javascript`: JS 代码。
+- - `error`: 执行错误信息。
+-
+-## 4. 交互流程示例 (Interaction Flow)
+-
+-调用`CodeAgent.task("任务描述")`之后:
+-
+-1. **任务开始**: Agent 发送 `status: [START]`。
+-2. **AI 思考**: Agent 发送 `ai_content: [BEGIN]`, 随后发送多条内容片段, 最后发送 `ai_content: [END]`。
+-3. **代码解析**: Agent 发现代码块。(Agent发现的代码块并不会传给客户端,客户端需要自己按顺序切分代码片段)
+-4. **请求权限**: Agent 发送 `status: [BLOCK0]`, `request: [BLOCK0]need_permission`。
+-5. **用户确认**: 客户端发送 `content: approve`。
+-6. **代码执行**: Agent 执行代码,持续发送 `type: text` (日志/结果)。
+-7. **执行完成**: Agent 继续下一轮或结束。
+-8. **任务结束**: Agent 发送 `status: [STOP]`。
+-
+-## 5. TODO (Suggestions)
+-1. **修复图片传输**: base64太长,之后可以采取压缩方法
+-2. **结构化状态**: 目前的 `[START]` 等状态码混在 `content` 字符串中,建议后续优化为独立的枚举字段,方便前端解析。
+-3. **上下文未处理**
+Index: core/computer/mouse/__init__.py
+===================================================================
+diff --git a/core/computer/mouse/__init__.py b/core/computer/mouse/__init__.py
+deleted file mode 100644
+--- a/core/computer/mouse/__init__.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,33 +0,0 @@
+-"""
+-鼠标操作包
+-"""
+-from .mouse import (
+- Mouse,
+- click,
+- double_click,
+- right_click,
+- move,
+- move_rel,
+- drag,
+- drag_rel,
+- scroll,
+- get_position,
+- mouse_down,
+- mouse_up
+-)
+-
+-__all__ = [
+- # Mouse类和函数
+- 'Mouse',
+- 'click',
+- 'double_click',
+- 'right_click',
+- 'move',
+- 'move_rel',
+- 'drag',
+- 'drag_rel',
+- 'scroll',
+- 'get_position',
+- 'mouse_down',
+- 'mouse_up',
+-]
+\ No newline at end of file
+Index: core/computer/code/__init__.py
+===================================================================
+diff --git a/core/computer/code/__init__.py b/core/computer/code/__init__.py
+deleted file mode 100644
+--- a/core/computer/code/__init__.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,11 +0,0 @@
+-"""
+-代码运行包
+-"""
+-
+-
+-from .base_language import BaseLanguage
+-from .code import Code
+-
+-__all__ = ['Code', 'BaseLanguage']
+-
+-__version__ = '1.0.0'
+\ No newline at end of file
+Index: core/computer/screen/screen.py
+===================================================================
+diff --git a/core/computer/screen/screen.py b/core/computer/screen/screen.py
+deleted file mode 100644
+--- a/core/computer/screen/screen.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,35 +0,0 @@
+-import base64
+-import io
+-
+-from PIL import Image, ImageGrab
+-
+-
+-class Screen:
+- def __init__(self):
+- pass
+- def screenshot(self, resize_factor: float = 0.5, format: str= "png", quality: int = 100):
+- """
+- 获取截屏
+- :param resize_factor: 缩放因子
+- :param format: 格式,可选png/jpeg
+- :param quality: 图片质量,jpeg有效
+- :return: [{"type": f"image/{format}", "content": base64_encoded}]
+- """
+- image = ImageGrab.grab()
+- new_width = int(image.size[0] * resize_factor)
+- new_height = int(image.size[1] * resize_factor)
+- image = image.resize((new_width, new_height), Image.LANCZOS)
+-
+- img_byte_arr= io.BytesIO()
+- format = format.lower()
+- if format == "png":
+- image.save(img_byte_arr, format=format)
+- elif format == "jpeg":
+- image.save(img_byte_arr, format=format, quality=quality)
+- else:
+- raise ValueError("[Screen]Unsupported format: ", format)
+-
+- img_bytes = img_byte_arr.getvalue()
+- base64_encoded = base64.b64encode(img_bytes).decode('utf-8')
+-
+- return [{"type": f"image/{format}", "content": base64_encoded}]
+\ No newline at end of file
+Index: core/computer/code/languages/python.py
+===================================================================
+diff --git a/core/computer/code/languages/python.py b/core/computer/code/languages/python.py
+deleted file mode 100644
+--- a/core/computer/code/languages/python.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,131 +0,0 @@
+-import logging
+-import queue
+-import re
+-import threading
+-import time
+-
+-from jupyter_client.manager import KernelManager
+-
+-from ..base_language import BaseLanguage
+-
+-
+-class PythonLanguage(BaseLanguage):
+- def __init__(self):
+- super().__init__()
+- self.km = None
+- self.kc = None
+- self.current_msg_id = None
+-
+- def start(self):
+- self.should_stop = False
+- self.start_time = time.time()
+- self.elapsed_time = 0
+-
+- if self.km:
+- self.stop()
+- try:
+- self.km = KernelManager(kernel_name='python3')
+- self.is_running = True
+- self.km.start_kernel()
+- self.kc = self.km.client()
+- self.kc.start_channels()
+- self.kc.wait_for_ready()
+- logging.info("[PythonLanguage]Started kernel client&manager")
+- except Exception as e:
+- self.stop()
+- logging.error("[PythonLanguage]Error starting kernel: %s", e)
+-
+- def stop(self):
+- self.is_running = False
+- if self.start_time:
+- self.elapsed_time = time.time() - self.start_time
+- self.start_time = None
+-
+- try:
+- if self.km:
+- self.km.shutdown_kernel()
+- self.is_running = False
+- self.km = None
+- if self.kc:
+- self.kc.stop_channels()
+- self.current_msg_id = None
+- self.kc = None
+- logging.info("[PythonLanguage]Stopped kernel client&manager")
+- except Exception as e:
+- logging.error("[PythonLanguage]Error during cleanup kernel: %s", e)
+-
+- def wait_for_shutdown(self):
+- while self.is_running or self.kc:
+- time.sleep(0.1)
+-
+- def run(self, code: str):
+- message = queue.Queue()
+-
+- excecution_thread = threading.Thread(target=self._execute_jupyter, args=(code, message))
+- excecution_thread.daemon = True
+- excecution_thread.start()
+-
+- return message
+-
+- def _execute_jupyter(self, code: str, message: queue.Queue):
+- self.start()
+-
+- if self.km.is_alive() is False:
+- message.put({"type": "error", "content": "[PythonLanguage]Faild to start Jupyter kernel"})
+- return
+-
+- # 只在需要时添加matplotlib魔法命令
+- if "matplotlib" in code and "%matplotlib" not in code:
+- code = "%matplotlib inline\n" + code
+-
+- try:
+- self.current_msg_id=self.kc.execute(code)
+- except Exception as e:
+- message.put({"type": "error", "content": f"[PythonLanguage]Error while executing code: {e}"})
+- logging.error("[PythonLanguage]Error while executing code: %s", e)
+- print("[PythonLanguage]start runing...")
+- while True:
+- if self.should_stop:
+- self.km.interrupt_kernel()
+-
+- try:
+- msg = self.kc.get_iopub_msg(timeout=1)
+- except queue.Empty:
+- continue
+-
+- if msg['parent_header'].get('msg_id') != self.current_msg_id:
+- continue
+-
+- msg_type = msg['msg_type']
+- content = msg['content']
+-
+- print("get_one_msg")
+-
+- if msg_type == "stream":
+- message.put({"type": "text", "content": content['text']})
+-
+- elif msg_type == "error":
+- content = "\n".join(content["traceback"])
+- # 移除颜色标识
+- ansi_escape = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]")
+- content = ansi_escape.sub("", content)
+- message.put({"type": "text", "content": content})
+-
+- elif msg_type in ["display_data", "execute_result"]:
+- data = content["data"]
+- if "image/png" in data:
+- message.put({"type": "image/png", "content": data["image/png"]})
+- elif "image/jpeg" in data:
+- message.put({"type": "image/jpeg", "content": data["image/jpeg"]})
+- elif "text/html" in data:
+- message.put({"type": "html", "content": data["text/html"]})
+- elif "text/plain" in data:
+- message.put({"type": "text", "content": data["text/plain"]})
+- elif "application/javascript" in data:
+- message.put({"type": "javascript", "content": data["application/javascript"]})
+-
+- elif msg_type == 'status':
+- if content['execution_state'] == 'idle':
+- break
+- print("[PythonLanguage]finished.")
+- self.stop()
+Index: core/llm/code/code_parser.py
+===================================================================
+diff --git a/core/llm/code/code_parser.py b/core/llm/code/code_parser.py
+deleted file mode 100644
+--- a/core/llm/code/code_parser.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,10 +0,0 @@
+-import re
+-
+-def CodeParser(text: str):
+- pattern = r"```([\w\+\-\.]*)\n([\s\S]*?)\n```"
+- matches = re.findall(pattern, text)
+-
+- results = []
+- for lang, code in matches:
+- results.append({"lang": lang.strip() if lang else "text", "code": code})
+- return results
+\ No newline at end of file
+Index: core/computer/code/README.md
+===================================================================
+diff --git a/core/computer/code/README.md b/core/computer/code/README.md
+deleted file mode 100644
+--- a/core/computer/code/README.md (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,214 +0,0 @@
+-# Code执行模块
+-
+-这是一个多语言代码执行模块,支持Python、Bash和PowerShell代码的异步执行。
+-
+-## 功能概述
+-
+-该模块提供了一个统一的接口来执行不同编程语言的代码,并通过队列返回执行结果。支持代码中断、执行时间监控等功能。
+-
+-## 架构设计
+-
+-### 核心组件
+-
+-- **Code类**: 主要的代码执行管理器,负责语言选择和执行调度
+-- **BaseLanguage类**: 所有语言实现的抽象基类
+-- **PythonLanguage类**: Python代码执行器,基于Jupyter内核
+-- **BashLanguage类**: Bash/Shell代码执行器,基于subprocess
+-- **PowerShellLanguage类**: PowerShell代码执行器,基于subprocess
+-
+-### 消息系统
+-
+-所有执行结果通过`queue.Queue`对象返回,消息格式为字典:
+-
+-```python
+-{
+- "type": "消息类型",
+- "content": "消息内容"
+-}
+-```
+-
+-## run()返回的消息格式
+-
+-- **`text`**: 纯文本输出,包括标准输出、错误输出、执行结果等
+-- **`image/png`**: PNG格式的图片数据(base64编码)
+-- **`image/jpeg`**: JPEG格式的图片数据(base64编码)
+-- **`html`**: HTML格式的内容
+-- **`text/plain`**: 纯文本内容
+-- **`application/javascript`**: JavaScript代码
+-- **`error`**: 模块的错误信息,不包含代码运行的错误
+-
+-## 使用方法
+-
+-### 基本用法
+-
+-```python
+-from core.computer.code import Code
+-
+-# 创建代码执行器
+-code_executor = Code()
+-
+-# 执行Python代码
+-result_queue = code_executor.run("python", "print('Hello, World!')")
+-
+-# 执行Bash代码
+-result_queue = code_executor.run("bash", "ls -la")
+-
+-# 执行PowerShell代码
+-result_queue = code_executor.run("powershell", "Get-ChildItem")
+-
+-# 获取执行结果
+-while not result_queue.empty():
+- message = result_queue.get()
+- print(f"{message['type']}: {message['content']}")
+-```
+-
+-### 支持的语言
+-
+-- Python: `python`
+-- Bash: `bash`, `sh`
+-- PowerShell: `powershell`, `pwsh`
+-
+-### 中断执行
+-
+-```python
+-# 中断当前正在执行的代码
+-result_queue = code_executor.interrupt()
+-```
+-
+-### 监控执行状态
+-
+-```python
+-# 检查是否有代码正在运行
+-is_running = code_executor.is_running()
+-
+-# 获取已运行时间
+-elapsed_time = code_executor.get_elapsed_time()
+-```
+-
+-## 各语言实现详情
+-
+-### Python实现 (PythonLanguage)
+-
+-- **技术**: 基于Jupyter内核和jupyter_client
+-- **特性**:
+- - 支持matplotlib内联绘图
+- - 支持图片、HTML、JavaScript等多种输出格式
+- - 完整的Python语法支持
+- - 自动添加`%matplotlib inline`以支持可视化
+-- **依赖**: jupyter_client, ipython kernel
+-
+-### Bash实现 (BashLanguage)
+-
+-- **技术**: 基于subprocess.Popen
+-- **特性**:
+- - 检测bash是否可用
+- - 实时输出流
+- - 支持信号中断
+-- **可用性检查**: `shutil.which("bash")`
+-
+-### PowerShell实现 (PowerShellLanguage)
+-
+-- **技术**: 基于subprocess.Popen
+-- **特性**:
+- - 优先使用pwsh (PowerShell Core),回退到powershell
+- - 跨平台支持
+- - 无配置文件执行 (`-NoProfile`)
+-- **可用性检查**: `shutil.which("powershell") or shutil.which("pwsh")`
+-
+-## 错误处理
+-
+-### 模块级错误
+-
+-- 不支持的语言
+-- 系统环境问题
+-- 内核启动失败
+-
+-### 代码执行错误
+-
+-- 语法错误
+-- 运行时错误
+-- 依赖缺失
+-
+-## 线程安全
+-
+-- 每次代码执行都在独立的线程中运行
+-- 使用队列进行线程间通信
+-- 支持优雅的中断机制
+-
+-## 性能考虑
+-
+-- Python内核会重复启动和停止,适合短时间执行
+-- Bash和PowerShell为每次执行创建新进程
+-- 所有语言都支持实时输出,不会阻塞主线程
+-
+-## 依赖要求
+-
+-### Python环境
+-- Python 3.7+
+-- jupyter_client
+-- IPython kernel
+-
+-### 系统环境
+-- Bash: Git Bash, WSL, 或Linux/macOS环境
+-- PowerShell: Windows PowerShell 5.1+ 或 PowerShell Core 6.0+
+-
+-## 示例代码
+-
+-```python
+-# 完整示例
+-from core.computer.code import Code
+-import time
+-
+-def execute_code_example():
+- executor = Code()
+-
+- # Python可视化示例
+- print("执行Python代码...")
+- result = executor.run("python", """
+-import matplotlib.pyplot as plt
+-import numpy as np
+-
+-x = np.linspace(0, 10, 100)
+-y = np.sin(x)
+-
+-plt.figure(figsize=(8, 4))
+-plt.plot(x, y)
+-plt.title('正弦波形')
+-plt.xlabel('x')
+-plt.ylabel('sin(x)')
+-plt.grid(True)
+-plt.show()
+-""")
+-
+- # 读取结果
+- while not result.empty() or executor.is_running():
+- if not result.empty():
+- msg = result.get()
+- print(f"收到消息: {msg['type']}")
+- if msg['type'].startswith('image/'):
+- print(f"图片数据: {len(msg['content'])} 字节")
+- else:
+- print(f"内容: {msg['content'][:100]}...")
+- time.sleep(0.1)
+-
+- print("Python执行完成")
+-
+-if __name__ == "__main__":
+- execute_code_example()
+-```
+-
+-## 注意事项
+-
+-1. **Python内核**: 每次执行都会重新启动内核,状态不会保留
+-2. **安全性**: 该模块设计用于受控环境,避免执行不受信任的代码
+-3. **资源管理**: 长时间运行可能产生大量进程,建议监控资源使用
+-4. **平台兼容性**: 某些功能在不同操作系统上表现可能不同
+-
+-## 未来改进
+-
+-- [ ] 支持更多编程语言 (Node.js, Ruby等)
+-- [ ] Python内核持久化,避免重复启动
+-- [ ] 代码执行超时设置
+-- [ ] 更细粒度的权限控制
+-- [ ] 代码执行历史记录
+-- [ ] 性能监控和分析
+Index: core/llm/code/__init__.py
+===================================================================
+diff --git a/core/llm/code/__init__.py b/core/llm/code/__init__.py
+deleted file mode 100644
+--- a/core/llm/code/__init__.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,3 +0,0 @@
+-from .agent import CodeAgent
+-
+-__all__ = ["CodeAgent"]
+\ No newline at end of file
+Index: core/computer/keyboard/keyboard.py
+===================================================================
+diff --git a/core/computer/keyboard/keyboard.py b/core/computer/keyboard/keyboard.py
+deleted file mode 100644
+--- a/core/computer/keyboard/keyboard.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,296 +0,0 @@
+-import pyautogui
+-import time
+-from typing import Union, List, Optional
+-
+-
+-class Keyboard:
+- """键盘操作类,提供各种键盘控制功能"""
+-
+- def __init__(self):
+- """初始化键盘模块"""
+- pyautogui.PAUSE = 0.05 # 每次操作后暂停0.05秒
+-
+- def type_text(self, text: str, interval: float = 0.0) -> dict:
+- """
+- 输入文本
+-
+- Args:
+- text: 要输入的文本
+- interval: 每个字符之间的间隔时间(秒)
+-
+- Returns:
+- 包含操作结果的字典
+-
+- Examples:
+- >>> keyboard.type_text("Hello World")
+- >>> keyboard.type_text("慢速输入", interval=0.1)
+-
+- Note:
+- 对于中文输入,需要系统已经切换到中文输入法
+- """
+- try:
+- pyautogui.write(text, interval=interval)
+- return {
+- 'success': True,
+- 'action': 'type_text',
+- 'text': text,
+- 'length': len(text),
+- 'interval': interval
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'action': 'type_text',
+- 'error': str(e)
+- }
+-
+- def press(self, key: str, presses: int = 1, interval: float = 0.0) -> dict:
+- """
+- 按下指定键
+-
+- Args:
+- key: 键名,如 'enter', 'space', 'a', 'ctrl' 等
+- presses: 按键次数
+- interval: 多次按键之间的间隔(秒)
+-
+- Returns:
+- 包含操作结果的字典
+-
+- Examples:
+- >>> keyboard.press('enter') # 按下回车键
+- >>> keyboard.press('tab', presses=3) # 按3次Tab键
+- >>> keyboard.press('backspace') # 按退格键
+-
+- 常用键名:
+- - 字母: 'a', 'b', 'c' ...
+- - 数字: '0', '1', '2' ...
+- - 功能键: 'f1', 'f2' ... 'f12'
+- - 方向键: 'up', 'down', 'left', 'right'
+- - 特殊键: 'enter', 'space', 'tab', 'backspace', 'delete', 'esc'
+- - 修饰键: 'ctrl', 'shift', 'alt', 'win' (或 'command' 在Mac上)
+- """
+- try:
+- pyautogui.press(key, presses=presses, interval=interval)
+- return {
+- 'success': True,
+- 'action': 'press',
+- 'key': key,
+- 'presses': presses,
+- 'interval': interval
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'action': 'press',
+- 'error': str(e)
+- }
+-
+- def hotkey(self, *keys: str) -> dict:
+- """
+- 按下组合键(快捷键)
+-
+- Args:
+- *keys: 要同时按下的键,按顺序传入
+-
+- Returns:
+- 包含操作结果的字典
+-
+- Examples:
+- >>> keyboard.hotkey('ctrl', 'c') # Ctrl+C 复制
+- >>> keyboard.hotkey('ctrl', 'v') # Ctrl+V 粘贴
+- >>> keyboard.hotkey('ctrl', 'shift', 's') # Ctrl+Shift+S
+- >>> keyboard.hotkey('alt', 'tab') # Alt+Tab 切换窗口
+- >>> keyboard.hotkey('ctrl', 'a') # Ctrl+A 全选
+- """
+- try:
+- pyautogui.hotkey(*keys)
+- return {
+- 'success': True,
+- 'action': 'hotkey',
+- 'keys': keys,
+- 'combination': '+'.join(keys)
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'action': 'hotkey',
+- 'error': str(e)
+- }
+-
+- def key_down(self, key: str) -> dict:
+- """
+- 按下键(不释放)
+-
+- Args:
+- key: 键名
+-
+- Returns:
+- 包含操作结果的字典
+-
+- Examples:
+- >>> keyboard.key_down('shift') # 按下Shift键
+- """
+- try:
+- pyautogui.keyDown(key)
+- return {
+- 'success': True,
+- 'action': 'key_down',
+- 'key': key
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'action': 'key_down',
+- 'error': str(e)
+- }
+-
+- def key_up(self, key: str) -> dict:
+- """
+- 释放键
+-
+- Args:
+- key: 键名
+-
+- Returns:
+- 包含操作结果的字典
+-
+- Examples:
+- >>> keyboard.key_up('shift') # 释放Shift键
+- """
+- try:
+- pyautogui.keyUp(key)
+- return {
+- 'success': True,
+- 'action': 'key_up',
+- 'key': key
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'action': 'key_up',
+- 'error': str(e)
+- }
+-
+- def hold_key(self, key: str, duration: float = 1.0) -> dict:
+- """
+- 按住一个键一段时间
+-
+- Args:
+- key: 键名
+- duration: 按住的时间(秒)
+-
+- Returns:
+- 包含操作结果的字典
+-
+- Examples:
+- >>> keyboard.hold_key('space', duration=2.0) # 按住空格键2秒
+- """
+- try:
+- pyautogui.keyDown(key)
+- time.sleep(duration)
+- pyautogui.keyUp(key)
+- return {
+- 'success': True,
+- 'action': 'hold_key',
+- 'key': key,
+- 'duration': duration
+- }
+- except Exception as e:
+- return {
+- 'success': False,
+- 'action': 'hold_key',
+- 'error': str(e)
+- }
+-
+- # 常用快捷键的便捷方法
+-
+- def copy(self) -> dict:
+- """复制 (Ctrl+C)"""
+- return self.hotkey('ctrl', 'c')
+-
+- def paste(self) -> dict:
+- """粘贴 (Ctrl+V)"""
+- return self.hotkey('ctrl', 'v')
+-
+- def cut(self) -> dict:
+- """剪切 (Ctrl+X)"""
+- return self.hotkey('ctrl', 'x')
+-
+- def select_all(self) -> dict:
+- """全选 (Ctrl+A)"""
+- return self.hotkey('ctrl', 'a')
+-
+- def undo(self) -> dict:
+- """撤销 (Ctrl+Z)"""
+- return self.hotkey('ctrl', 'z')
+-
+- def redo(self) -> dict:
+- """重做 (Ctrl+Y)"""
+- return self.hotkey('ctrl', 'y')
+-
+- def save(self) -> dict:
+- """保存 (Ctrl+S)"""
+- return self.hotkey('ctrl', 's')
+-
+- def find(self) -> dict:
+- """查找 (Ctrl+F)"""
+- return self.hotkey('ctrl', 'f')
+-
+- def new_tab(self) -> dict:
+- """新建标签页 (Ctrl+T)"""
+- return self.hotkey('ctrl', 't')
+-
+- def close_tab(self) -> dict:
+- """关闭标签页 (Ctrl+W)"""
+- return self.hotkey('ctrl', 'w')
+-
+- def refresh(self) -> dict:
+- """刷新 (F5)"""
+- return self.press('f5')
+-
+- def switch_window(self) -> dict:
+- """切换窗口 (Alt+Tab)"""
+- return self.hotkey('alt', 'tab')
+-
+-
+-# 创建全局实例,支持直接调用
+-_keyboard_instance = Keyboard()
+-
+-# 导出便捷函数
+-type_text = _keyboard_instance.type_text
+-press = _keyboard_instance.press
+-hotkey = _keyboard_instance.hotkey
+-key_down = _keyboard_instance.key_down
+-key_up = _keyboard_instance.key_up
+-hold_key = _keyboard_instance.hold_key
+-
+-# 导出快捷键函数
+-copy = _keyboard_instance.copy
+-paste = _keyboard_instance.paste
+-cut = _keyboard_instance.cut
+-select_all = _keyboard_instance.select_all
+-undo = _keyboard_instance.undo
+-redo = _keyboard_instance.redo
+-save = _keyboard_instance.save
+-find = _keyboard_instance.find
+-new_tab = _keyboard_instance.new_tab
+-close_tab = _keyboard_instance.close_tab
+-refresh = _keyboard_instance.refresh
+-switch_window = _keyboard_instance.switch_window
+-
+-
+-if __name__ == "__main__":
+- # 简单测试
+- print("测试键盘模块...")
+-
+- # 测试按键
+- print("按下Esc键...")
+- result = press('esc')
+- print(f"结果: {result}")
+-
+- # 测试快捷键
+- print("测试Ctrl+C快捷键...")
+- result = copy()
+- print(f"结果: {result}")
+-
+- print("键盘模块测试完成!")
+Index: core/computer/code/languages/bash.py
+===================================================================
+diff --git a/core/computer/code/languages/bash.py b/core/computer/code/languages/bash.py
+deleted file mode 100644
+--- a/core/computer/code/languages/bash.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,63 +0,0 @@
+-import queue
+-import shutil
+-import subprocess
+-import threading
+-import time
+-
+-from ..base_language import BaseLanguage
+-
+-
+-class BashLanguage(BaseLanguage):
+- def __init__(self):
+- super().__init__()
+- self.process = None
+-
+- def is_available(self):
+- return shutil.which("bash") is not None
+-
+- def run(self, code: str):
+- message = queue.Queue()
+- execution_thread = threading.Thread(target=self._execute, args=(code, message))
+- execution_thread.daemon = True
+- execution_thread.start()
+- return message
+-
+- def _execute(self, code: str, message: queue.Queue):
+- self.is_running = True
+- self.start_time = time.time()
+- self.should_stop = False
+-
+- try:
+- self.process = subprocess.Popen(
+- ["bash"],
+- stdin=subprocess.PIPE,
+- stdout=subprocess.PIPE,
+- stderr=subprocess.STDOUT,
+- text=True,
+- bufsize=1,
+- universal_newlines=True
+- )
+-
+- self.process.stdin.write(code)
+- self.process.stdin.close()
+-
+- for line in self.process.stdout:
+- message.put({"type": "text", "content": line})
+-
+- return_code = self.process.wait()
+- message.put({"type": "text", "content": f"Return code: {return_code}"})
+-
+- except Exception as e:
+- message.put({"type": "error", "content": f"[BashLanguage]Error: {e}"})
+- finally:
+- self.is_running = False
+- self.process = None
+-
+- def interrupt(self):
+- self.should_stop = True
+- if self.process:
+- self.process.terminate()
+- try:
+- self.process.wait(timeout=2)
+- except subprocess.TimeoutExpired:
+- self.process.kill()
+Index: core/computer/code/base_language.py
+===================================================================
+diff --git a/core/computer/code/base_language.py b/core/computer/code/base_language.py
+deleted file mode 100644
+--- a/core/computer/code/base_language.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,19 +0,0 @@
+-import time
+-
+-class BaseLanguage:
+- def __init__(self):
+- self.is_running = False
+- self.start_time = None
+- self.elapsed_time = 0
+- self.should_stop = False
+-
+- def run(self, code: str):
+- raise NotImplementedError("[BaseLanguage]Subclasses must implement this method")
+-
+- def get_elapsed_time(self):
+- if self.is_running and self.start_time:
+- return time.time() - self.start_time
+- return self.elapsed_time
+-
+- def interrupt(self):
+- self.should_stop = True
+\ No newline at end of file
+Index: core/computer/README.md
+===================================================================
+diff --git a/core/computer/README.md b/core/computer/README.md
+deleted file mode 100644
+--- a/core/computer/README.md (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,3 +0,0 @@
+-### 设计
+-
+-所有返回,字典由列表或者queue装起来
+\ No newline at end of file
+Index: core/llm/code/default_prompt.py
+===================================================================
+diff --git a/core/llm/code/default_prompt.py b/core/llm/code/default_prompt.py
+deleted file mode 100644
+--- a/core/llm/code/default_prompt.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,33 +0,0 @@
+-import getpass
+-import platform
+-
+-
+-default_prompt = f"""
+-You are Open Interpreter, a world-class programmer that can complete any goal by executing code.
+-For advanced requests, start by writing a plan.
+-When you execute code, it will be executed **on the user's machine**. The user has given you **full and complete permission** to execute any code necessary to complete the task.
+-You can access the internet. Run **any code** to achieve the goal, and if at first you don't succeed, try again and again.
+-You can install new packages.
+-When a user refers to a filename, they're likely referring to an existing file in the directory you're currently executing code in.
+-Write messages to the user in Markdown.
+-In general, try to **make plans** with as few steps as possible.
+-You should try something, print information about it, then continue from there in tiny, informed steps.
+-You will never get it on the first try, and attempting it in one go will often lead to errors you cant see.
+-You are capable of **any** task.
+-Print your code directly in the output. Do not print any additional information, including code explanation, running guide, etc.
+-
+-Use the following format to output your code:
+-
+-```python
+-# Your python code here
+-print("Result to inspect")
+-```
+-
+-User's Name: {getpass.getuser()}
+-User's OS: {platform.system()}
+-Language: {{language}}
+-"""
+-
+-default_prompt_end = "Are we done? If the task is finished, print \"The task is done.\" in the first line, then summarize the result. If the task is not finished yet, what's next?"
+-# As for actually executing code to carry out that plan, for *stateful* languages (like python, javascript, shell, but NOT for html which starts from 0 every time) **it's critical not to try to do everything in one code block.**
+-# If the task is impossible, print \"The task is impossible.\" in the first line, then explain why.
+\ No newline at end of file
+Index: lin.py
+===================================================================
+diff --git a/lin.py b/lin.py
+deleted file mode 100644
+--- a/lin.py (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,3 +0,0 @@
+-import numpy
+-
+-ss
+\ No newline at end of file
+Index: .gitignore
+===================================================================
+diff --git a/.gitignore b/.gitignore
+deleted file mode 100644
+--- a/.gitignore (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,7 +0,0 @@
+-.idea
+-.vscode
+-__pycache__
+-test
+-
+-*.log
+-.env*
+\ No newline at end of file
+Index: requirements.txt
+===================================================================
+diff --git a/requirements.txt b/requirements.txt
+deleted file mode 100644
+--- a/requirements.txt (revision 4057a203831344e54e570576815336c422e4fe9f)
++++ /dev/null (revision 4057a203831344e54e570576815336c422e4fe9f)
+@@ -1,3 +0,0 @@
+-litellm
+-jupyter_client
+-pyautogui
+\ No newline at end of file
+diff --git a/core/llm/gui/__init__.py b/core/llm/gui/__init__.py
+deleted file mode 100644
+diff --git a/core/__init__.py b/core/__init__.py
+deleted file mode 100644
+diff --git a/core/computer/__init__.py b/core/computer/__init__.py
+deleted file mode 100644
diff --git a/core/__init__.py b/core/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/core/computer/README.md b/core/computer/README.md
deleted file mode 100644
index ee0d150..0000000
--- a/core/computer/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### 设计
-
-所有返回,字典由列表或者queue装起来
\ No newline at end of file
diff --git a/core/computer/__init__.py b/core/computer/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/core/computer/code/README.md b/core/computer/code/README.md
deleted file mode 100644
index e1a9f23..0000000
--- a/core/computer/code/README.md
+++ /dev/null
@@ -1,214 +0,0 @@
-# Code执行模块
-
-这是一个多语言代码执行模块,支持Python、Bash和PowerShell代码的异步执行。
-
-## 功能概述
-
-该模块提供了一个统一的接口来执行不同编程语言的代码,并通过队列返回执行结果。支持代码中断、执行时间监控等功能。
-
-## 架构设计
-
-### 核心组件
-
-- **Code类**: 主要的代码执行管理器,负责语言选择和执行调度
-- **BaseLanguage类**: 所有语言实现的抽象基类
-- **PythonLanguage类**: Python代码执行器,基于Jupyter内核
-- **BashLanguage类**: Bash/Shell代码执行器,基于subprocess
-- **PowerShellLanguage类**: PowerShell代码执行器,基于subprocess
-
-### 消息系统
-
-所有执行结果通过`queue.Queue`对象返回,消息格式为字典:
-
-```python
-{
- "type": "消息类型",
- "content": "消息内容"
-}
-```
-
-## run()返回的消息格式
-
-- **`text`**: 纯文本输出,包括标准输出、错误输出、执行结果等
-- **`image/png`**: PNG格式的图片数据(base64编码)
-- **`image/jpeg`**: JPEG格式的图片数据(base64编码)
-- **`html`**: HTML格式的内容
-- **`text/plain`**: 纯文本内容
-- **`application/javascript`**: JavaScript代码
-- **`error`**: 模块的错误信息,不包含代码运行的错误
-
-## 使用方法
-
-### 基本用法
-
-```python
-from core.computer.code import Code
-
-# 创建代码执行器
-code_executor = Code()
-
-# 执行Python代码
-result_queue = code_executor.run("python", "print('Hello, World!')")
-
-# 执行Bash代码
-result_queue = code_executor.run("bash", "ls -la")
-
-# 执行PowerShell代码
-result_queue = code_executor.run("powershell", "Get-ChildItem")
-
-# 获取执行结果
-while not result_queue.empty():
- message = result_queue.get()
- print(f"{message['type']}: {message['content']}")
-```
-
-### 支持的语言
-
-- Python: `python`
-- Bash: `bash`, `sh`
-- PowerShell: `powershell`, `pwsh`
-
-### 中断执行
-
-```python
-# 中断当前正在执行的代码
-result_queue = code_executor.interrupt()
-```
-
-### 监控执行状态
-
-```python
-# 检查是否有代码正在运行
-is_running = code_executor.is_running()
-
-# 获取已运行时间
-elapsed_time = code_executor.get_elapsed_time()
-```
-
-## 各语言实现详情
-
-### Python实现 (PythonLanguage)
-
-- **技术**: 基于Jupyter内核和jupyter_client
-- **特性**:
- - 支持matplotlib内联绘图
- - 支持图片、HTML、JavaScript等多种输出格式
- - 完整的Python语法支持
- - 自动添加`%matplotlib inline`以支持可视化
-- **依赖**: jupyter_client, ipython kernel
-
-### Bash实现 (BashLanguage)
-
-- **技术**: 基于subprocess.Popen
-- **特性**:
- - 检测bash是否可用
- - 实时输出流
- - 支持信号中断
-- **可用性检查**: `shutil.which("bash")`
-
-### PowerShell实现 (PowerShellLanguage)
-
-- **技术**: 基于subprocess.Popen
-- **特性**:
- - 优先使用pwsh (PowerShell Core),回退到powershell
- - 跨平台支持
- - 无配置文件执行 (`-NoProfile`)
-- **可用性检查**: `shutil.which("powershell") or shutil.which("pwsh")`
-
-## 错误处理
-
-### 模块级错误
-
-- 不支持的语言
-- 系统环境问题
-- 内核启动失败
-
-### 代码执行错误
-
-- 语法错误
-- 运行时错误
-- 依赖缺失
-
-## 线程安全
-
-- 每次代码执行都在独立的线程中运行
-- 使用队列进行线程间通信
-- 支持优雅的中断机制
-
-## 性能考虑
-
-- Python内核会重复启动和停止,适合短时间执行
-- Bash和PowerShell为每次执行创建新进程
-- 所有语言都支持实时输出,不会阻塞主线程
-
-## 依赖要求
-
-### Python环境
-- Python 3.7+
-- jupyter_client
-- IPython kernel
-
-### 系统环境
-- Bash: Git Bash, WSL, 或Linux/macOS环境
-- PowerShell: Windows PowerShell 5.1+ 或 PowerShell Core 6.0+
-
-## 示例代码
-
-```python
-# 完整示例
-from core.computer.code import Code
-import time
-
-def execute_code_example():
- executor = Code()
-
- # Python可视化示例
- print("执行Python代码...")
- result = executor.run("python", """
-import matplotlib.pyplot as plt
-import numpy as np
-
-x = np.linspace(0, 10, 100)
-y = np.sin(x)
-
-plt.figure(figsize=(8, 4))
-plt.plot(x, y)
-plt.title('正弦波形')
-plt.xlabel('x')
-plt.ylabel('sin(x)')
-plt.grid(True)
-plt.show()
-""")
-
- # 读取结果
- while not result.empty() or executor.is_running():
- if not result.empty():
- msg = result.get()
- print(f"收到消息: {msg['type']}")
- if msg['type'].startswith('image/'):
- print(f"图片数据: {len(msg['content'])} 字节")
- else:
- print(f"内容: {msg['content'][:100]}...")
- time.sleep(0.1)
-
- print("Python执行完成")
-
-if __name__ == "__main__":
- execute_code_example()
-```
-
-## 注意事项
-
-1. **Python内核**: 每次执行都会重新启动内核,状态不会保留
-2. **安全性**: 该模块设计用于受控环境,避免执行不受信任的代码
-3. **资源管理**: 长时间运行可能产生大量进程,建议监控资源使用
-4. **平台兼容性**: 某些功能在不同操作系统上表现可能不同
-
-## 未来改进
-
-- [ ] 支持更多编程语言 (Node.js, Ruby等)
-- [ ] Python内核持久化,避免重复启动
-- [ ] 代码执行超时设置
-- [ ] 更细粒度的权限控制
-- [ ] 代码执行历史记录
-- [ ] 性能监控和分析
diff --git a/core/computer/code/__init__.py b/core/computer/code/__init__.py
deleted file mode 100644
index 49f78e3..0000000
--- a/core/computer/code/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-"""
-代码运行包
-"""
-
-
-from .base_language import BaseLanguage
-from .code import Code
-
-__all__ = ['Code', 'BaseLanguage']
-
-__version__ = '1.0.0'
\ No newline at end of file
diff --git a/core/computer/code/base_language.py b/core/computer/code/base_language.py
deleted file mode 100644
index 26ffb40..0000000
--- a/core/computer/code/base_language.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import time
-
-class BaseLanguage:
- def __init__(self):
- self.is_running = False
- self.start_time = None
- self.elapsed_time = 0
- self.should_stop = False
-
- def run(self, code: str):
- raise NotImplementedError("[BaseLanguage]Subclasses must implement this method")
-
- def get_elapsed_time(self):
- if self.is_running and self.start_time:
- return time.time() - self.start_time
- return self.elapsed_time
-
- def interrupt(self):
- self.should_stop = True
\ No newline at end of file
diff --git a/core/computer/code/code.py b/core/computer/code/code.py
deleted file mode 100644
index eab47c8..0000000
--- a/core/computer/code/code.py
+++ /dev/null
@@ -1,74 +0,0 @@
-import queue
-
-from .languages import PythonLanguage, BashLanguage, PowerShellLanguage
-
-
-class Code:
- def __init__(self):
- self.python = PythonLanguage()
- # self.cmd = CMDLanguage()
- self.bash = BashLanguage()
- self.powershell = PowerShellLanguage()
- self.current_language = None
- self.language_map = {
- "python": self.python,
- # "cmd": self.cmd,
- "powershell": self.powershell,
- "pwsh": self.powershell, # PowerShell Core别名
- "bash": self.bash,
- "sh": self.bash, # Shell别名
- }
- self.language_list = []
- for lang, lang_obj in self.language_map.items():
- if hasattr(lang_obj, 'is_available'):
- if lang_obj.is_available():
- self.language_list.append(lang)
- else:
- # Python总是可用的
- self.language_list.append(lang)
-
- # def language_list(self):
- # available = []
-
- def run(self, lang: str, code: str):
- """
- 运行代码
-
- :param lang: 要运行的代码语言
- :type lang: str
- :param code: 要运行的代码
- :type code: str
- """
- lang = lang.lower()
- if lang in self.language_list:
- self.current_language = self.language_map[lang]
- return self.current_language.run(code)
- else:
- message = queue.Queue()
- message.put({"type": "error", "content": f"[Code]Unsupported language:{lang}"})
- return message
-
- def interrupt(self):
- """
- 中断执行中的代码
- """
- message = queue.Queue()
- if self.current_language and self.current_language.is_running:
- self.current_language.interrupt()
- message.put({"type": "text", "content": "Code execution interrupted"})
- else:
- message.put({"type": "text", "content": "No code is running"})
- return message
-
- def get_elapsed_time(self):
- """
- 获取代码已运行时间
- """
- if self.current_language:
- return self.current_language.get_elapsed_time()
-
- def is_running(self):
- """
- 代码是否正在运行
- """
- return self.current_language and self.current_language.is_running
\ No newline at end of file
diff --git a/core/computer/code/languages/__init__.py b/core/computer/code/languages/__init__.py
deleted file mode 100644
index 2f0da07..0000000
--- a/core/computer/code/languages/__init__.py
+++ /dev/null
@@ -1,12 +0,0 @@
-"""
-
-"""
-
-
-from .bash import BashLanguage
-from .powershell import PowerShellLanguage
-from .python import PythonLanguage
-
-__all__ = ['PythonLanguage', 'BashLanguage', 'PowerShellLanguage']
-
-__version__ = '1.0.0'
\ No newline at end of file
diff --git a/core/computer/code/languages/bash.py b/core/computer/code/languages/bash.py
deleted file mode 100644
index fde830e..0000000
--- a/core/computer/code/languages/bash.py
+++ /dev/null
@@ -1,63 +0,0 @@
-import queue
-import shutil
-import subprocess
-import threading
-import time
-
-from ..base_language import BaseLanguage
-
-
-class BashLanguage(BaseLanguage):
- def __init__(self):
- super().__init__()
- self.process = None
-
- def is_available(self):
- return shutil.which("bash") is not None
-
- def run(self, code: str):
- message = queue.Queue()
- execution_thread = threading.Thread(target=self._execute, args=(code, message))
- execution_thread.daemon = True
- execution_thread.start()
- return message
-
- def _execute(self, code: str, message: queue.Queue):
- self.is_running = True
- self.start_time = time.time()
- self.should_stop = False
-
- try:
- self.process = subprocess.Popen(
- ["bash"],
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- text=True,
- bufsize=1,
- universal_newlines=True
- )
-
- self.process.stdin.write(code)
- self.process.stdin.close()
-
- for line in self.process.stdout:
- message.put({"type": "text", "content": line})
-
- return_code = self.process.wait()
- message.put({"type": "text", "content": f"Return code: {return_code}"})
-
- except Exception as e:
- message.put({"type": "error", "content": f"[BashLanguage]Error: {e}"})
- finally:
- self.is_running = False
- self.process = None
-
- def interrupt(self):
- self.should_stop = True
- if self.process:
- self.process.terminate()
- try:
- self.process.wait(timeout=2)
- except subprocess.TimeoutExpired:
- self.process.kill()
diff --git a/core/computer/code/languages/powershell.py b/core/computer/code/languages/powershell.py
deleted file mode 100644
index 20427f4..0000000
--- a/core/computer/code/languages/powershell.py
+++ /dev/null
@@ -1,64 +0,0 @@
-import queue
-import shutil
-import subprocess
-import threading
-import time
-
-from ..base_language import BaseLanguage
-
-
-class PowerShellLanguage(BaseLanguage):
- def __init__(self):
- super().__init__()
- self.process = None
-
- def is_available(self):
- return shutil.which("powershell") is not None or shutil.which("pwsh") is not None
-
- def run(self, code: str):
- message = queue.Queue()
- execution_thread = threading.Thread(target=self._execute, args=(code, message))
- execution_thread.daemon = True
- execution_thread.start()
- return message
-
- def _execute(self, code: str, message: queue.Queue):
- self.is_running = True
- self.start_time = time.time()
- self.should_stop = False
-
- executable = "pwsh" if shutil.which("pwsh") else "powershell"
-
- try:
- # -Command - tells powershell to read command from stdin
- self.process = subprocess.Popen(
- [executable, "-NoProfile", "-Command", code],
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- text=True,
- bufsize=1,
- universal_newlines=True
- )
-
- for line in self.process.stdout:
- if self.should_stop:
- break
- message.put({"type": "text", "content": line})
-
- return_code = self.process.wait()
- message.put({"type": "text", "content": f"Return code: {return_code}"})
-
- except Exception as e:
- message.put({"type": "error", "content": f"[PowerShellLanguage]Error: {e}"})
- finally:
- self.is_running = False
- self.process = None
-
- def interrupt(self):
- super().interrupt()
- if self.process:
- self.process.terminate()
- try:
- self.process.wait(timeout=2)
- except subprocess.TimeoutExpired:
- self.process.kill()
diff --git a/core/computer/code/languages/python.py b/core/computer/code/languages/python.py
deleted file mode 100644
index 53745c0..0000000
--- a/core/computer/code/languages/python.py
+++ /dev/null
@@ -1,131 +0,0 @@
-import logging
-import queue
-import re
-import threading
-import time
-
-from jupyter_client.manager import KernelManager
-
-from ..base_language import BaseLanguage
-
-
-class PythonLanguage(BaseLanguage):
- def __init__(self):
- super().__init__()
- self.km = None
- self.kc = None
- self.current_msg_id = None
-
- def start(self):
- self.should_stop = False
- self.start_time = time.time()
- self.elapsed_time = 0
-
- if self.km:
- self.stop()
- try:
- self.km = KernelManager(kernel_name='python3')
- self.is_running = True
- self.km.start_kernel()
- self.kc = self.km.client()
- self.kc.start_channels()
- self.kc.wait_for_ready()
- logging.info("[PythonLanguage]Started kernel client&manager")
- except Exception as e:
- self.stop()
- logging.error("[PythonLanguage]Error starting kernel: %s", e)
-
- def stop(self):
- self.is_running = False
- if self.start_time:
- self.elapsed_time = time.time() - self.start_time
- self.start_time = None
-
- try:
- if self.km:
- self.km.shutdown_kernel()
- self.is_running = False
- self.km = None
- if self.kc:
- self.kc.stop_channels()
- self.current_msg_id = None
- self.kc = None
- logging.info("[PythonLanguage]Stopped kernel client&manager")
- except Exception as e:
- logging.error("[PythonLanguage]Error during cleanup kernel: %s", e)
-
- def wait_for_shutdown(self):
- while self.is_running or self.kc:
- time.sleep(0.1)
-
- def run(self, code: str):
- message = queue.Queue()
-
- excecution_thread = threading.Thread(target=self._execute_jupyter, args=(code, message))
- excecution_thread.daemon = True
- excecution_thread.start()
-
- return message
-
- def _execute_jupyter(self, code: str, message: queue.Queue):
- self.start()
-
- if self.km.is_alive() is False:
- message.put({"type": "error", "content": "[PythonLanguage]Faild to start Jupyter kernel"})
- return
-
- # 只在需要时添加matplotlib魔法命令
- if "matplotlib" in code and "%matplotlib" not in code:
- code = "%matplotlib inline\n" + code
-
- try:
- self.current_msg_id=self.kc.execute(code)
- except Exception as e:
- message.put({"type": "error", "content": f"[PythonLanguage]Error while executing code: {e}"})
- logging.error("[PythonLanguage]Error while executing code: %s", e)
- print("[PythonLanguage]start runing...")
- while True:
- if self.should_stop:
- self.km.interrupt_kernel()
-
- try:
- msg = self.kc.get_iopub_msg(timeout=1)
- except queue.Empty:
- continue
-
- if msg['parent_header'].get('msg_id') != self.current_msg_id:
- continue
-
- msg_type = msg['msg_type']
- content = msg['content']
-
- print("get_one_msg")
-
- if msg_type == "stream":
- message.put({"type": "text", "content": content['text']})
-
- elif msg_type == "error":
- content = "\n".join(content["traceback"])
- # 移除颜色标识
- ansi_escape = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]")
- content = ansi_escape.sub("", content)
- message.put({"type": "text", "content": content})
-
- elif msg_type in ["display_data", "execute_result"]:
- data = content["data"]
- if "image/png" in data:
- message.put({"type": "image/png", "content": data["image/png"]})
- elif "image/jpeg" in data:
- message.put({"type": "image/jpeg", "content": data["image/jpeg"]})
- elif "text/html" in data:
- message.put({"type": "html", "content": data["text/html"]})
- elif "text/plain" in data:
- message.put({"type": "text", "content": data["text/plain"]})
- elif "application/javascript" in data:
- message.put({"type": "javascript", "content": data["application/javascript"]})
-
- elif msg_type == 'status':
- if content['execution_state'] == 'idle':
- break
- print("[PythonLanguage]finished.")
- self.stop()
diff --git a/core/computer/keyboard/__init__.py b/core/computer/keyboard/__init__.py
deleted file mode 100644
index 2c19937..0000000
--- a/core/computer/keyboard/__init__.py
+++ /dev/null
@@ -1,47 +0,0 @@
-"""
-键盘操作包
-"""
-from .keyboard import (
- Keyboard,
- type_text,
- press,
- hotkey,
- key_down,
- key_up,
- hold_key,
- copy,
- paste,
- cut,
- select_all,
- undo,
- redo,
- save,
- find,
- new_tab,
- close_tab,
- refresh,
- switch_window
-)
-
-__all__ = [
- # Keyboard类和函数
- 'Keyboard',
- 'type_text',
- 'press',
- 'hotkey',
- 'key_down',
- 'key_up',
- 'hold_key',
- 'copy',
- 'paste',
- 'cut',
- 'select_all',
- 'undo',
- 'redo',
- 'save',
- 'find',
- 'new_tab',
- 'close_tab',
- 'refresh',
- 'switch_window',
-]
diff --git a/core/computer/keyboard/keyboard.py b/core/computer/keyboard/keyboard.py
deleted file mode 100644
index 0c71680..0000000
--- a/core/computer/keyboard/keyboard.py
+++ /dev/null
@@ -1,296 +0,0 @@
-import pyautogui
-import time
-from typing import Union, List, Optional
-
-
-class Keyboard:
- """键盘操作类,提供各种键盘控制功能"""
-
- def __init__(self):
- """初始化键盘模块"""
- pyautogui.PAUSE = 0.05 # 每次操作后暂停0.05秒
-
- def type_text(self, text: str, interval: float = 0.0) -> dict:
- """
- 输入文本
-
- Args:
- text: 要输入的文本
- interval: 每个字符之间的间隔时间(秒)
-
- Returns:
- 包含操作结果的字典
-
- Examples:
- >>> keyboard.type_text("Hello World")
- >>> keyboard.type_text("慢速输入", interval=0.1)
-
- Note:
- 对于中文输入,需要系统已经切换到中文输入法
- """
- try:
- pyautogui.write(text, interval=interval)
- return {
- 'success': True,
- 'action': 'type_text',
- 'text': text,
- 'length': len(text),
- 'interval': interval
- }
- except Exception as e:
- return {
- 'success': False,
- 'action': 'type_text',
- 'error': str(e)
- }
-
- def press(self, key: str, presses: int = 1, interval: float = 0.0) -> dict:
- """
- 按下指定键
-
- Args:
- key: 键名,如 'enter', 'space', 'a', 'ctrl' 等
- presses: 按键次数
- interval: 多次按键之间的间隔(秒)
-
- Returns:
- 包含操作结果的字典
-
- Examples:
- >>> keyboard.press('enter') # 按下回车键
- >>> keyboard.press('tab', presses=3) # 按3次Tab键
- >>> keyboard.press('backspace') # 按退格键
-
- 常用键名:
- - 字母: 'a', 'b', 'c' ...
- - 数字: '0', '1', '2' ...
- - 功能键: 'f1', 'f2' ... 'f12'
- - 方向键: 'up', 'down', 'left', 'right'
- - 特殊键: 'enter', 'space', 'tab', 'backspace', 'delete', 'esc'
- - 修饰键: 'ctrl', 'shift', 'alt', 'win' (或 'command' 在Mac上)
- """
- try:
- pyautogui.press(key, presses=presses, interval=interval)
- return {
- 'success': True,
- 'action': 'press',
- 'key': key,
- 'presses': presses,
- 'interval': interval
- }
- except Exception as e:
- return {
- 'success': False,
- 'action': 'press',
- 'error': str(e)
- }
-
- def hotkey(self, *keys: str) -> dict:
- """
- 按下组合键(快捷键)
-
- Args:
- *keys: 要同时按下的键,按顺序传入
-
- Returns:
- 包含操作结果的字典
-
- Examples:
- >>> keyboard.hotkey('ctrl', 'c') # Ctrl+C 复制
- >>> keyboard.hotkey('ctrl', 'v') # Ctrl+V 粘贴
- >>> keyboard.hotkey('ctrl', 'shift', 's') # Ctrl+Shift+S
- >>> keyboard.hotkey('alt', 'tab') # Alt+Tab 切换窗口
- >>> keyboard.hotkey('ctrl', 'a') # Ctrl+A 全选
- """
- try:
- pyautogui.hotkey(*keys)
- return {
- 'success': True,
- 'action': 'hotkey',
- 'keys': keys,
- 'combination': '+'.join(keys)
- }
- except Exception as e:
- return {
- 'success': False,
- 'action': 'hotkey',
- 'error': str(e)
- }
-
- def key_down(self, key: str) -> dict:
- """
- 按下键(不释放)
-
- Args:
- key: 键名
-
- Returns:
- 包含操作结果的字典
-
- Examples:
- >>> keyboard.key_down('shift') # 按下Shift键
- """
- try:
- pyautogui.keyDown(key)
- return {
- 'success': True,
- 'action': 'key_down',
- 'key': key
- }
- except Exception as e:
- return {
- 'success': False,
- 'action': 'key_down',
- 'error': str(e)
- }
-
- def key_up(self, key: str) -> dict:
- """
- 释放键
-
- Args:
- key: 键名
-
- Returns:
- 包含操作结果的字典
-
- Examples:
- >>> keyboard.key_up('shift') # 释放Shift键
- """
- try:
- pyautogui.keyUp(key)
- return {
- 'success': True,
- 'action': 'key_up',
- 'key': key
- }
- except Exception as e:
- return {
- 'success': False,
- 'action': 'key_up',
- 'error': str(e)
- }
-
- def hold_key(self, key: str, duration: float = 1.0) -> dict:
- """
- 按住一个键一段时间
-
- Args:
- key: 键名
- duration: 按住的时间(秒)
-
- Returns:
- 包含操作结果的字典
-
- Examples:
- >>> keyboard.hold_key('space', duration=2.0) # 按住空格键2秒
- """
- try:
- pyautogui.keyDown(key)
- time.sleep(duration)
- pyautogui.keyUp(key)
- return {
- 'success': True,
- 'action': 'hold_key',
- 'key': key,
- 'duration': duration
- }
- except Exception as e:
- return {
- 'success': False,
- 'action': 'hold_key',
- 'error': str(e)
- }
-
- # 常用快捷键的便捷方法
-
- def copy(self) -> dict:
- """复制 (Ctrl+C)"""
- return self.hotkey('ctrl', 'c')
-
- def paste(self) -> dict:
- """粘贴 (Ctrl+V)"""
- return self.hotkey('ctrl', 'v')
-
- def cut(self) -> dict:
- """剪切 (Ctrl+X)"""
- return self.hotkey('ctrl', 'x')
-
- def select_all(self) -> dict:
- """全选 (Ctrl+A)"""
- return self.hotkey('ctrl', 'a')
-
- def undo(self) -> dict:
- """撤销 (Ctrl+Z)"""
- return self.hotkey('ctrl', 'z')
-
- def redo(self) -> dict:
- """重做 (Ctrl+Y)"""
- return self.hotkey('ctrl', 'y')
-
- def save(self) -> dict:
- """保存 (Ctrl+S)"""
- return self.hotkey('ctrl', 's')
-
- def find(self) -> dict:
- """查找 (Ctrl+F)"""
- return self.hotkey('ctrl', 'f')
-
- def new_tab(self) -> dict:
- """新建标签页 (Ctrl+T)"""
- return self.hotkey('ctrl', 't')
-
- def close_tab(self) -> dict:
- """关闭标签页 (Ctrl+W)"""
- return self.hotkey('ctrl', 'w')
-
- def refresh(self) -> dict:
- """刷新 (F5)"""
- return self.press('f5')
-
- def switch_window(self) -> dict:
- """切换窗口 (Alt+Tab)"""
- return self.hotkey('alt', 'tab')
-
-
-# 创建全局实例,支持直接调用
-_keyboard_instance = Keyboard()
-
-# 导出便捷函数
-type_text = _keyboard_instance.type_text
-press = _keyboard_instance.press
-hotkey = _keyboard_instance.hotkey
-key_down = _keyboard_instance.key_down
-key_up = _keyboard_instance.key_up
-hold_key = _keyboard_instance.hold_key
-
-# 导出快捷键函数
-copy = _keyboard_instance.copy
-paste = _keyboard_instance.paste
-cut = _keyboard_instance.cut
-select_all = _keyboard_instance.select_all
-undo = _keyboard_instance.undo
-redo = _keyboard_instance.redo
-save = _keyboard_instance.save
-find = _keyboard_instance.find
-new_tab = _keyboard_instance.new_tab
-close_tab = _keyboard_instance.close_tab
-refresh = _keyboard_instance.refresh
-switch_window = _keyboard_instance.switch_window
-
-
-if __name__ == "__main__":
- # 简单测试
- print("测试键盘模块...")
-
- # 测试按键
- print("按下Esc键...")
- result = press('esc')
- print(f"结果: {result}")
-
- # 测试快捷键
- print("测试Ctrl+C快捷键...")
- result = copy()
- print(f"结果: {result}")
-
- print("键盘模块测试完成!")
diff --git a/core/computer/mouse/__init__.py b/core/computer/mouse/__init__.py
deleted file mode 100644
index 4abfea7..0000000
--- a/core/computer/mouse/__init__.py
+++ /dev/null
@@ -1,33 +0,0 @@
-"""
-鼠标操作包
-"""
-from .mouse import (
- Mouse,
- click,
- double_click,
- right_click,
- move,
- move_rel,
- drag,
- drag_rel,
- scroll,
- get_position,
- mouse_down,
- mouse_up
-)
-
-__all__ = [
- # Mouse类和函数
- 'Mouse',
- 'click',
- 'double_click',
- 'right_click',
- 'move',
- 'move_rel',
- 'drag',
- 'drag_rel',
- 'scroll',
- 'get_position',
- 'mouse_down',
- 'mouse_up',
-]
\ No newline at end of file
diff --git a/core/computer/mouse/mouse.py b/core/computer/mouse/mouse.py
deleted file mode 100644
index eb1ee10..0000000
--- a/core/computer/mouse/mouse.py
+++ /dev/null
@@ -1,368 +0,0 @@
-import pyautogui
-import time
-from typing import Tuple, Optional, Union
-
-
-class Mouse:
- """鼠标操作类,提供各种鼠标控制功能"""
-
- def __init__(self):
- """初始化鼠标模块"""
- # 设置PyAutoGUI的安全特性
- pyautogui.FAILSAFE = True # 移动鼠标到屏幕左上角会触发异常
- pyautogui.PAUSE = 0.1 # 每次操作后暂停0.1秒
-
- def click(self, x: Optional[int] = None, y: Optional[int] = None,
- clicks: int = 1, interval: float = 0.0,
- button: str = 'left', duration: float = 0.0) -> dict:
- """
- 鼠标点击操作
-
- Args:
- x: X坐标,None表示当前位置
- y: Y坐标,None表示当前位置
- clicks: 点击次数,默认1次
- interval: 多次点击之间的间隔(秒)
- button: 鼠标按键 'left'/'right'/'middle'
- duration: 移动到目标位置的持续时间(秒)
-
- Returns:
- 包含操作结果的字典
-
- Examples:
- >>> mouse.click(100, 200) # 点击坐标(100, 200)
- >>> mouse.click() # 点击当前位置
- >>> mouse.click(button='right') # 右键点击当前位置
- """
- try:
- if x is not None and y is not None:
- pyautogui.click(x, y, clicks=clicks, interval=interval,
- button=button, duration=duration)
- else:
- pyautogui.click(clicks=clicks, interval=interval, button=button)
-
- current_pos = pyautogui.position()
- return {
- 'success': True,
- 'action': 'click',
- 'position': (current_pos.x, current_pos.y),
- 'button': button,
- 'clicks': clicks
- }
- except Exception as e:
- return {
- 'success': False,
- 'action': 'click',
- 'error': str(e)
- }
-
- def double_click(self, x: Optional[int] = None, y: Optional[int] = None,
- button: str = 'left', duration: float = 0.0) -> dict:
- """
- 鼠标双击操作
-
- Args:
- x: X坐标,None表示当前位置
- y: Y坐标,None表示当前位置
- button: 鼠标按键 'left'/'right'/'middle'
- duration: 移动到目标位置的持续时间(秒)
-
- Returns:
- 包含操作结果的字典
-
- Examples:
- >>> mouse.double_click(300, 400) # 双击坐标(300, 400)
- """
- return self.click(x, y, clicks=2, button=button, duration=duration)
-
- def right_click(self, x: Optional[int] = None, y: Optional[int] = None,
- duration: float = 0.0) -> dict:
- """
- 鼠标右键点击
-
- Args:
- x: X坐标,None表示当前位置
- y: Y坐标,None表示当前位置
- duration: 移动到目标位置的持续时间(秒)
-
- Returns:
- 包含操作结果的字典
-
- Examples:
- >>> mouse.right_click(500, 300) # 右键点击坐标(500, 300)
- """
- return self.click(x, y, button='right', duration=duration)
-
- def move(self, x: int, y: int, duration: float = 0.0) -> dict:
- """
- 移动鼠标到指定位置
-
- Args:
- x: 目标X坐标
- y: 目标Y坐标
- duration: 移动持续时间(秒),0表示立即移动
-
- Returns:
- 包含操作结果的字典
-
- Examples:
- >>> mouse.move(800, 600) # 立即移动到(800, 600)
- >>> mouse.move(800, 600, duration=1.0) # 用1秒时间移动到(800, 600)
- """
- try:
- pyautogui.moveTo(x, y, duration=duration)
- current_pos = pyautogui.position()
- return {
- 'success': True,
- 'action': 'move',
- 'position': (current_pos.x, current_pos.y),
- 'duration': duration
- }
- except Exception as e:
- return {
- 'success': False,
- 'action': 'move',
- 'error': str(e)
- }
-
- def move_rel(self, x_offset: int, y_offset: int, duration: float = 0.0) -> dict:
- """
- 相对移动鼠标(从当前位置偏移)
-
- Args:
- x_offset: X轴偏移量
- y_offset: Y轴偏移量
- duration: 移动持续时间(秒)
-
- Returns:
- 包含操作结果的字典
-
- Examples:
- >>> mouse.move_rel(100, 0) # 向右移动100像素
- """
- try:
- pyautogui.moveRel(x_offset, y_offset, duration=duration)
- current_pos = pyautogui.position()
- return {
- 'success': True,
- 'action': 'move_rel',
- 'position': (current_pos.x, current_pos.y),
- 'offset': (x_offset, y_offset),
- 'duration': duration
- }
- except Exception as e:
- return {
- 'success': False,
- 'action': 'move_rel',
- 'error': str(e)
- }
-
- def drag(self, x: int, y: int, duration: float = 0.5,
- button: str = 'left') -> dict:
- """
- 拖拽鼠标到指定位置
-
- Args:
- x: 目标X坐标
- y: 目标Y坐标
- duration: 拖拽持续时间(秒)
- button: 使用的鼠标按键
-
- Returns:
- 包含操作结果的字典
-
- Examples:
- >>> mouse.drag(500, 500, duration=1.0) # 拖拽到(500, 500)
- """
- try:
- pyautogui.drag(x, y, duration=duration, button=button)
- current_pos = pyautogui.position()
- return {
- 'success': True,
- 'action': 'drag',
- 'position': (current_pos.x, current_pos.y),
- 'button': button,
- 'duration': duration
- }
- except Exception as e:
- return {
- 'success': False,
- 'action': 'drag',
- 'error': str(e)
- }
-
- def drag_rel(self, x_offset: int, y_offset: int, duration: float = 0.5,
- button: str = 'left') -> dict:
- """
- 相对拖拽(从当前位置偏移)
-
- Args:
- x_offset: X轴偏移量
- y_offset: Y轴偏移量
- duration: 拖拽持续时间(秒)
- button: 使用的鼠标按键
-
- Returns:
- 包含操作结果的字典
-
- Examples:
- >>> mouse.drag_rel(100, 50) # 向右下拖拽
- """
- try:
- pyautogui.dragRel(x_offset, y_offset, duration=duration, button=button)
- current_pos = pyautogui.position()
- return {
- 'success': True,
- 'action': 'drag_rel',
- 'position': (current_pos.x, current_pos.y),
- 'offset': (x_offset, y_offset),
- 'button': button,
- 'duration': duration
- }
- except Exception as e:
- return {
- 'success': False,
- 'action': 'drag_rel',
- 'error': str(e)
- }
-
- def scroll(self, clicks: int, x: Optional[int] = None,
- y: Optional[int] = None) -> dict:
- """
- 滚动鼠标滚轮
-
- Args:
- clicks: 滚动单位数,正数向上滚动,负数向下滚动
- x: 在指定位置滚动的X坐标(可选)
- y: 在指定位置滚动的Y坐标(可选)
-
- Returns:
- 包含操作结果的字典
-
- Examples:
- >>> mouse.scroll(5) # 向上滚动5个单位
- >>> mouse.scroll(-3) # 向下滚动3个单位
- >>> mouse.scroll(5, 500, 500) # 在(500, 500)位置向上滚动
- """
- try:
- if x is not None and y is not None:
- pyautogui.scroll(clicks, x, y)
- else:
- pyautogui.scroll(clicks)
-
- return {
- 'success': True,
- 'action': 'scroll',
- 'clicks': clicks,
- 'position': (x, y) if x and y else 'current'
- }
- except Exception as e:
- return {
- 'success': False,
- 'action': 'scroll',
- 'error': str(e)
- }
-
- def get_position(self) -> dict:
- """
- 获取当前鼠标位置
-
- Returns:
- 包含鼠标位置的字典
-
- Examples:
- >>> pos = mouse.get_position()
- >>> print(f"鼠标位置: ({pos['x']}, {pos['y']})")
- """
- try:
- pos = pyautogui.position()
- return {
- 'success': True,
- 'x': pos.x,
- 'y': pos.y,
- 'position': (pos.x, pos.y)
- }
- except Exception as e:
- return {
- 'success': False,
- 'error': str(e)
- }
-
- def mouse_down(self, x: Optional[int] = None, y: Optional[int] = None,
- button: str = 'left') -> dict:
- """
- 按下鼠标按键(不释放)
-
- Args:
- x: X坐标(可选)
- y: Y坐标(可选)
- button: 鼠标按键
-
- Returns:
- 包含操作结果的字典
- """
- try:
- if x is not None and y is not None:
- pyautogui.mouseDown(x, y, button=button)
- else:
- pyautogui.mouseDown(button=button)
-
- return {
- 'success': True,
- 'action': 'mouse_down',
- 'button': button
- }
- except Exception as e:
- return {
- 'success': False,
- 'action': 'mouse_down',
- 'error': str(e)
- }
-
- def mouse_up(self, x: Optional[int] = None, y: Optional[int] = None,
- button: str = 'left') -> dict:
- """
- 释放鼠标按键
-
- Args:
- x: X坐标(可选)
- y: Y坐标(可选)
- button: 鼠标按键
-
- Returns:
- 包含操作结果的字典
- """
- try:
- if x is not None and y is not None:
- pyautogui.mouseUp(x, y, button=button)
- else:
- pyautogui.mouseUp(button=button)
-
- return {
- 'success': True,
- 'action': 'mouse_up',
- 'button': button
- }
- except Exception as e:
- return {
- 'success': False,
- 'action': 'mouse_up',
- 'error': str(e)
- }
-
-
-# 创建全局实例,支持直接调用
-_mouse_instance = Mouse()
-
-# 导出便捷函数
-click = _mouse_instance.click
-double_click = _mouse_instance.double_click
-right_click = _mouse_instance.right_click
-move = _mouse_instance.move
-move_rel = _mouse_instance.move_rel
-drag = _mouse_instance.drag
-drag_rel = _mouse_instance.drag_rel
-scroll = _mouse_instance.scroll
-get_position = _mouse_instance.get_position
-mouse_down = _mouse_instance.mouse_down
-mouse_up = _mouse_instance.mouse_up
\ No newline at end of file
diff --git a/core/computer/screen/__init__.py b/core/computer/screen/__init__.py
deleted file mode 100644
index 4e5eb6a..0000000
--- a/core/computer/screen/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from .screen import Screen
-
-
-__all__ = [Screen]
-
-__version__ = '1.0.0'
\ No newline at end of file
diff --git a/core/computer/screen/screen.py b/core/computer/screen/screen.py
deleted file mode 100644
index eb5521d..0000000
--- a/core/computer/screen/screen.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import base64
-import io
-
-from PIL import Image, ImageGrab
-
-
-class Screen:
- def __init__(self):
- pass
- def screenshot(self, resize_factor: float = 0.5, format: str= "png", quality: int = 100):
- """
- 获取截屏
- :param resize_factor: 缩放因子
- :param format: 格式,可选png/jpeg
- :param quality: 图片质量,jpeg有效
- :return: [{"type": f"image/{format}", "content": base64_encoded}]
- """
- image = ImageGrab.grab()
- new_width = int(image.size[0] * resize_factor)
- new_height = int(image.size[1] * resize_factor)
- image = image.resize((new_width, new_height), Image.LANCZOS)
-
- img_byte_arr= io.BytesIO()
- format = format.lower()
- if format == "png":
- image.save(img_byte_arr, format=format)
- elif format == "jpeg":
- image.save(img_byte_arr, format=format, quality=quality)
- else:
- raise ValueError("[Screen]Unsupported format: ", format)
-
- img_bytes = img_byte_arr.getvalue()
- base64_encoded = base64.b64encode(img_bytes).decode('utf-8')
-
- return [{"type": f"image/{format}", "content": base64_encoded}]
\ No newline at end of file
diff --git a/core/llm/code/__init__.py b/core/llm/code/__init__.py
deleted file mode 100644
index 3dc5561..0000000
--- a/core/llm/code/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from .agent import CodeAgent
-
-__all__ = ["CodeAgent"]
\ No newline at end of file
diff --git a/core/llm/code/agent.py b/core/llm/code/agent.py
deleted file mode 100644
index d06157b..0000000
--- a/core/llm/code/agent.py
+++ /dev/null
@@ -1,202 +0,0 @@
-import logging
-import os
-import time
-import queue
-import threading
-from queue import Queue
-from dotenv import load_dotenv
-from litellm import completion
-from core.computer.code import Code
-from .default_prompt import default_prompt, default_prompt_end
-from .code_parser import CodeParser
-
-dotenv_path = os.path.join(os.path.dirname(__file__), ".env")
-load_dotenv(dotenv_path)
-
-class CodeAgent:
- def __init__(self):
- self.code_executer = Code()
- self.SYSTEM_PROMPT = default_prompt.format(language=str(self.code_executer.language_list))
- logging.info("[CodeAgent]"+self.SYSTEM_PROMPT)
- self.SYSTEM_PROMPT_END = default_prompt_end
- self.loop_breakers = ["The task is done.", "The task is impossible."]
- self.model = os.getenv("CodeAgent_MODEL")
- self.api_base = os.getenv("CodeAgent_API_BASE")
- self.api_key = os.getenv("CodeAgent_API_KEY")
- self.stop_code = False
- self.stop_agent = False
- self.permission = None
-
- def _listener(self, message_from_client: Queue):
- """
- 监听来自客户端的信息
- :param message_from_client:
- :return:
- """
- while True:
- try:
- message = message_from_client.get(timeout=0.5)
- except queue.Empty:
- continue
- print("get client message")
- # 不是发给CodeAgent的信息,放回
- if message["name"] != "CodeAgent":
- message_from_client.put(message)
- continue
- # 允许执行代码
- if message["type"] == "request":
- if message["content"] == "deny":
- self.permission = False
- logging.info("[CodeAgent]User denied execution")
- elif message["content"] == "approve":
- self.permission = True
- logging.info("[CodeAgent]User approved execution")
- # 停止相关
- elif message["content"] == "stop_agent":
- self.stop_agent = True
- logging.info("[CodeAgent]User stopped agent")
- elif message["content"] == "stop_code":
- self.stop_code = True
- logging.info("[CodeAgent]User stopped code execution")
-
- def _should_stop(self, ai_content: str = None):
- if ai_content:
- for loop_breaker in self.loop_breakers:
- if loop_breaker in ai_content:
- return True
- return False
-
- def task(self, description: str, message_from_client: Queue, message_to_client: Queue):
- self.stop_agent = False
- messages = [
- {"role": "system", "content": self.SYSTEM_PROMPT},
- {"role": "user", "content": description}]
- listener_thread = threading.Thread(target=self._listener, args=(message_from_client,))
- listener_thread.daemon = True
- listener_thread.start()
- logging.info("[CodeAgent][START]")
- message_to_client.put({"name": "CodeAgent", "type": "status", "content": "[START]"})
-
- while not self.stop_agent:
- # 请求ai对话
- response = completion(
- model=self.model,
- api_base=self.api_base,
- api_key=self.api_key,
- messages=messages,
- stream=True,
- )
- # 流式返回
- message_to_client.put({"name": "CodeAgent", "type": "ai_content", "content": "[BEGIN]"})
- ai_content = ""
- for chunk in response:
- # 检查是否需要停止
- if self.stop_agent:
- logging.info("[CodeAgent][STOP]: User stop")
- message_to_client.put({"name": "CodeAgent", "type": "status", "content": "[STOP]"})
- return
- if chunk.choices[0].delta.content:
- delta = chunk.choices[0].delta.content
- message_to_client.put({"name": "CodeAgent", "type": "ai_content", "content": delta})
- ai_content += delta
- message_to_client.put({"name": "CodeAgent", "type": "ai_content", "content": "[END]"})
- messages.append({"role": "assistant", "content": ai_content})
-
- # 检查ai是否想要停止
- if self._should_stop(ai_content):
- break
-
- # TODO: If the context is too long, use RAG or other methods to handle it
- # if len(messages) > 10:
- # messages = [messages[0]] + messages[-5:]
-
- # 获取模型返回的代码
- codes = CodeParser(ai_content)
- if not codes:
- messages.append({"role": "user", "content": "No code blocks found. Skip execution. " + self.SYSTEM_PROMPT_END})
- continue
-
- # 依次执行代码
- logging.info(f"Find {len(codes)} code blocks. Executing...")
- for i in range(len(codes)):
-
- logging.info(f"Executing code block {i}..., code: {codes[i]}")
- code = codes[i]
- self.permission = None
- message_to_client.put({"name": "CodeAgent", "type": "status", "content": f"[BLOCK{i}]"})
- message_to_client.put({"name": "CodeAgent", "type": "request", "content": f"[BLOCK{i}]need_permission"})
-
- # 阻塞等待客户端返回允许结果
- print("wtf???")
- while self.permission is None:
- logging.info("waiting permission")
- print("waiting permission")
- # 检查是否需要停止
- time.sleep(0.5)
- if self.stop_agent:
- logging.info("[CodeAgent][STOP]: User stop")
- message_to_client.put({"name": "CodeAgent", "type": "status", "content": "[STOP]"})
- return
- if not self.permission:
- logging.info(f"User rejected to excecute code block{i}")
- messages.append({"role": "user", "content": f"User rejected to excecute code block{i}"})
- continue
-
- logging.info(f"User approved to excecute code block {i}, start executing")
- results = self.code_executer.run(lang=code["lang"], code=code["code"]) # 正确解包
- code_output_content = [{"type": "text", "text": f"Code block{i} is executed, and the output is as follows:"}]
-
- self.stop_code = False
- while self.code_executer.is_running() or not results.empty():
- logging.info(f"[CodeAgent]: Code block{i} is running, code_executer:{self.code_executer.is_running()}, results.empty():{results.empty()}")
- # 检查是否需要停止
- if self.stop_code or self.stop_agent:
- self.code_executer.interrupt()
- break
-
- try:
- delta = results.get(timeout=0.2)
- except queue.Empty:
- continue
-
- # TODO: 有bug,图片先不返回
- if delta["type"] == "image/png" or delta["type"] == "image/jpeg":
- # pass
- message_to_client.put({"name": "CodeAgent", **delta})
- code_output_content.append(
- {
- "type": "image_url",
- "image_url": {
- "url": f"data:{delta["type"]};base64,{delta["content"]}"
- }
- }
- )
- else: # 暂时把其他所有内容转为text
- message_to_client.put({"name": "CodeAgent", "type": "text", "content": delta["content"]})
- code_output_content.append(
- {
- "type": "text",
- "text": delta["content"]
- }
- )
-
- logging.info(f"Finish executing code block {i}")
- messages.append({"role": "user", "content": code_output_content})
-
- messages.append({"role": "user", "content": "All code blocks are executed. " + self.SYSTEM_PROMPT_END})
-
- logging.info("[CodeAgent][STOP]: task finished")
- message_to_client.put({"name": "CodeAgent", "type": "status", "content": "[STOP]"})
- return messages[-1]["content"]
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/core/llm/code/code_parser.py b/core/llm/code/code_parser.py
deleted file mode 100644
index 83b91a9..0000000
--- a/core/llm/code/code_parser.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import re
-
-def CodeParser(text: str):
- pattern = r"```([\w\+\-\.]*)\n([\s\S]*?)\n```"
- matches = re.findall(pattern, text)
-
- results = []
- for lang, code in matches:
- results.append({"lang": lang.strip() if lang else "text", "code": code})
- return results
\ No newline at end of file
diff --git a/core/llm/code/default_prompt.py b/core/llm/code/default_prompt.py
deleted file mode 100644
index 63a6852..0000000
--- a/core/llm/code/default_prompt.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import getpass
-import platform
-
-
-default_prompt = f"""
-You are Open Interpreter, a world-class programmer that can complete any goal by executing code.
-For advanced requests, start by writing a plan.
-When you execute code, it will be executed **on the user's machine**. The user has given you **full and complete permission** to execute any code necessary to complete the task.
-You can access the internet. Run **any code** to achieve the goal, and if at first you don't succeed, try again and again.
-You can install new packages.
-When a user refers to a filename, they're likely referring to an existing file in the directory you're currently executing code in.
-Write messages to the user in Markdown.
-In general, try to **make plans** with as few steps as possible.
-You should try something, print information about it, then continue from there in tiny, informed steps.
-You will never get it on the first try, and attempting it in one go will often lead to errors you cant see.
-You are capable of **any** task.
-Print your code directly in the output. Do not print any additional information, including code explanation, running guide, etc.
-
-Use the following format to output your code:
-
-```python
-# Your python code here
-print("Result to inspect")
-```
-
-User's Name: {getpass.getuser()}
-User's OS: {platform.system()}
-Language: {{language}}
-"""
-
-default_prompt_end = "Are we done? If the task is finished, print \"The task is done.\" in the first line, then summarize the result. If the task is not finished yet, what's next?"
-# As for actually executing code to carry out that plan, for *stateful* languages (like python, javascript, shell, but NOT for html which starts from 0 every time) **it's critical not to try to do everything in one code block.**
-# If the task is impossible, print \"The task is impossible.\" in the first line, then explain why.
\ No newline at end of file
diff --git "a/core/llm/code/\346\266\210\346\201\257\350\256\276\350\256\241.md" "b/core/llm/code/\346\266\210\346\201\257\350\256\276\350\256\241.md"
deleted file mode 100644
index d780a77..0000000
--- "a/core/llm/code/\346\266\210\346\201\257\350\256\276\350\256\241.md"
+++ /dev/null
@@ -1,83 +0,0 @@
-# 消息设计 (Message Design)
-
-Agent 与客户端(UI)之间通过 `Queue` 进行通信,消息格式为 JSON 字典。
-
-## 1. 客户端 -> Agent (Client to Agent)
-客户端发送的消息主要用于控制 Agent 的行为和响应权限请求。
-
-**基本格式:**
-```json
-{
- "name": "CodeAgent", // 给谁发送就填谁
- "type": "request",
- "content": "指令内容"
-}
-```
-
-**指令内容 (content):**
-- `approve`: 允许执行当前代码块。
-- `deny`: 拒绝执行当前代码块。
-- `stop_agent`: 停止整个 Agent 任务。
-- `stop_code`: 停止当前正在执行的代码(中断执行)。
-
-## 3. Agent -> 客户端 (Agent to Client)
-Agent 发送的消息用于更新状态、流式传输 AI 回复、请求权限以及展示代码执行结果。
-
-**基本格式:**
-```json
-{
- "name": "CodeAgent",
- "type": "消息类型",
- "content": "消息内容"
-}
-```
-
-### 3.1 状态消息 (type: "status")
-用于通知 UI 当前 Agent 的工作阶段。
-- `[START]`: 任务开始。
-- `[STOP]`: 任务结束(完成或被用户停止)。
-- `[BLOCK{i}]`: 正在处理第 `i` 个代码块(准备执行)。
-
-### 3.2 AI 内容流 (type: "ai_content")
-用于流式展示 LLM 的思考和回复过程。
-- `[BEGIN]`: 开始生成内容。
-- `[END]`: 内容生成结束。
-- ``: AI 生成的文本片段(增量更新)。
-
-### 3.3 权限请求 (type: "request")
-当 Agent 解析出代码块并准备执行时,向 UI 请求权限。
-- `[BLOCK{i}]need_permission`: 请求执行第 `i` 个代码块的权限。
- - UI 收到此消息后应显示“批准/拒绝”按钮。
-
-### 3.4 代码执行输出 (type: "text" / "image/png" 等)
-展示代码执行的实时输出。
-
-- **文本输出 (type: "text"):**
- - `content`: 标准输出 (stdout) 或标准错误 (stderr) 的文本内容。
-
-- **图片输出 (type: "image/png" / "image/jpeg"):**
- - *注意: 目前 `agent.py` 中图片处理逻辑被注释/跳过,需要修复才能正常接收图片。*
- - `content`: Base64 编码的图片数据。
-
-- **其他类型:**
- - `html`: HTML 内容。
- - `javascript`: JS 代码。
- - `error`: 执行错误信息。
-
-## 4. 交互流程示例 (Interaction Flow)
-
-调用`CodeAgent.task("任务描述")`之后:
-
-1. **任务开始**: Agent 发送 `status: [START]`。
-2. **AI 思考**: Agent 发送 `ai_content: [BEGIN]`, 随后发送多条内容片段, 最后发送 `ai_content: [END]`。
-3. **代码解析**: Agent 发现代码块。(Agent发现的代码块并不会传给客户端,客户端需要自己按顺序切分代码片段)
-4. **请求权限**: Agent 发送 `status: [BLOCK0]`, `request: [BLOCK0]need_permission`。
-5. **用户确认**: 客户端发送 `content: approve`。
-6. **代码执行**: Agent 执行代码,持续发送 `type: text` (日志/结果)。
-7. **执行完成**: Agent 继续下一轮或结束。
-8. **任务结束**: Agent 发送 `status: [STOP]`。
-
-## 5. TODO (Suggestions)
-1. **修复图片传输**: base64太长,之后可以采取压缩方法
-2. **结构化状态**: 目前的 `[START]` 等状态码混在 `content` 字符串中,建议后续优化为独立的枚举字段,方便前端解析。
-3. **上下文未处理**
diff --git a/core/llm/gui/__init__.py b/core/llm/gui/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index cac7992..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-litellm
-jupyter_client
-pyautogui
\ No newline at end of file