jarvis-ai-assistant 0.1.17__tar.gz → 0.1.19__tar.gz

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.

Potentially problematic release.


This version of jarvis-ai-assistant might be problematic. Click here for more details.

Files changed (57) hide show
  1. {jarvis_ai_assistant-0.1.17/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.1.19}/PKG-INFO +137 -1
  2. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/README.md +136 -0
  3. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/pyproject.toml +1 -1
  4. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/setup.py +1 -1
  5. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/__init__.py +1 -1
  6. jarvis_ai_assistant-0.1.19/src/jarvis/__pycache__/__init__.cpython-313.pyc +0 -0
  7. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/__pycache__/agent.cpython-313.pyc +0 -0
  8. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/__pycache__/main.cpython-313.pyc +0 -0
  9. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/agent.py +39 -71
  10. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/main.py +35 -5
  11. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/tools/__init__.py +2 -0
  12. jarvis_ai_assistant-0.1.19/src/jarvis/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  13. jarvis_ai_assistant-0.1.19/src/jarvis/tools/__pycache__/base.cpython-313.pyc +0 -0
  14. jarvis_ai_assistant-0.1.19/src/jarvis/tools/__pycache__/calculator.cpython-313.pyc +0 -0
  15. jarvis_ai_assistant-0.1.19/src/jarvis/tools/__pycache__/calculator_tool.cpython-313.pyc +0 -0
  16. jarvis_ai_assistant-0.1.19/src/jarvis/tools/__pycache__/file_ops.cpython-313.pyc +0 -0
  17. jarvis_ai_assistant-0.1.19/src/jarvis/tools/__pycache__/generator.cpython-313.pyc +0 -0
  18. jarvis_ai_assistant-0.1.19/src/jarvis/tools/__pycache__/shell.cpython-313.pyc +0 -0
  19. jarvis_ai_assistant-0.1.19/src/jarvis/tools/base.py +195 -0
  20. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/tools/file_ops.py +22 -3
  21. jarvis_ai_assistant-0.1.19/src/jarvis/tools/generator.py +227 -0
  22. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/tools/shell.py +23 -6
  23. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19/src/jarvis_ai_assistant.egg-info}/PKG-INFO +137 -1
  24. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +4 -0
  25. jarvis_ai_assistant-0.1.17/src/jarvis/__pycache__/__init__.cpython-313.pyc +0 -0
  26. jarvis_ai_assistant-0.1.17/src/jarvis/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  27. jarvis_ai_assistant-0.1.17/src/jarvis/tools/__pycache__/base.cpython-313.pyc +0 -0
  28. jarvis_ai_assistant-0.1.17/src/jarvis/tools/__pycache__/file_ops.cpython-313.pyc +0 -0
  29. jarvis_ai_assistant-0.1.17/src/jarvis/tools/__pycache__/shell.cpython-313.pyc +0 -0
  30. jarvis_ai_assistant-0.1.17/src/jarvis/tools/base.py +0 -113
  31. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/LICENSE +0 -0
  32. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/MANIFEST.in +0 -0
  33. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/setup.cfg +0 -0
  34. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/__pycache__/models.cpython-313.pyc +0 -0
  35. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/__pycache__/tools.cpython-313.pyc +0 -0
  36. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/__pycache__/utils.cpython-313.pyc +0 -0
  37. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/__pycache__/zte_llm.cpython-313.pyc +0 -0
  38. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/models/__init__.py +0 -0
  39. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/models/__pycache__/__init__.cpython-313.pyc +0 -0
  40. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/models/__pycache__/base.cpython-313.pyc +0 -0
  41. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/models/__pycache__/kimi.cpython-313.pyc +0 -0
  42. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/models/base.py +0 -0
  43. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/models/kimi.py +0 -0
  44. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/tools/__pycache__/bing_search.cpython-313.pyc +0 -0
  45. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/tools/__pycache__/python_script.cpython-313.pyc +0 -0
  46. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/tools/__pycache__/rag.cpython-313.pyc +0 -0
  47. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/tools/__pycache__/search.cpython-313.pyc +0 -0
  48. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/tools/__pycache__/sub_agent.cpython-313.pyc +0 -0
  49. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/tools/__pycache__/user_confirmation.cpython-313.pyc +0 -0
  50. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/tools/__pycache__/user_input.cpython-313.pyc +0 -0
  51. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/tools/__pycache__/user_interaction.cpython-313.pyc +0 -0
  52. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/tools/__pycache__/webpage.cpython-313.pyc +0 -0
  53. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis/utils.py +0 -0
  54. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
  55. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -0
  56. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
  57. {jarvis_ai_assistant-0.1.17 → jarvis_ai_assistant-0.1.19}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.17
