pycoze 0.1.341__py3-none-any.whl → 0.1.343__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pycoze/bot/chat.py CHANGED
@@ -1,100 +1,130 @@
1
- import json
2
- from .chat_base import handle_user_inputs
3
- from .lib import get_abilities, get_system_prompt
4
- from .message import INPUT_MESSAGE, output, CHAT_DATA, clear_chat_data
5
- import os
6
- import asyncio
7
- from pycoze import utils
8
- import tempfile
9
-
10
-
11
- async def check_interrupt_file(interval, interrupt_file, chat_task):
12
- while True:
13
- await asyncio.sleep(interval)
14
- if os.path.exists(interrupt_file):
15
- os.remove(interrupt_file)
16
- chat_task.cancel()
17
- break
18
-
19
-
20
- async def run_with_interrupt_check(conversation_history, user_input, cwd: str, abilities, has_any_tool, bot_setting, interrupt_file):
21
- clear_chat_data()
22
- try:
23
- chat_task = asyncio.create_task(
24
- handle_user_inputs(conversation_history, user_input, cwd, abilities, has_any_tool, bot_setting)
25
- )
26
- check_task = asyncio.create_task(
27
- check_interrupt_file(0.5, interrupt_file, chat_task)
28
- )
29
- result = await chat_task
30
- return result
31
- except asyncio.CancelledError:
32
- return CHAT_DATA["info"]
33
- except Exception as e:
34
- import traceback
35
-
36
- print(traceback.format_exc())
37
- return None # 返回 None 或者处理异常后的结果
38
- finally:
39
- if not chat_task.done():
40
- chat_task.cancel()
41
- # 确保即使发生异常也会取消检查任务
42
- if not check_task.done():
43
- check_task.cancel()
44
- try:
45
- await check_task
46
- except asyncio.CancelledError:
47
- pass # 忽略取消错误
48
-
49
-
50
- def chat(bot_setting_file: str):
51
- with open(bot_setting_file, encoding="utf-8") as f:
52
- bot_setting = json.load(f)
53
- abilities = get_abilities(bot_setting)
54
- cwd = tempfile.mkdtemp()
55
- system_prompt, has_any_tool = get_system_prompt(abilities, bot_setting)
56
- conversation_history = [
57
- {
58
- "role": "system",
59
- "content": system_prompt,
60
- }
61
- ]
62
- while True:
63
- clear_chat_data()
64
- input_text = input()
65
- if not input_text.startswith(INPUT_MESSAGE):
66
- raise ValueError("Invalid message")
67
- message = json.loads(input_text[len(INPUT_MESSAGE) :])
68
- user_input = message["content"]
69
- params = utils.params
70
- if "interruptFile" in params:
71
- asyncio.run(
72
- run_with_interrupt_check(
73
- conversation_history, user_input, cwd, abilities, has_any_tool, bot_setting, params["interruptFile"]
74
- )
75
- )
76
- else:
77
- asyncio.run(
78
- handle_user_inputs(conversation_history, user_input, cwd, abilities, has_any_tool, bot_setting)
79
- )
80
-
81
- output("assistant", CHAT_DATA["info"])
82
-
83
-
84
- def get_chat_response(bot_setting_file: str, user_input: str):
85
- with open(bot_setting_file, encoding="utf-8") as f:
86
- bot_setting = json.load(f)
87
- abilities = get_abilities(bot_setting)
88
- cwd = tempfile.mkdtemp()
89
- system_prompt, has_any_tool = get_system_prompt(abilities, bot_setting)
90
- conversation_history = [
91
- {
92
- "role": "system",
93
- "content": system_prompt,
94
- }
95
- ]
96
- asyncio.run(
97
- handle_user_inputs(conversation_history, user_input, cwd, abilities, has_any_tool, bot_setting)
98
- )
99
-
100
- return CHAT_DATA["info"]
1
+ import json
2
+ from .chat_base import handle_user_inputs
3
+ from .lib import get_abilities, get_system_prompt
4
+ from .message import INPUT_MESSAGE, output, CHAT_DATA, clear_chat_data
5
+ import os
6
+ import asyncio
7
+ from pycoze import utils
8
+ import tempfile
9
+
10
+
11
+ async def check_interrupt_file(interval, interrupt_file, chat_task):
12
+ while True:
13
+ await asyncio.sleep(interval)
14
+ if os.path.exists(interrupt_file):
15
+ os.remove(interrupt_file)
16
+ chat_task.cancel()
17
+ break
18
+
19
+
20
+ async def run_with_interrupt_check(
21
+ conversation_history,
22
+ user_input,
23
+ cwd: str,
24
+ abilities,
25
+ has_any_tool,
26
+ bot_setting,
27
+ interrupt_file,
28
+ ):
29
+ clear_chat_data()
30
+ try:
31
+ chat_task = asyncio.create_task(
32
+ handle_user_inputs(
33
+ conversation_history,
34
+ user_input,
35
+ cwd,
36
+ abilities,
37
+ has_any_tool,
38
+ bot_setting,
39
+ )
40
+ )
41
+ check_task = asyncio.create_task(
42
+ check_interrupt_file(0.5, interrupt_file, chat_task)
43
+ )
44
+ result = await chat_task
45
+ return result
46
+ except asyncio.CancelledError:
47
+ return CHAT_DATA["info"]
48
+ except Exception as e:
49
+ import traceback
50
+
51
+ print(traceback.format_exc())
52
+ return None # 返回 None 或者处理异常后的结果
53
+ finally:
54
+ if not chat_task.done():
55
+ chat_task.cancel()
56
+ # 确保即使发生异常也会取消检查任务
57
+ if not check_task.done():
58
+ check_task.cancel()
59
+ try:
60
+ await check_task
61
+ except asyncio.CancelledError:
62
+ pass # 忽略取消错误
63
+
64
+
65
+ def chat(bot_setting_file: str):
66
+ with open(bot_setting_file, encoding="utf-8") as f:
67
+ bot_setting = json.load(f)
68
+ abilities = get_abilities(bot_setting)
69
+ cwd = tempfile.mkdtemp()
70
+ system_prompt, has_any_tool = get_system_prompt(abilities, bot_setting)
71
+ conversation_history = [
72
+ {
73
+ "role": "system",
74
+ "content": system_prompt,
75
+ }
76
+ ]
77
+ while True:
78
+ clear_chat_data()
79
+ input_text = input()
80
+ if not input_text.startswith(INPUT_MESSAGE):
81
+ raise ValueError("Invalid message")
82
+ message = json.loads(input_text[len(INPUT_MESSAGE) :])
83
+ user_input = message["content"]
84
+ params = utils.params
85
+ if "interruptFile" in params:
86
+ asyncio.run(
87
+ run_with_interrupt_check(
88
+ conversation_history,
89
+ user_input,
90
+ cwd,
91
+ abilities,
92
+ has_any_tool,
93
+ bot_setting,
94
+ params["interruptFile"],
95
+ )
96
+ )
97
+ else:
98
+ asyncio.run(
99
+ handle_user_inputs(
100
+ conversation_history,
101
+ user_input,
102
+ cwd,
103
+ abilities,
104
+ has_any_tool,
105
+ bot_setting,
106
+ )
107
+ )
108
+ print("has_output")
109
+ output("assistant", CHAT_DATA["info"])
110
+
111
+
112
+ def get_chat_response(bot_setting_file: str, user_input: str):
113
+ with open(bot_setting_file, encoding="utf-8") as f:
114
+ bot_setting = json.load(f)
115
+ abilities = get_abilities(bot_setting)
116
+ cwd = tempfile.mkdtemp()
117
+ system_prompt, has_any_tool = get_system_prompt(abilities, bot_setting)
118
+ conversation_history = [
119
+ {
120
+ "role": "system",
121
+ "content": system_prompt,
122
+ }
123
+ ]
124
+ asyncio.run(
125
+ handle_user_inputs(
126
+ conversation_history, user_input, cwd, abilities, has_any_tool, bot_setting
127
+ )
128
+ )
129
+
130
+ return CHAT_DATA["info"]
pycoze/bot/tools.py CHANGED
@@ -53,7 +53,7 @@ class ExecuteCommandTool(Tool):
53
53
  shell=True,
