jarvis-ai-assistant 0.1.89__py3-none-any.whl → 0.1.91__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.
Potentially problematic release.
This version of jarvis-ai-assistant might be problematic. Click here for more details.
- jarvis/__init__.py +1 -1
- jarvis/agent.py +3 -3
- jarvis/jarvis_codebase/main.py +3 -2
- jarvis/jarvis_platform/main.py +121 -0
- jarvis/jarvis_rag/main.py +42 -14
- jarvis/jarvis_smart_shell/main.py +0 -6
- jarvis/models/ai8.py +36 -44
- jarvis/models/base.py +10 -1
- jarvis/models/kimi.py +7 -2
- jarvis/models/ollama.py +7 -12
- jarvis/models/openai.py +12 -3
- jarvis/models/oyi.py +15 -21
- jarvis/models/registry.py +12 -1
- jarvis/tools/ask_user.py +4 -14
- jarvis/tools/codebase_qa.py +1 -1
- jarvis/tools/rag.py +134 -0
- jarvis/tools/thinker.py +203 -0
- jarvis/utils.py +3 -5
- {jarvis_ai_assistant-0.1.89.dist-info → jarvis_ai_assistant-0.1.91.dist-info}/METADATA +4 -7
- jarvis_ai_assistant-0.1.91.dist-info/RECORD +41 -0
- {jarvis_ai_assistant-0.1.89.dist-info → jarvis_ai_assistant-0.1.91.dist-info}/entry_points.txt +1 -1
- jarvis/jarvis_coder/git_utils.py +0 -67
- jarvis/jarvis_coder/main.py +0 -358
- jarvis/jarvis_coder/model_utils.py +0 -30
- jarvis/jarvis_coder/patch_handler.py +0 -390
- jarvis/tools/coder.py +0 -69
- jarvis_ai_assistant-0.1.89.dist-info/RECORD +0 -43
- /jarvis/{jarvis_coder → jarvis_platform}/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.89.dist-info → jarvis_ai_assistant-0.1.91.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.89.dist-info → jarvis_ai_assistant-0.1.91.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.89.dist-info → jarvis_ai_assistant-0.1.91.dist-info}/top_level.txt +0 -0
jarvis/models/registry.py
CHANGED
|
@@ -11,7 +11,11 @@ REQUIRED_METHODS = [
|
|
|
11
11
|
('name', []),
|
|
12
12
|
('delete_chat', []),
|
|
13
13
|
('reset', []),
|
|
14
|
-
('set_system_message', ['message'])
|
|
14
|
+
('set_system_message', ['message']),
|
|
15
|
+
('set_model_name', ['model_name']),
|
|
16
|
+
('get_model_list', []),
|
|
17
|
+
('set_suppress_output', ['suppress']),
|
|
18
|
+
('upload_files', ['file_list'])
|
|
15
19
|
]
|
|
16
20
|
|
|
17
21
|
class PlatformRegistry:
|
|
@@ -174,6 +178,13 @@ class PlatformRegistry:
|
|
|
174
178
|
platform = self.create_platform(platform_name)
|
|
175
179
|
platform.set_model_name(model_name)
|
|
176
180
|
return platform
|
|
181
|
+
|
|
182
|
+
def get_thinking_platform(self) -> BasePlatform:
|
|
183
|
+
platform_name = os.environ.get("JARVIS_THINKING_PLATFORM", os.environ.get("JARVIS_PLATFORM", "kimi"))
|
|
184
|
+
model_name = os.environ.get("JARVIS_THINKING_MODEL", os.environ.get("JARVIS_MODEL", "kimi"))
|
|
185
|
+
platform = self.create_platform(platform_name)
|
|
186
|
+
platform.set_model_name(model_name)
|
|
187
|
+
return platform
|
|
177
188
|
|
|
178
189
|
def register_platform(self, name: str, platform_class: Type[BasePlatform]):
|
|
179
190
|
"""注册平台类
|
jarvis/tools/ask_user.py
CHANGED
|
@@ -3,18 +3,8 @@ from jarvis.tools.base import Tool
|
|
|
3
3
|
from jarvis.utils import get_multiline_input, PrettyOutput, OutputType
|
|
4
4
|
|
|
5
5
|
class AskUserTool:
|
|
6
|
-
name="ask_user"
|
|
7
|
-
description="""
|
|
8
|
-
用户可以输入多行文本,空行结束输入。
|
|
9
|
-
|
|
10
|
-
使用场景:
|
|
11
|
-
1. 需要用户提供更多信息来完成任务
|
|
12
|
-
2. 需要用户做出关键决策
|
|
13
|
-
3. 需要用户确认某些重要操作
|
|
14
|
-
4. 需要用户提供额外信息
|
|
15
|
-
|
|
16
|
-
参数说明:
|
|
17
|
-
- question: 要询问用户的问题,应该清晰明确""",
|
|
6
|
+
name="ask_user"
|
|
7
|
+
description="""当缺少完成任务的信息或有关键决策信息缺失时,询问用户。用户可以输入多行文本,空行结束输入。使用场景:1. 需要用户提供更多信息来完成任务;2. 需要用户做出关键决策;3. 需要用户确认某些重要操作;4. 需要用户提供额外信息"""
|
|
18
8
|
parameters={
|
|
19
9
|
"type": "object",
|
|
20
10
|
"properties": {
|
|
@@ -40,8 +30,8 @@ class AskUserTool:
|
|
|
40
30
|
question = args["question"]
|
|
41
31
|
|
|
42
32
|
# 显示问题
|
|
43
|
-
PrettyOutput.print("\n问题:", OutputType.
|
|
44
|
-
PrettyOutput.print(question, OutputType.
|
|
33
|
+
PrettyOutput.print("\n问题:", OutputType.SYSTEM)
|
|
34
|
+
PrettyOutput.print(question, OutputType.SYSTEM)
|
|
45
35
|
|
|
46
36
|
# 获取用户输入
|
|
47
37
|
PrettyOutput.print("\n请输入您的回答(输入空行结束):", OutputType.INPUT)
|
jarvis/tools/codebase_qa.py
CHANGED
jarvis/tools/rag.py
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
from typing import Dict, Any
|
|
2
|
+
import os
|
|
3
|
+
from jarvis.utils import OutputType, PrettyOutput
|
|
4
|
+
from jarvis.jarvis_rag.main import RAGTool as RAGCore
|
|
5
|
+
|
|
6
|
+
class RAGTool:
|
|
7
|
+
name = "rag"
|
|
8
|
+
description = "基于文档目录进行问答,支持多种文档格式(txt、pdf、docx等)"
|
|
9
|
+
parameters = {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"dir": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "文档目录路径,支持相对路径和绝对路径"
|
|
15
|
+
},
|
|
16
|
+
"question": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "要询问的问题"
|
|
19
|
+
},
|
|
20
|
+
"rebuild_index": {
|
|
21
|
+
"type": "boolean",
|
|
22
|
+
"description": "是否重建索引",
|
|
23
|
+
"default": False
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"required": ["dir", "question"]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
def __init__(self):
|
|
30
|
+
"""初始化 RAG 工具"""
|
|
31
|
+
self.rag_instances = {} # 缓存不同目录的 RAG 实例
|
|
32
|
+
|
|
33
|
+
def _get_rag_instance(self, dir_path: str) -> RAGCore:
|
|
34
|
+
"""获取或创建 RAG 实例
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
dir_path: 文档目录的绝对路径
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
RAGCore: RAG 实例
|
|
41
|
+
"""
|
|
42
|
+
if dir_path not in self.rag_instances:
|
|
43
|
+
self.rag_instances[dir_path] = RAGCore(dir_path)
|
|
44
|
+
return self.rag_instances[dir_path]
|
|
45
|
+
|
|
46
|
+
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
47
|
+
"""执行文档问答
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
args: 包含参数的字典
|
|
51
|
+
- dir: 文档目录路径
|
|
52
|
+
- question: 要询问的问题
|
|
53
|
+
- rebuild_index: 是否重建索引
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
Dict[str, Any]: 执行结果
|
|
57
|
+
"""
|
|
58
|
+
try:
|
|
59
|
+
# 获取参数
|
|
60
|
+
dir_path = os.path.expanduser(args["dir"]) # 展开 ~ 等路径
|
|
61
|
+
dir_path = os.path.abspath(dir_path) # 转换为绝对路径
|
|
62
|
+
question = args["question"]
|
|
63
|
+
rebuild_index = args.get("rebuild_index", False)
|
|
64
|
+
|
|
65
|
+
# 检查目录是否存在
|
|
66
|
+
if not os.path.exists(dir_path):
|
|
67
|
+
return {
|
|
68
|
+
"success": False,
|
|
69
|
+
"error": f"目录不存在: {dir_path}"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# 检查是否是目录
|
|
73
|
+
if not os.path.isdir(dir_path):
|
|
74
|
+
return {
|
|
75
|
+
"success": False,
|
|
76
|
+
"error": f"路径不是目录: {dir_path}"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# 获取 RAG 实例
|
|
80
|
+
rag = self._get_rag_instance(dir_path)
|
|
81
|
+
|
|
82
|
+
# 如果需要重建索引或索引不存在
|
|
83
|
+
if rebuild_index or not rag.is_index_built():
|
|
84
|
+
PrettyOutput.print("正在构建文档索引...", OutputType.INFO)
|
|
85
|
+
rag.build_index(dir_path)
|
|
86
|
+
|
|
87
|
+
# 执行问答
|
|
88
|
+
PrettyOutput.print(f"问题: {question}", OutputType.INFO)
|
|
89
|
+
response = rag.ask(question)
|
|
90
|
+
|
|
91
|
+
if response is None:
|
|
92
|
+
return {
|
|
93
|
+
"success": False,
|
|
94
|
+
"error": "未能获取答案,可能是没有找到相关文档"
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
"success": True,
|
|
99
|
+
"stdout": response,
|
|
100
|
+
"stderr": ""
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
except Exception as e:
|
|
104
|
+
PrettyOutput.print(f"文档问答失败: {str(e)}", OutputType.ERROR)
|
|
105
|
+
return {
|
|
106
|
+
"success": False,
|
|
107
|
+
"error": f"执行失败: {str(e)}"
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
def main():
|
|
111
|
+
"""命令行直接运行工具"""
|
|
112
|
+
import argparse
|
|
113
|
+
|
|
114
|
+
parser = argparse.ArgumentParser(description='文档问答工具')
|
|
115
|
+
parser.add_argument('--dir', required=True, help='文档目录路径')
|
|
116
|
+
parser.add_argument('--question', required=True, help='要询问的问题')
|
|
117
|
+
parser.add_argument('--rebuild', action='store_true', help='重建索引')
|
|
118
|
+
args = parser.parse_args()
|
|
119
|
+
|
|
120
|
+
tool = RAGTool()
|
|
121
|
+
result = tool.execute({
|
|
122
|
+
"dir": args.dir,
|
|
123
|
+
"question": args.question,
|
|
124
|
+
"rebuild_index": args.rebuild
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
if result["success"]:
|
|
128
|
+
PrettyOutput.print("\n回答:", OutputType.INFO)
|
|
129
|
+
PrettyOutput.print(result["stdout"], OutputType.INFO)
|
|
130
|
+
else:
|
|
131
|
+
PrettyOutput.print(result["error"], OutputType.ERROR)
|
|
132
|
+
|
|
133
|
+
if __name__ == "__main__":
|
|
134
|
+
main()
|
jarvis/tools/thinker.py
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
from typing import Dict, Any
|
|
2
|
+
from jarvis.utils import OutputType, PrettyOutput, load_env_from_file
|
|
3
|
+
from jarvis.models.registry import PlatformRegistry
|
|
4
|
+
|
|
5
|
+
class ThinkerTool:
|
|
6
|
+
name = "thinker"
|
|
7
|
+
description = "使用思维链推理方式分析复杂问题,适用于需要多步推理、逻辑分析或创造性思考的场景"
|
|
8
|
+
parameters = {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"properties": {
|
|
11
|
+
"question": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "需要分析的问题或任务"
|
|
14
|
+
},
|
|
15
|
+
"context": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"description": "问题相关的上下文信息或背景知识",
|
|
18
|
+
"default": ""
|
|
19
|
+
},
|
|
20
|
+
"approach": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"enum": ["chain_of_thought", "tree_of_thought", "step_by_step"],
|
|
23
|
+
"description": "思考方式:chain_of_thought(思维链)、tree_of_thought(思维树)、step_by_step(步骤分解)",
|
|
24
|
+
"default": "chain_of_thought"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"required": ["question"]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
def __init__(self):
|
|
31
|
+
"""初始化思考工具"""
|
|
32
|
+
self.model = PlatformRegistry.get_global_platform_registry().get_thinking_platform()
|
|
33
|
+
|
|
34
|
+
def _generate_prompt(self, question: str, context: str, approach: str) -> str:
|
|
35
|
+
"""生成提示词
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
question: 问题
|
|
39
|
+
context: 上下文
|
|
40
|
+
approach: 思考方式
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
str: 完整的提示词
|
|
44
|
+
"""
|
|
45
|
+
# 基础提示词
|
|
46
|
+
base_prompt = "你是一个擅长深度思考和逻辑推理的助手。"
|
|
47
|
+
|
|
48
|
+
# 根据不同的思考方式添加具体指导
|
|
49
|
+
approach_prompts = {
|
|
50
|
+
"chain_of_thought": """请使用思维链方式分析问题:
|
|
51
|
+
1. 仔细阅读问题和上下文
|
|
52
|
+
2. 逐步推理,每一步都要说明推理依据
|
|
53
|
+
3. 考虑多个可能的角度
|
|
54
|
+
4. 得出最终结论
|
|
55
|
+
|
|
56
|
+
请按以下格式输出:
|
|
57
|
+
思考过程:
|
|
58
|
+
1. [第一步推理]
|
|
59
|
+
2. [第二步推理]
|
|
60
|
+
...
|
|
61
|
+
|
|
62
|
+
结论:
|
|
63
|
+
[最终结论]""",
|
|
64
|
+
|
|
65
|
+
"tree_of_thought": """请使用思维树方式分析问题:
|
|
66
|
+
1. 将问题分解为多个子问题
|
|
67
|
+
2. 对每个子问题进行分支探索
|
|
68
|
+
3. 评估每个分支的可行性
|
|
69
|
+
4. 整合最优路径
|
|
70
|
+
|
|
71
|
+
请按以下格式输出:
|
|
72
|
+
问题分解:
|
|
73
|
+
- 子问题1
|
|
74
|
+
- 分支1.1
|
|
75
|
+
- 分支1.2
|
|
76
|
+
- 子问题2
|
|
77
|
+
- 分支2.1
|
|
78
|
+
- 分支2.2
|
|
79
|
+
|
|
80
|
+
分析过程:
|
|
81
|
+
[详细分析每个分支]
|
|
82
|
+
|
|
83
|
+
最优路径:
|
|
84
|
+
[说明选择原因]
|
|
85
|
+
|
|
86
|
+
结论:
|
|
87
|
+
[最终结论]""",
|
|
88
|
+
|
|
89
|
+
"step_by_step": """请使用步骤分解方式分析问题:
|
|
90
|
+
1. 将问题分解为具体步骤
|
|
91
|
+
2. 详细说明每个步骤的执行方法
|
|
92
|
+
3. 考虑每个步骤可能的问题
|
|
93
|
+
4. 提供完整的解决方案
|
|
94
|
+
|
|
95
|
+
请按以下格式输出:
|
|
96
|
+
步骤分解:
|
|
97
|
+
步骤1: [具体内容]
|
|
98
|
+
步骤2: [具体内容]
|
|
99
|
+
...
|
|
100
|
+
|
|
101
|
+
执行分析:
|
|
102
|
+
[详细分析每个步骤]
|
|
103
|
+
|
|
104
|
+
解决方案:
|
|
105
|
+
[完整方案]"""
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# 构建完整提示词
|
|
109
|
+
prompt = f"""{base_prompt}
|
|
110
|
+
|
|
111
|
+
{approach_prompts[approach]}
|
|
112
|
+
|
|
113
|
+
问题:
|
|
114
|
+
{question}
|
|
115
|
+
|
|
116
|
+
"""
|
|
117
|
+
# 如果有上下文,添加到提示词中
|
|
118
|
+
if context:
|
|
119
|
+
prompt += f"""
|
|
120
|
+
相关上下文:
|
|
121
|
+
{context}
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
prompt += "\n请开始分析:"
|
|
125
|
+
return prompt
|
|
126
|
+
|
|
127
|
+
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
128
|
+
"""执行思考分析
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
args: 包含参数的字典
|
|
132
|
+
- question: 问题
|
|
133
|
+
- context: 上下文(可选)
|
|
134
|
+
- approach: 思考方式(可选)
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
Dict[str, Any]: 执行结果
|
|
138
|
+
"""
|
|
139
|
+
try:
|
|
140
|
+
# 获取参数
|
|
141
|
+
question = args["question"]
|
|
142
|
+
context = args.get("context", "")
|
|
143
|
+
approach = args.get("approach", "chain_of_thought")
|
|
144
|
+
|
|
145
|
+
# 生成提示词
|
|
146
|
+
prompt = self._generate_prompt(question, context, approach)
|
|
147
|
+
|
|
148
|
+
# 记录开始分析
|
|
149
|
+
PrettyOutput.print(f"开始分析问题: {question}", OutputType.INFO)
|
|
150
|
+
if context:
|
|
151
|
+
PrettyOutput.print("包含上下文信息", OutputType.INFO)
|
|
152
|
+
PrettyOutput.print(f"使用{approach}方式思考", OutputType.INFO)
|
|
153
|
+
|
|
154
|
+
# 调用模型进行分析
|
|
155
|
+
response = self.model.chat(prompt)
|
|
156
|
+
|
|
157
|
+
if not response:
|
|
158
|
+
return {
|
|
159
|
+
"success": False,
|
|
160
|
+
"error": "未能获得有效的分析结果"
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
"success": True,
|
|
165
|
+
"stdout": response,
|
|
166
|
+
"stderr": ""
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
except Exception as e:
|
|
170
|
+
PrettyOutput.print(f"思考分析失败: {str(e)}", OutputType.ERROR)
|
|
171
|
+
return {
|
|
172
|
+
"success": False,
|
|
173
|
+
"error": f"执行失败: {str(e)}"
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
def main():
|
|
177
|
+
"""命令行直接运行工具"""
|
|
178
|
+
import argparse
|
|
179
|
+
|
|
180
|
+
load_env_from_file()
|
|
181
|
+
|
|
182
|
+
parser = argparse.ArgumentParser(description='深度思考分析工具')
|
|
183
|
+
parser.add_argument('--question', required=True, help='需要分析的问题')
|
|
184
|
+
parser.add_argument('--context', help='问题相关的上下文信息')
|
|
185
|
+
parser.add_argument('--approach', choices=['chain_of_thought', 'tree_of_thought', 'step_by_step'],
|
|
186
|
+
default='chain_of_thought', help='思考方式')
|
|
187
|
+
args = parser.parse_args()
|
|
188
|
+
|
|
189
|
+
tool = ThinkerTool()
|
|
190
|
+
result = tool.execute({
|
|
191
|
+
"question": args.question,
|
|
192
|
+
"context": args.context,
|
|
193
|
+
"approach": args.approach
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
if result["success"]:
|
|
197
|
+
PrettyOutput.print("\n分析结果:", OutputType.INFO)
|
|
198
|
+
PrettyOutput.print(result["stdout"], OutputType.INFO)
|
|
199
|
+
else:
|
|
200
|
+
PrettyOutput.print(result["error"], OutputType.ERROR)
|
|
201
|
+
|
|
202
|
+
if __name__ == "__main__":
|
|
203
|
+
main()
|
jarvis/utils.py
CHANGED
|
@@ -97,7 +97,7 @@ class PrettyOutput:
|
|
|
97
97
|
return formatted_text
|
|
98
98
|
|
|
99
99
|
@staticmethod
|
|
100
|
-
def print(text: str, output_type: OutputType, timestamp: bool =
|
|
100
|
+
def print(text: str, output_type: OutputType, timestamp: bool = True):
|
|
101
101
|
"""打印格式化的输出"""
|
|
102
102
|
print(PrettyOutput.format(text, output_type, timestamp))
|
|
103
103
|
if output_type == OutputType.ERROR:
|
|
@@ -110,7 +110,7 @@ class PrettyOutput:
|
|
|
110
110
|
width = 60
|
|
111
111
|
color = PrettyOutput.COLORS.get(output_type, "")
|
|
112
112
|
print(f"\n{color}" + "=" * width + f"{ColoramaStyle.RESET_ALL}")
|
|
113
|
-
PrettyOutput.print(title.center(width - 10), output_type, timestamp=
|
|
113
|
+
PrettyOutput.print(title.center(width - 10), output_type, timestamp=True)
|
|
114
114
|
print(f"{color}" + "=" * width + f"{ColoramaStyle.RESET_ALL}\n")
|
|
115
115
|
|
|
116
116
|
@staticmethod
|
|
@@ -128,7 +128,7 @@ class PrettyOutput:
|
|
|
128
128
|
|
|
129
129
|
def get_multiline_input(tip: str) -> str:
|
|
130
130
|
"""获取多行输入,支持方向键、历史记录等功能"""
|
|
131
|
-
|
|
131
|
+
print(f"{Fore.GREEN}{tip}{ColoramaStyle.RESET_ALL}")
|
|
132
132
|
|
|
133
133
|
# 创建输入会话,启用历史记录
|
|
134
134
|
session = PromptSession(history=None) # 使用默认历史记录
|
|
@@ -219,7 +219,6 @@ def load_embedding_model():
|
|
|
219
219
|
# 首先尝试离线加载
|
|
220
220
|
embedding_model = SentenceTransformer(
|
|
221
221
|
model_name,
|
|
222
|
-
device="cpu",
|
|
223
222
|
cache_folder=os.path.expanduser("~/.cache/huggingface/hub"),
|
|
224
223
|
local_files_only=True
|
|
225
224
|
)
|
|
@@ -229,7 +228,6 @@ def load_embedding_model():
|
|
|
229
228
|
# 如果离线加载失败,尝试在线下载
|
|
230
229
|
embedding_model = SentenceTransformer(
|
|
231
230
|
model_name,
|
|
232
|
-
device="cpu",
|
|
233
231
|
cache_folder=os.path.expanduser("~/.cache/huggingface/hub")
|
|
234
232
|
)
|
|
235
233
|
PrettyOutput.print("模型下载并加载成功", OutputType.SUCCESS)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: jarvis-ai-assistant
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.91
|
|
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
|
|
@@ -129,11 +129,13 @@ Jarvis supports configuration through environment variables that can be set in t
|
|
|
129
129
|
|---------|------|--------|------|
|
|
130
130
|
| JARVIS_PLATFORM | AI platform to use, supports kimi/openai/ai8 etc | kimi | Yes |
|
|
131
131
|
| JARVIS_MODEL | Model name to use | - | No |
|
|
132
|
-
| JARVIS_THREAD_COUNT | Number of threads for parallel processing | 10 | No |
|
|
133
132
|
| JARVIS_CODEGEN_PLATFORM | AI platform for code generation | Same as JARVIS_PLATFORM | No |
|
|
134
133
|
| JARVIS_CODEGEN_MODEL | Model name for code generation | Same as JARVIS_MODEL | No |
|
|
135
134
|
| JARVIS_CHEAP_PLATFORM | AI platform for cheap operations | Same as JARVIS_PLATFORM | No |
|
|
136
135
|
| JARVIS_CHEAP_MODEL | Model name for cheap operations | Same as JARVIS_MODEL | No |
|
|
136
|
+
| JARVIS_THINKING_PLATFORM | AI platform for thinking | Same as JARVIS_PLATFORM | No |
|
|
137
|
+
| JARVIS_THINKING_MODEL | Model name for thinking | Same as JARVIS_MODEL | No |
|
|
138
|
+
| JARVIS_THREAD_COUNT | Number of threads for parallel processing | 10 | No |
|
|
137
139
|
| OPENAI_API_KEY | API key for OpenAI platform | - | Required for OpenAI |
|
|
138
140
|
| OPENAI_API_BASE | Base URL for OpenAI API | https://api.deepseek.com | No |
|
|
139
141
|
| OPENAI_MODEL_NAME | Model name for OpenAI | deepseek-chat | No |
|
|
@@ -150,11 +152,6 @@ Jarvis supports configuration through environment variables that can be set in t
|
|
|
150
152
|
jarvis
|
|
151
153
|
```
|
|
152
154
|
|
|
153
|
-
### Code Generation
|
|
154
|
-
```bash
|
|
155
|
-
jarvis-coder
|
|
156
|
-
```
|
|
157
|
-
|
|
158
155
|
### Codebase Search
|
|
159
156
|
```bash
|
|
160
157
|
# Generate codebase index
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
jarvis/__init__.py,sha256=3Ab7ipGCmdagjBEJ81C-I_xiKdsal6hFcitNVQKYwt4,50
|
|
2
|
+
jarvis/agent.py,sha256=82F6n8YKOaLaHp40eljZLfV-Ad4RktB8s-1c8X8-LGU,19128
|
|
3
|
+
jarvis/main.py,sha256=72od8757A3bhe0ncE38S7u-YZsAh0y50w9ozMhgqIU8,5423
|
|
4
|
+
jarvis/utils.py,sha256=Maqu93-rixR-_rjvoBCocCH6XiB1ol1Xozj1eMjNjE0,10308
|
|
5
|
+
jarvis/jarvis_codebase/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
jarvis/jarvis_codebase/main.py,sha256=hbFYetHZOKSU0HBbKUU8Vu4o3m25nufvBnHGI8OxT6g,26503
|
|
7
|
+
jarvis/jarvis_platform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
jarvis/jarvis_platform/main.py,sha256=V-gJQdfHihtrZD6WIYbVAQSDmtrf0PFVndZ7jPrlGZg,4277
|
|
9
|
+
jarvis/jarvis_rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
jarvis/jarvis_rag/main.py,sha256=ZzNnU0KhAiz64kMmHd5BSBhImieXYbcfgRT-s-PiP2Y,26415
|
|
11
|
+
jarvis/jarvis_smart_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
jarvis/jarvis_smart_shell/main.py,sha256=4BKXMIz7zGATC_4K47UQxHh7sHPH4K2dqj4RSIH9t4Y,3552
|
|
13
|
+
jarvis/models/__init__.py,sha256=mrOt67nselz_H1gX9wdAO4y2DY5WPXzABqJbr5Des8k,63
|
|
14
|
+
jarvis/models/ai8.py,sha256=ejMUAf614wBgmsYPkcWrCzONBcIAP4pUTy4b9hrolJY,11830
|
|
15
|
+
jarvis/models/base.py,sha256=qIpO32lejPhaZk5T3VIua3td4gEguXMaeFER5kXYwLY,1782
|
|
16
|
+
jarvis/models/kimi.py,sha256=cB1tC_ifdTAZUEqndzNTIcgHWi4w4tM8zdzSOcDhOrQ,16348
|
|
17
|
+
jarvis/models/ollama.py,sha256=3Mb9ukwKk_HFfYp5dU0Zao5aa9AH_cTJoYhwHJt3MOo,5626
|
|
18
|
+
jarvis/models/openai.py,sha256=W1FmaNnFSxeu-4qFQcuop5xeb-zh8-x6E-D56hMaVuA,4370
|
|
19
|
+
jarvis/models/oyi.py,sha256=IWsrReLmphm-UMzxXcbAoiWP6w1fJRP3iQTlyDpSyg8,14491
|
|
20
|
+
jarvis/models/registry.py,sha256=SDnrNzf0wQi8mb7qbu4ZNfYIy5vhz1CxmVL3Ru-VATk,8797
|
|
21
|
+
jarvis/tools/__init__.py,sha256=7Rqyj5hBAv5cWDVr5T9ZTZASO7ssBHeQNm2_4ZARdkA,72
|
|
22
|
+
jarvis/tools/ask_user.py,sha256=KNRaiBlAqqAZ0uUkq_l7AKi-y9ZCLE83uLtTdd-UM0o,1919
|
|
23
|
+
jarvis/tools/base.py,sha256=EGRGbdfbLXDLwtyoWdvp9rlxNX7bzc20t0Vc2VkwIEY,652
|
|
24
|
+
jarvis/tools/chdir.py,sha256=TjfPbX8yvNKgUNJEMXh3ZlVDEIse_Fo8xMoVsiK7_dA,2688
|
|
25
|
+
jarvis/tools/codebase_qa.py,sha256=Lk8EXkin45RKUsp5C_UHm6jADBhyCT-xsYubwJ1hSiE,2403
|
|
26
|
+
jarvis/tools/file_ops.py,sha256=h8g0eT9UvlJf4kt0DLXvdSsjcPj7x19lxWdDApeDfpg,3842
|
|
27
|
+
jarvis/tools/generator.py,sha256=TB1zcw_JmRL2W9w6L4IxtrLF3gjnNw5Jj2Zrowj0eSg,5763
|
|
28
|
+
jarvis/tools/methodology.py,sha256=UG6s5VYRcd9wrKX4cg6f7zJhet5AIcthFGMOAdevBiw,5175
|
|
29
|
+
jarvis/tools/rag.py,sha256=tJzuhHaTrujVXCBgmyMqSynVF0UFsIJeRTG0Y_Tt964,4483
|
|
30
|
+
jarvis/tools/registry.py,sha256=AbADf8pcjHqfNoQNJkWqEuVg6zHRdryhJyDQ5w4O2sc,9177
|
|
31
|
+
jarvis/tools/search.py,sha256=c9dXtyICdl8Lm8shNPNyIx9k67uY0rMF8xnIKu2RsnE,8787
|
|
32
|
+
jarvis/tools/shell.py,sha256=UPKshPyOaUwTngresUw-ot1jHjQIb4wCY5nkJqa38lU,2520
|
|
33
|
+
jarvis/tools/sub_agent.py,sha256=rEtAmSVY2ZjFOZEKr5m5wpACOQIiM9Zr_3dT92FhXYU,2621
|
|
34
|
+
jarvis/tools/thinker.py,sha256=Zv1v4Mp7R08w5p3e2iv5X4UWQstgAMyRD9huE-b-ZS0,5938
|
|
35
|
+
jarvis/tools/webpage.py,sha256=d3w3Jcjcu1ESciezTkz3n3Zf-rp_l91PrVoDEZnckOo,2391
|
|
36
|
+
jarvis_ai_assistant-0.1.91.dist-info/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
|
37
|
+
jarvis_ai_assistant-0.1.91.dist-info/METADATA,sha256=ahfOtRplwS5KpK_gh3_YP2WzfbRsc3wi5D8GaSvAUps,12710
|
|
38
|
+
jarvis_ai_assistant-0.1.91.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
39
|
+
jarvis_ai_assistant-0.1.91.dist-info/entry_points.txt,sha256=47WUorU2y8wAKrGEVh5n6o3NaOB7A-4-PfSWp-xuFSg,286
|
|
40
|
+
jarvis_ai_assistant-0.1.91.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
|
41
|
+
jarvis_ai_assistant-0.1.91.dist-info/RECORD,,
|
{jarvis_ai_assistant-0.1.89.dist-info → jarvis_ai_assistant-0.1.91.dist-info}/entry_points.txt
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[console_scripts]
|
|
2
2
|
jarvis = jarvis.main:main
|
|
3
3
|
jarvis-codebase = jarvis.jarvis_codebase.main:main
|
|
4
|
-
jarvis-
|
|
4
|
+
jarvis-platform = jarvis.jarvis_platform.main:main
|
|
5
5
|
jarvis-rag = jarvis.jarvis_rag.main:main
|
|
6
6
|
jarvis-smart-shell = jarvis.jarvis_smart_shell.main:main
|
|
7
7
|
jss = jarvis.jarvis_smart_shell.main:main
|
jarvis/jarvis_coder/git_utils.py
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from typing import List
|
|
3
|
-
import yaml
|
|
4
|
-
import time
|
|
5
|
-
from jarvis.utils import OutputType, PrettyOutput
|
|
6
|
-
from jarvis.models.registry import PlatformRegistry
|
|
7
|
-
from .model_utils import call_model_with_retry
|
|
8
|
-
|
|
9
|
-
def has_uncommitted_files() -> bool:
|
|
10
|
-
"""判断代码库是否有未提交的文件"""
|
|
11
|
-
# 获取未暂存的修改
|
|
12
|
-
unstaged = os.popen("git diff --name-only").read()
|
|
13
|
-
# 获取已暂存但未提交的修改
|
|
14
|
-
staged = os.popen("git diff --cached --name-only").read()
|
|
15
|
-
# 获取未跟踪的文件
|
|
16
|
-
untracked = os.popen("git ls-files --others --exclude-standard").read()
|
|
17
|
-
|
|
18
|
-
return bool(unstaged or staged or untracked)
|
|
19
|
-
|
|
20
|
-
def generate_commit_message(git_diff: str, feature: str) -> str:
|
|
21
|
-
"""根据git diff和功能描述生成commit信息"""
|
|
22
|
-
prompt = f"""你是一个经验丰富的程序员,请根据以下代码变更和功能描述生成简洁明了的commit信息:
|
|
23
|
-
|
|
24
|
-
功能描述:
|
|
25
|
-
{feature}
|
|
26
|
-
|
|
27
|
-
代码变更:
|
|
28
|
-
Git Diff:
|
|
29
|
-
{git_diff}
|
|
30
|
-
|
|
31
|
-
请遵循以下规则:
|
|
32
|
-
1. 使用英文编写
|
|
33
|
-
2. 采用常规的commit message格式:<type>(<scope>): <subject>
|
|
34
|
-
3. 保持简洁,不超过50个字符
|
|
35
|
-
4. 准确描述代码变更的主要内容
|
|
36
|
-
5. 优先考虑功能描述和git diff中的变更内容
|
|
37
|
-
"""
|
|
38
|
-
|
|
39
|
-
model = PlatformRegistry().get_global_platform_registry().get_codegen_platform()
|
|
40
|
-
model.set_suppress_output(True)
|
|
41
|
-
success, response = call_model_with_retry(model, prompt)
|
|
42
|
-
if not success:
|
|
43
|
-
return "Update code changes"
|
|
44
|
-
|
|
45
|
-
return response.strip().split("\n")[0]
|
|
46
|
-
|
|
47
|
-
def save_edit_record(record_dir: str, commit_message: str, git_diff: str) -> None:
|
|
48
|
-
"""保存代码修改记录"""
|
|
49
|
-
# 获取下一个序号
|
|
50
|
-
existing_records = [f for f in os.listdir(record_dir) if f.endswith('.yaml')]
|
|
51
|
-
next_num = 1
|
|
52
|
-
if existing_records:
|
|
53
|
-
last_num = max(int(f[:4]) for f in existing_records)
|
|
54
|
-
next_num = last_num + 1
|
|
55
|
-
|
|
56
|
-
# 创建记录文件
|
|
57
|
-
record = {
|
|
58
|
-
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
|
|
59
|
-
"commit_message": commit_message,
|
|
60
|
-
"git_diff": git_diff
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
record_path = os.path.join(record_dir, f"{next_num:04d}.yaml")
|
|
64
|
-
with open(record_path, "w", encoding="utf-8") as f:
|
|
65
|
-
yaml.safe_dump(record, f, allow_unicode=True)
|
|
66
|
-
|
|
67
|
-
PrettyOutput.print(f"已保存修改记录: {record_path}", OutputType.SUCCESS)
|