3
+ Version: 0.1.19
4
4
  Summary: Jarvis: An AI assistant that uses tools to interact with the system
5
5
  Home-page: https://github.com/skyfireitdiy/Jarvis
6
6
  Author: skyfire
@@ -87,6 +87,9 @@ Dynamic: requires-python
87
87
  - File operations (read/write/append)
88
88
  - Task automation
89
89
  - Predefined task support
90
+ - Dynamic tool system with auto-loading
91
+ - AI-powered tool generation
92
+ - Custom tool development
90
93
 
91
94
  🔄 **Interactive Experience**
92
95
  - Natural language understanding
@@ -95,6 +98,139 @@ Dynamic: requires-python
95
98
  - Multi-line input support
96
99
  - Colored output with progress indicators
97
100
 
101
+ ## 🛠️ Custom Tools
102
+
103
+ ### Tool Locations
104
+ - Built-in tools: `src/jarvis/tools/`
105
+ - User tools: `~/.jarvis_tools/` (automatically created)
106
+
107
+ ### Creating Tools
108
+
109
+ #### 1. Using AI Generator (Recommended)
110
+ ```yaml
111
+ <START_TOOL_CALL>
112
+ name: generate_tool
113
+ arguments:
114
+ tool_name: calculator
115
+ class_name: CalculatorTool
116
+ description: Basic math calculations
117
+ parameters:
118
+ type: object
119
+ properties:
120
+ operation:
121
+ type: string
122
+ enum: ["add", "subtract", "multiply", "divide"]
123
+ numbers:
124
+ type: array
125
+ items:
126
+ type: number
127
+ required: ["operation", "numbers"]
128
+ <END_TOOL_CALL>
129
+ ```
130
+
131
+ #### 2. Manual Creation
132
+ Create a new Python file in `~/.jarvis_tools/`:
133
+
134
+ ```python
135
+ from typing import Dict, Any, Protocol, Optional
136
+ from enum import Enum
137
+
138
+ class OutputType(Enum):
139
+ INFO = "info"
140
+ ERROR = "error"
141
+
142
+ class OutputHandler(Protocol):
143
+ def print(self, text: str, output_type: OutputType) -> None: ...
144
+
145
+ class ModelHandler(Protocol):
146
+ def chat(self, message: str) -> str: ...
147
+
148
+ class CustomTool:
149
+ name = "tool_name" # Tool name for invocation
150
+ description = "Tool description" # Tool purpose
151
+ parameters = { # JSON Schema for parameters
152
+ "type": "object",
153
+ "properties": {
154
+ "param1": {"type": "string"}
155
+ },
156
+ "required": ["param1"]
157
+ }
158
+
159
+ def __init__(self, **kwargs):
160
+ """Initialize tool with optional dependencies
161
+
162
+ Args:
163
+ model: AI model for advanced features
164
+ output_handler: For consistent output formatting
165
+ register: Access to tool registry
166
+ """
167
+ self.model = kwargs.get('model')
168
+ self.output = kwargs.get('output_handler')
169
+ self.register = kwargs.get('register')
170
+
171
+ def _print(self, text: str, output_type: OutputType = OutputType.INFO):
172
+ """Print formatted output"""
173
+ if self.output:
174
+ self.output.print(text, output_type)
175
+
176
+ def execute(self, args: Dict) -> Dict[str, Any]:
177
+ """Execute tool functionality
178
+
179
+ Args:
180
+ args: Parameters passed to the tool
181
+
182
+ Returns:
183
+ Dict with execution results:
184
+ {
185
+ "success": bool,
186
+ "stdout": str, # On success
187
+ "stderr": str, # Optional error details
188
+ "error": str # On failure
189
+ }
190
+ """
191
+ try:
192
+ # Implement tool logic here
193
+ result = "Tool execution result"
194
+
195
+ return {
196
+ "success": True,
197
+ "stdout": result,
198
+ "stderr": ""
199
+ }
200
+ except Exception as e:
201
+ self._print(str(e), OutputType.ERROR)
202
+ return {
203
+ "success": False,
204
+ "error": str(e)
205
+ }
206
+ ```
207
+
208
+ ### Development Guidelines
209
+
210
+ 1. **Tool Structure**
211
+ - Clear name and description
212
+ - Well-defined parameters schema
213
+ - Proper error handling
214
+ - Consistent output format
215
+
216
+ 2. **Best Practices**
217
+ - Use `_print` for output
218
+ - Handle all required parameters
219
+ - Document functionality
220
+ - Return standardized results
221
+ - Keep tools focused and simple
222
+
223
+ 3. **Testing**
224
+ - Verify parameter validation
225
+ - Test error handling
226
+ - Check output format
227
+ - Ensure proper cleanup
228
+
229
+ 4. **Integration**
230
+ - Tools are auto-loaded on startup
231
+ - No manual registration needed
232
+ - Hot-reload supported
233
+ - Dependencies injected automatically
98
234
 