54
54
  capture_output=True,
55
55
  text=True,
56
- cwd=self.cwd
56
+ cwd=self.cwd,
57
57
  )
58
58
  if result.returncode != 0:
59
59
  raise subprocess.CalledProcessError(
@@ -73,7 +73,9 @@ class ReadFileTool(Tool):
73
73
  """读取文件工具"""
74
74
 
75
75
  def validate(self) -> bool:
76
- return "path" in self.params and os.path.exists(resolve_relative_path(self.cwd, self.params["path"]))
76
+ return "path" in self.params and os.path.exists(
77
+ resolve_relative_path(self.cwd, self.params["path"])
78
+ )
77
79
 
78
80
  def execute(self) -> str:
79
81
  path = resolve_relative_path(self.cwd, self.params["path"])
@@ -196,13 +198,15 @@ class WebAccessTool(Tool):
196
198
  try:
197
199
  content = web.get_simplified_webpage(url)[: 32 * 1024]
198
200
  result = ai.chat(
199
- [{
200
- "role": "user",
201
- "content": f"""Please answer user question based on web page content. The user's question is:
201
+ [
202
+ {
203
+ "role": "user",
204
+ "content": f"""Please answer user question based on web page content. The user's question is:
202
205
  {question}
203
206
  Web page content is:
204
- {content}"""
205
- }],
207
+ {content}""",
208
+ }
209
+ ],
206
210
  )
207
211
  return f"Web page access completed, result is: {result}"
208
212
  except Exception as e:
@@ -214,10 +218,10 @@ class AskFollowUpQuestionTool(Tool):
214
218
  """询问后续问题工具"""
215
219
 
216
220
  def validate(self) -> bool:
217
- return 'question' in self.params
221
+ return "question" in self.params
218
222
 
219
223
  def execute(self) -> str:
220
- info("assistant", self.params['question'])
224
+ info("assistant", self.params["question"])
221
225
  return f"Asked user: {self.params['question']}, Waiting for user replied.\n\n"
222
226
 
223
227
 
@@ -225,13 +229,20 @@ class AttemptTaskCompletionTool(Tool):
225
229
  """完成所有任务工具"""
226
230
 
227
231
  def validate(self) -> bool:
228
- return 'result' in self.params
232
+ return "result" in self.params
229
233
 
230
234
  def execute(self) -> str:
231
- result = self.params['result']
232
- info("assistant", 'Completed:' + result + "\n")
233
- if 'command' in self.params:
234
- result = subprocess.run(self.params['command'], shell=True, capture_output=True, text=True, cwd=self.cwd)
235
+ result = self.params["result"]
236
+ info("assistant", "Completed:" + result + "\n")
237
+ print("self.params", self.params)
238
+ if "command" in self.params:
239
+ result = subprocess.run(
240
+ self.params["command"],
241
+ shell=True,
242
+ capture_output=True,
243
+ text=True,
244
+ cwd=self.cwd,
245
+ )
235
246
  return f"Task completed: {result}, executed command: {self.params['command']}, execution result: {result.stdout + result.stderr}"
236
247
  else:
237
248
  return f"Task completed: {result}"
@@ -249,12 +260,12 @@ class ToolExecutor:
249
260
  "search_files": SearchFilesTool,
250
261
  "list_files": ListFilesTool,
251
262
  "access_webpage": WebAccessTool,
252
- 'ask_follow_up_question': AskFollowUpQuestionTool,
253
- 'complete_all_tasks': AttemptTaskCompletionTool,
263
+ "ask_follow_up_question": AskFollowUpQuestionTool,
264
+ "complete_all_tasks": AttemptTaskCompletionTool,
254
265
  }