99
235
  ## ⚙️ Environment Setup
100
236
 
@@ -34,6 +34,9 @@
34
34
  - File operations (read/write/append)
35
35
  - Task automation
36
36
  - Predefined task support
37
+ - Dynamic tool system with auto-loading
38
+ - AI-powered tool generation
39
+ - Custom tool development
37
40
 
38
41
  🔄 **Interactive Experience**
39
42
  - Natural language understanding
@@ -42,6 +45,139 @@
42
45
  - Multi-line input support
43
46
  - Colored output with progress indicators
44
47
 
48
+ ## 🛠️ Custom Tools
49
+
50
+ ### Tool Locations
51
+ - Built-in tools: `src/jarvis/tools/`
52
+ - User tools: `~/.jarvis_tools/` (automatically created)
53
+
54
+ ### Creating Tools
55
+
56
+ #### 1. Using AI Generator (Recommended)
57
+ ```yaml
58
+ <START_TOOL_CALL>
59
+ name: generate_tool
60
+ arguments:
61
+ tool_name: calculator
62
+ class_name: CalculatorTool
63
+ description: Basic math calculations
64
+ parameters:
65
+ type: object
66
+ properties:
67
+ operation:
68
+ type: string
69
+ enum: ["add", "subtract", "multiply", "divide"]
70
+ numbers:
71
+ type: array
72
+ items:
73
+ type: number
74
+ required: ["operation", "numbers"]
75
+ <END_TOOL_CALL>
76
+ ```
77
+
78
+ #### 2. Manual Creation
79
+ Create a new Python file in `~/.jarvis_tools/`:
80
+
81
+ ```python
82
+ from typing import Dict, Any, Protocol, Optional
83
+ from enum import Enum
84
+
85
+ class OutputType(Enum):
86
+ INFO = "info"
87
+ ERROR = "error"
88
+
89
+ class OutputHandler(Protocol):
90
+ def print(self, text: str, output_type: OutputType) -> None: ...
91
+
92
+ class ModelHandler(Protocol):
93
+ def chat(self, message: str) -> str: ...
94
+
95
+ class CustomTool:
96
+ name = "tool_name" # Tool name for invocation
97
+ description = "Tool description" # Tool purpose
98
+ parameters = { # JSON Schema for parameters
99
+ "type": "object",
100
+ "properties": {
101
+ "param1": {"type": "string"}
102
+ },
103
+ "required": ["param1"]
104
+ }
105
+
106
+ def __init__(self, **kwargs):
107
+ """Initialize tool with optional dependencies
108
+
109
+ Args:
110
+ model: AI model for advanced features
111
+ output_handler: For consistent output formatting
112
+ register: Access to tool registry
113
+ """
114
+ self.model = kwargs.get('model')
115
+ self.output = kwargs.get('output_handler')
116
+ self.register = kwargs.get('register')
117
+
118
+ def _print(self, text: str, output_type: OutputType = OutputType.INFO):
119
+ """Print formatted output"""
120
+ if self.output:
121
+ self.output.print(text, output_type)
122
+
123
+ def execute(self, args: Dict) -> Dict[str, Any]:
124
+ """Execute tool functionality
125
+
126
+ Args:
127
+ args: Parameters passed to the tool
128
+
129
+ Returns:
130
+ Dict with execution results:
131
+ {
132
+ "success": bool,
133
+ "stdout": str, # On success
134
+ "stderr": str, # Optional error details
135
+ "error": str # On failure
136
+ }
137
+ """
138
+ try:
139
+ # Implement tool logic here
140
+ result = "Tool execution result"
141
+
142
+ return {
143
+ "success": True,
144
+ "stdout": result,
145
+ "stderr": ""
146
+ }
147
+ except Exception as e:
148
+ self._print(str(e), OutputType.ERROR)
149
+ return {
150
+ "success": False,
151
+ "error": str(e)
152
+ }
153
+ ```
154
+
155
+ ### Development Guidelines
156
+
157
+ 1. **Tool Structure**
158
+ - Clear name and description
159
+ - Well-defined parameters schema
160
+ - Proper error handling
161
+ - Consistent output format
162
+
163
+ 2. **Best Practices**
164
+ - Use `_print` for output
165
+ - Handle all required parameters
166
+ - Document functionality
167
+ - Return standardized results
168
+ - Keep tools focused and simple
169
+
170
+ 3. **Testing**
171
+ - Verify parameter validation
172
+ - Test error handling
173
+ - Check output format
174
+ - Ensure proper cleanup
175
+
176
+ 4. **Integration**
177
+ - Tools are auto-loaded on startup
178
+ - No manual registration needed
179
+ - Hot-reload supported
180
+ - Dependencies injected automatically
45
181
 