255
266
 
256
267
  @classmethod
257
- def execute_tool(cls, cwd:str, tool_request, abilities) -> Tuple[bool, bool, any]:
268
+ def execute_tool(cls, cwd: str, tool_request, abilities) -> Tuple[bool, bool, any]:
258
269
  """执行工具"""
259
270
  try:
260
271
  tool_name = list(tool_request.keys())[0]
@@ -274,9 +285,13 @@ class ToolExecutor:
274
285
  result = json.dumps(result, indent=4, ensure_ascii=False)
275
286
  except:
276
287
  return True, False, str(result)
277
- return True, True,str(result)
288
+ return True, True, str(result)
278
289
  else:
279
- return False, False, f"Unknown tool: {tool_name}, the first key of output json ({tool_name}) will be recognized as a tool, so do not output other json except for executing tools."
290
+ return (
291
+ False,
292
+ False,
293
+ f"Unknown tool: {tool_name}, the first key of output json ({tool_name}) will be recognized as a tool, so do not output other json except for executing tools.",
294
+ )
280
295
  tool = tool_class(params, cwd)
281
296
  if not tool.validate():
282
297
  return False, False, "Tool parameter validation failed."
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pycoze
3
- Version: 0.1.341
3
+ Version: 0.1.343
4
4
  Summary: Package for pycoze only!
5
5
  Home-page: UNKNOWN
6
6
  Author: Yuan Jie Xiong