46
182
  ## ⚙️ Environment Setup
47
183
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "jarvis-ai-assistant"
7
- version = "0.1.17"
7
+ version = "0.1.19"
8
8
  description = "Jarvis: An AI assistant that uses tools to interact with the system"
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Your Name", email = "your.email@example.com" }]
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="jarvis-ai-assistant",
5
- version="0.1.17",
5
+ version="0.1.19",
6
6
  author="skyfire",
7
7
  author_email="skyfireitdiy@hotmail.com",
8
8
  description="An AI assistant that uses various tools to interact with the system",
@@ -1,3 +1,3 @@
1
1
  """Jarvis AI Assistant"""
2
2
 
3
- __version__ = "0.1.17"
3
+ __version__ = "0.1.19"
@@ -103,55 +103,32 @@ class Agent:
103
103
  tools_prompt += f" 描述: {tool['description']}\n"
104
104
  tools_prompt += f" 参数: {tool['parameters']}\n"
105
105
 
106
- self.prompt = f"""你是 {self.name},一个严格遵循 ReAct 框架进行逐步推理和行动的 AI 助手。
106
+ self.prompt = f"""你是 {self.name},一个严格遵循 ReAct 框架的 AI 助手。
107
107
 
108
108
  {tools_prompt}
109
109
 
110
- 关键规则:
111
- ‼️ 禁止创建虚假对话
112
- ‼️ 禁止假设用户回应
113
- ‼️ 禁止在没有实际用户输入时继续
114
- ‼️ 只回应用户实际说的内容
115
- ‼️ 每个动作后停止并等待
110
+ 核心能力:
111
+ 1. 使用现有工具完成任务
112
+ 2. 通过 generate_tool 创建新工具扩展功能
113
+ 3. 遵循 ReAct (思考-行动-观察) 框架
116
114
 