@@ -12,12 +12,12 @@ pycoze/api/lib/view.py,sha256=_PIpTfeuTPPlMDKshMGsqFQYMq7ZiO4Hg5XwHwDoU60,7357
12
12
  pycoze/api/lib/web.py,sha256=GWgtiTJOolKOX2drXcwuyqTcbo5FQVxa1NuBGcNyjyc,223
13
13
  pycoze/api/lib/window.py,sha256=bTkQCzQZ7i3pYXB70bUSTBNJ9C4TW_X3yMae1VkquGk,1944
14
14
  pycoze/bot/__init__.py,sha256=rL3Q-ycczRpSFfKn84fg3QBl5k22WpyeIU5qOEjEby8,79
15
- pycoze/bot/chat.py,sha256=s12X8iOZa8MK-5VUd9JfzIA-gLxY80FJfphcfEx3b_s,3414
15
+ pycoze/bot/chat.py,sha256=DB0fUb4B0EVRWWEavCzIa-cSXOpiZrxIusJnQYGPKG8,3765
16
16
  pycoze/bot/chat_base.py,sha256=d7rsp_E1woC8UFBsqPExicNfwMHAB0e50vsodL8ISGA,9722
17
17
  pycoze/bot/lib.py,sha256=smigeWuhl8esHE-Y5l_9bpjJkEJ5OqrxTyPcO8JIubM,7224
18
18
  pycoze/bot/message.py,sha256=Zq-_k8HztBMOUIs3hbOvWvwHBNopn4UJJBliCROIGcc,718
19
19
  pycoze/bot/prompt.md,sha256=OBxwUY6yiwEmusnUHhwixWYByrWX3BpwfxG_Gfas8UM,15783
20
- pycoze/bot/tools.py,sha256=23iDk0_myJcQDOErKm4LRGr1Foane1n_RNNKJPAmgdY,9953
20
+ pycoze/bot/tools.py,sha256=dsxsfT1DoeoT46PNGi6fvPbvTH1B9RbU0w6U-uvZbmI,10247
21
21
  pycoze/reference/__init__.py,sha256=zgqGqvmA9HaqytEM33B6vi0kQVk8IiCwJaXa22xsFz8,114
22
22
  pycoze/reference/bot.py,sha256=pxHVYo0G3P3YZ--vBYbMEiEyBoxxPwaO5dMTf9WFMSc,2014
23
23
  pycoze/reference/lib.py,sha256=T-oBOKxkus5dTouc0oDgfRzUyi6aTyY-FF4yX7SzF5M,3755
@@ -33,8 +33,8 @@ pycoze/utils/arg.py,sha256=jop1tBfe5hYkHW1NSpCeaZBEznkgguBscj_7M2dWfrs,503
33
33
  pycoze/utils/env.py,sha256=5pWlXfM1F5ZU9hhv1rHlDEanjEW5wf0nbyez9bNRqqA,559
34
34
  pycoze/utils/socket.py,sha256=bZbFFRH4mfThzRqt55BAAGQ6eICx_ja4x8UGGrUdAm8,2428
35
35
  pycoze/utils/text_or_file.py,sha256=gpxZVWt2DW6YiEg_MnMuwg36VNf3TX383QD_1oZNB0Y,551
36
- pycoze-0.1.341.dist-info/LICENSE,sha256=QStd_Qsd0-kAam_-sOesCIp_uKrGWeoKwt9M49NVkNU,1090
37
- pycoze-0.1.341.dist-info/METADATA,sha256=4TbIEp79JsS7uw3qPGCEUWF6wdY8W9XwtTk3HMuf75c,755
38
- pycoze-0.1.341.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92
39
- pycoze-0.1.341.dist-info/top_level.txt,sha256=76dPeDhKvOCleL3ZC5gl1-y4vdS1tT_U1hxWVAn7sFo,7
40
- pycoze-0.1.341.dist-info/RECORD,,
36
+ pycoze-0.1.343.dist-info/LICENSE,sha256=QStd_Qsd0-kAam_-sOesCIp_uKrGWeoKwt9M49NVkNU,1090
37
+ pycoze-0.1.343.dist-info/METADATA,sha256=m24gK8AcSDRGaGsrR1dmSLjzDW5R5wRAafj1tsWg8G8,755
38
+ pycoze-0.1.343.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92
39
+ pycoze-0.1.343.dist-info/top_level.txt,sha256=76dPeDhKvOCleL3ZC5gl1-y4vdS1tT_U1hxWVAn7sFo,7
40
+ pycoze-0.1.343.dist-info/RECORD,,