117
- ReAct 框架:
115
+ 工作流程:
118
116
  1. 思考
119
- - 分析当前情况
120
- - 考虑可用工具
121
- - 规划下一步行动
122
- - 仅基于事实
123
- - 不做用户回应的假设
124
- - 不想象对话内容
125
-
126
- 2. 行动(可选)
127
- - 不是每次回应都需要调用工具
128
- - 如果需要更多信息,直接询问用户
129
- - 使用工具时:
130
- - 只使用下面列出的工具
131
- - 每次只执行一个工具
132
- - 工具由用户手动执行
133
- - 必须使用有效合法的YAML格式:
134
- <START_TOOL_CALL>
135
- name: tool_name
136
- arguments:
137
- param1: value1 # 所有参数必须正确缩进
138
- param2: | # 使用YAML块样式表示多行字符串
139
- line1
140
- line2
141
- <END_TOOL_CALL>
142
-
117
+ - 分析需求和可用工具
118
+ - 评估是否需要新工具
119
+ - 规划解决方案
120
+
121
+ 2. 行动 (如果需要)
122
+ - 使用现有工具
123
+ - 创建新工具
124
+ - 询问更多信息
125
+
143
126
  3. 观察
144
- - 等待工具执行结果或用户回应
145
- - 工具执行结果由用户提供
146
- - 不要假设或想象回应
147
- - 不要创建虚假对话
148
- - 停止并等待实际输入
127
+ - 等待执行结果
128
+ - 分析反馈
129
+ - 规划下一步
149
130
 
150
- 回应格式:
151
- 思考:我分析当前情况[具体情况]... 基于[事实],我需要[目标]...
152
-
153
- [如果需要使用工具:]
154
- 行动:我将使用[工具]来[具体目的]...
131
+ 工具使用格式:
155
132
  <START_TOOL_CALL>
156
133
  name: tool_name
157
134
  arguments:
@@ -161,37 +138,28 @@ arguments:
161
138
  value
162
139
  <END_TOOL_CALL>
163
140
 
164
- [如果需要更多信息:]
165
- 我需要了解更多关于[具体细节]的信息。请提供[需要的信息]。
141
+ 创建新工具示例:
142
+ <START_TOOL_CALL>
143
+ name: generate_tool
144
+ arguments:
145
+ tool_name: custom_tool_name
146
+ class_name: CustomToolName
147
+ description: 详细的工具描述
148
+ parameters:
149
+ type: object
150
+ properties:
151
+ param1:
152
+ type: string
153
+ description: 参数1的描述
154
+ required: [param1]
155
+ <END_TOOL_CALL>
166
156
 
167
157
  严格规则:
168
- ‼️ 只使用下面列出的工具
169
- ‼️ 工具调用是可选的 - 需要时询问用户
170
- ‼️ 每次只能调用一个工具
171
- ‼️ 工具调用必须是有效的YAML格式
172
- ‼️ 参数必须正确缩进
173
- ‼️ 使用YAML块样式(|)表示多行值
174
- ‼️ 工具由用户手动执行
175
- ‼️ 等待用户提供工具执行结果
176
- ‼️ 不要假设或想象用户回应
177
- ‼️ 没有用户输入时不要继续对话
178
- ‼️ 不要创建虚假对话
179
- ‼️ 每个动作后停止
180
- ‼️ 不要假设结果
181
- ‼️ 不要假设行动
182
-
183
- 注意事项:
184
- - 先思考再行动
185
- - 需要时询问用户
186
- - 只使用列出的工具
187
- - 一次一个工具
188
- - 严格遵循YAML格式
189
- - 等待用户回应
190
- - 工具结果来自用户
191
- - 不要假设回应
192
- - 不要虚构对话
193
- - 每个动作后停止
194
- - 只在有实际用户输入时继续
158
+ 1. 每次只能执行一个工具
159
+ 2. 等待用户提供执行结果
160
+ 3. 不要假设或想象结果
161
+ 4. 不要创建虚假对话
162
+ 5. 每个动作后停止等待
195
163
 
196
164
  任务:
197
165
  {user_input}
@@ -6,6 +6,9 @@ import yaml
6
6
  import os
7
7
  import sys
8
8
  from pathlib import Path
9
+ from prompt_toolkit import prompt
10
+ from prompt_toolkit.completion import WordCompleter
11
+ from prompt_toolkit.validation import Validator, ValidationError
9
12
 
10
13
  # 添加父目录到Python路径以支持导入
11
14
  sys.path.insert(0, str(Path(__file__).parent.parent))
@@ -55,6 +58,19 @@ def load_tasks() -> dict:
55
58
 
56
59
  return tasks
57
60
 
61
+ class NumberValidator(Validator):
62
+ def validate(self, document):
63
+ text = document.text.strip()
64
+ if not text: # Allow empty input
65
+ return
66
+
67
+ try:
68
+ number = int(text)
69
+ if number < 0:
70
+ raise ValidationError(message='Please enter a non-negative number')
71
+ except ValueError:
72
+ raise ValidationError(message='Please enter a valid number')
73
+
58
74
  def select_task(tasks: dict) -> str:
59
75
  """Let user select a task from the list or skip. Returns task description if selected."""
60
76
  if not tasks:
@@ -68,9 +84,20 @@ def select_task(tasks: dict) -> str:
68
84
  PrettyOutput.print(f"[{i}] {name}", OutputType.INFO)
69
85
  PrettyOutput.print("[0] Skip predefined tasks", OutputType.INFO)
70
86
 
87
+ # Create completer with valid numbers
88
+ valid_numbers = [str(i) for i in range(len(task_names) + 1)]
89
+ number_completer = WordCompleter(valid_numbers)
90
+
71
91
  while True:
72
92
  try:
73
- choice = input("\nSelect a task number (0 to skip): ").strip()
93
+ choice = prompt(
94
+ "\nSelect a task number (0 to skip): ",
95
+ completer=number_completer,
96
+ validator=NumberValidator(),
97
+ validate_while_typing=False,
98
+ enable_history_search=True,
99
+ ).strip()
100
+
74
101
  if not choice:
75
102
  return ""
76
103
 
@@ -81,9 +108,12 @@ def select_task(tasks: dict) -> str:
81
108
  selected_name = task_names[choice - 1]
82
109
  return tasks[selected_name] # Return the task description
83
110
  else:
84
- PrettyOutput.print("Invalid choice. Please try again.", OutputType.ERROR)
85
- except ValueError:
86
- PrettyOutput.print("Please enter a valid number.", OutputType.ERROR)
111
+ PrettyOutput.print("Invalid choice. Please select a number from the list.", OutputType.ERROR)
112
+
113
+ except KeyboardInterrupt:
114
+ return "" # Return empty on Ctrl+C
115
+ except EOFError:
116
+ return "" # Return empty on Ctrl+D
87
117
 
88
118
  def main():
89
119
  """Main entry point for Jarvis."""
@@ -121,7 +151,7 @@ def main():
121
151
 
122
152
  model = KimiModel(kimi_api_key)
123
153
 
124
- tool_registry = ToolRegistry(model)
154
+ tool_registry = ToolRegistry()
125
155
  agent = Agent(model, tool_registry)
126
156
 
127
157
  # 欢迎信息
@@ -1,10 +1,12 @@
1
1
  from .base import Tool, ToolRegistry
2
2
  from .file_ops import FileOperationTool
3
3
  from .shell import ShellTool
4
+ from .generator import ToolGeneratorTool
4
5
 
5
6
  __all__ = [
6
7
  'Tool',
7
8
  'ToolRegistry',
8
9
  'FileOperationTool',
9
10
  'ShellTool',
11
+ 'ToolGeneratorTool',
10
12
  ]