jarvis-ai-assistant 0.2.4__py3-none-any.whl → 0.2.5__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.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +13 -7
- jarvis/jarvis_agent/edit_file_handler.py +1 -2
- jarvis/jarvis_code_agent/code_agent.py +7 -13
- jarvis/jarvis_data/config_schema.json +2 -19
- jarvis/jarvis_stats/cli.py +72 -5
- jarvis/jarvis_stats/stats.py +175 -70
- jarvis/jarvis_stats/storage.py +53 -1
- jarvis/jarvis_stats/visualizer.py +63 -224
- jarvis/jarvis_tools/cli/main.py +7 -9
- jarvis/jarvis_tools/registry.py +2 -5
- jarvis/jarvis_utils/config.py +6 -8
- jarvis/jarvis_utils/methodology.py +74 -67
- jarvis/jarvis_utils/utils.py +342 -119
- {jarvis_ai_assistant-0.2.4.dist-info → jarvis_ai_assistant-0.2.5.dist-info}/METADATA +11 -2
- {jarvis_ai_assistant-0.2.4.dist-info → jarvis_ai_assistant-0.2.5.dist-info}/RECORD +20 -20
- {jarvis_ai_assistant-0.2.4.dist-info → jarvis_ai_assistant-0.2.5.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.2.4.dist-info → jarvis_ai_assistant-0.2.5.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.2.4.dist-info → jarvis_ai_assistant-0.2.5.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.2.4.dist-info → jarvis_ai_assistant-0.2.5.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
jarvis/jarvis_agent/__init__.py
CHANGED
@@ -511,7 +511,7 @@ class Agent:
|
|
511
511
|
)
|
512
512
|
if user_input:
|
513
513
|
run_input_handlers = True
|
514
|
-
#
|
514
|
+
# 如果有工具调用且用户确认继续,则继续执行工具调用
|
515
515
|
if any(
|
516
516
|
handler.can_handle(current_response)
|
517
517
|
for handler in self.output_handler
|
@@ -519,13 +519,19 @@ class Agent:
|
|
519
519
|
if user_confirm(
|
520
520
|
"检测到有工具调用,是否继续处理工具调用?", True
|
521
521
|
):
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
522
|
+
# 先添加用户干预信息到session
|
523
|
+
self.session.prompt = f"被用户中断,用户补充信息为:{user_input}\n\n用户同意继续工具调用。"
|
524
|
+
# 继续执行下面的工具调用逻辑,不要continue跳过
|
525
|
+
else:
|
526
|
+
# 用户选择不继续处理工具调用
|
527
|
+
self.session.prompt = f"被用户中断,用户补充信息为:{user_input}\n\n检测到有工具调用,但被用户拒绝执行。请根据用户的补充信息重新考虑下一步操作。"
|
526
528
|
continue
|
527
|
-
|
528
|
-
|
529
|
+
else:
|
530
|
+
# 没有检测到工具调用
|
531
|
+
self.session.prompt = (
|
532
|
+
f"被用户中断,用户补充信息为:{user_input}"
|
533
|
+
)
|
534
|
+
continue
|
529
535
|
|
530
536
|
need_return, self.session.prompt = self._call_tools(
|
531
537
|
current_response
|
@@ -58,8 +58,7 @@ class EditFileHandler(OutputHandler):
|
|
58
58
|
|
59
59
|
# 记录 edit_file 工具调用统计
|
60
60
|
from jarvis.jarvis_stats.stats import StatsManager
|
61
|
-
|
62
|
-
stats_manager.increment("edit_file", group="tool")
|
61
|
+
StatsManager.increment("edit_file", group="tool")
|
63
62
|
|
64
63
|
results = []
|
65
64
|
|
@@ -348,13 +348,11 @@ class CodeAgent:
|
|
348
348
|
from jarvis.jarvis_stats.stats import StatsManager
|
349
349
|
import re
|
350
350
|
|
351
|
-
stats_manager = StatsManager()
|
352
|
-
|
353
351
|
# 匹配插入行数
|
354
352
|
insertions_match = re.search(r"(\d+)\s+insertions?\(\+\)", diff_text)
|
355
353
|
if insertions_match:
|
356
354
|
insertions = int(insertions_match.group(1))
|
357
|
-
|
355
|
+
StatsManager.increment(
|
358
356
|
"code_lines_inserted", amount=insertions, group="code_agent"
|
359
357
|
)
|
360
358
|
|
@@ -362,7 +360,7 @@ class CodeAgent:
|
|
362
360
|
deletions_match = re.search(r"(\d+)\s+deletions?\(\-\)", diff_text)
|
363
361
|
if deletions_match:
|
364
362
|
deletions = int(deletions_match.group(1))
|
365
|
-
|
363
|
+
StatsManager.increment(
|
366
364
|
"code_lines_deleted", amount=deletions, group="code_agent"
|
367
365
|
)
|
368
366
|
|
@@ -397,8 +395,7 @@ class CodeAgent:
|
|
397
395
|
# 用户确认修改,统计修改次数
|
398
396
|
from jarvis.jarvis_stats.stats import StatsManager
|
399
397
|
|
400
|
-
|
401
|
-
stats_manager.increment("code_modification_confirmed", group="code_agent")
|
398
|
+
StatsManager.increment("code_modification_confirmed", group="code_agent")
|
402
399
|
|
403
400
|
try:
|
404
401
|
confirm_add_new_files()
|
@@ -430,7 +427,7 @@ class CodeAgent:
|
|
430
427
|
)
|
431
428
|
|
432
429
|
# 统计提交次数
|
433
|
-
|
430
|
+
StatsManager.increment("code_commits_accepted", group="code_agent")
|
434
431
|
except subprocess.CalledProcessError as e:
|
435
432
|
PrettyOutput.print(f"提交失败: {str(e)}", OutputType.ERROR)
|
436
433
|
|
@@ -455,8 +452,7 @@ class CodeAgent:
|
|
455
452
|
# 统计生成的commit数量
|
456
453
|
from jarvis.jarvis_stats.stats import StatsManager
|
457
454
|
|
458
|
-
|
459
|
-
stats_manager.increment("commits_generated", group="code_agent")
|
455
|
+
StatsManager.increment("commits_generated", group="code_agent")
|
460
456
|
|
461
457
|
commit_messages = "检测到以下提交记录:\n" + "\n".join(
|
462
458
|
f"- {commit_hash[:7]}: {message}" for commit_hash, message in commits
|
@@ -472,8 +468,7 @@ class CodeAgent:
|
|
472
468
|
# 统计接受的commit数量
|
473
469
|
from jarvis.jarvis_stats.stats import StatsManager
|
474
470
|
|
475
|
-
|
476
|
-
stats_manager.increment("commits_accepted", group="code_agent")
|
471
|
+
StatsManager.increment("commits_accepted", group="code_agent")
|
477
472
|
|
478
473
|
subprocess.run(
|
479
474
|
["git", "reset", "--mixed", str(start_commit)],
|
@@ -581,8 +576,7 @@ class CodeAgent:
|
|
581
576
|
# 统计修改次数
|
582
577
|
from jarvis.jarvis_stats.stats import StatsManager
|
583
578
|
|
584
|
-
|
585
|
-
stats_manager.increment("code_modifications", group="code_agent")
|
579
|
+
StatsManager.increment("code_modifications", group="code_agent")
|
586
580
|
|
587
581
|
# 获取提交信息
|
588
582
|
end_hash = get_latest_commit_hash()
|
@@ -111,14 +111,9 @@
|
|
111
111
|
"description": "Git提交信息生成提示模板",
|
112
112
|
"default": ""
|
113
113
|
},
|
114
|
-
"JARVIS_MAX_TOKEN_COUNT": {
|
115
|
-
"type": "number",
|
116
|
-
"description": "模型能处理的最大token数量",
|
117
|
-
"default": 960000
|
118
|
-
},
|
119
114
|
"JARVIS_MAX_INPUT_TOKEN_COUNT": {
|
120
115
|
"type": "number",
|
121
|
-
"description": "模型能处理的最大输入token
|
116
|
+
"description": "模型能处理的最大输入token数量。其他token限制基于此值计算:最大token数量=此值×100,最大大内容尺寸=此值×5",
|
122
117
|
"default": 32000
|
123
118
|
},
|
124
119
|
"JARVIS_PLATFORM": {
|
@@ -171,17 +166,9 @@
|
|
171
166
|
"type": "string",
|
172
167
|
"default": "deep_seek_v3"
|
173
168
|
},
|
174
|
-
"JARVIS_MAX_TOKEN_COUNT": {
|
175
|
-
"type": "number",
|
176
|
-
"default": 960000
|
177
|
-
},
|
178
169
|
"JARVIS_MAX_INPUT_TOKEN_COUNT": {
|
179
170
|
"type": "number",
|
180
171
|
"default": 32000
|
181
|
-
},
|
182
|
-
"JARVIS_MAX_BIG_CONTENT_SIZE": {
|
183
|
-
"type": "number",
|
184
|
-
"default": 160000
|
185
172
|
}
|
186
173
|
},
|
187
174
|
"required": [
|
@@ -206,11 +193,7 @@
|
|
206
193
|
"description": "Jarvis数据存储目录路径",
|
207
194
|
"default": "~/.jarvis"
|
208
195
|
},
|
209
|
-
|
210
|
-
"type": "number",
|
211
|
-
"description": "最大大内容尺寸",
|
212
|
-
"default": 160000
|
213
|
-
},
|
196
|
+
|
214
197
|
"JARVIS_PRETTY_OUTPUT": {
|
215
198
|
"type": "boolean",
|
216
199
|
"description": "是否启用美化输出",
|
jarvis/jarvis_stats/cli.py
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
使用 typer 提供友好的命令行交互
|
5
5
|
"""
|
6
6
|
|
7
|
+
import builtins
|
7
8
|
from datetime import datetime, timedelta
|
8
9
|
from typing import Optional, List
|
9
10
|
import typer
|
@@ -183,13 +184,14 @@ def list():
|
|
183
184
|
table.add_column("单位", style="green")
|
184
185
|
table.add_column("最后更新", style="yellow")
|
185
186
|
table.add_column("7天数据点", style="magenta")
|
187
|
+
table.add_column("标签", style="blue")
|
186
188
|
|
187
189
|
# 获取每个指标的信息
|
188
190
|
end_time = datetime.now()
|
189
191
|
start_time = end_time - timedelta(days=7)
|
190
192
|
|
191
193
|
for metric in metrics:
|
192
|
-
info = stats.
|
194
|
+
info = stats._get_storage().get_metric_info(metric)
|
193
195
|
if info:
|
194
196
|
unit = info.get("unit", "-")
|
195
197
|
last_updated = info.get("last_updated", "-")
|
@@ -202,11 +204,36 @@ def list():
|
|
202
204
|
except:
|
203
205
|
pass
|
204
206
|
|
205
|
-
#
|
206
|
-
records = stats.
|
207
|
+
# 获取数据点数和标签
|
208
|
+
records = stats._get_storage().get_metrics(metric, start_time, end_time)
|
207
209
|
count = len(records)
|
208
|
-
|
209
|
-
|
210
|
+
|
211
|
+
# 收集所有唯一的标签
|
212
|
+
all_tags = {}
|
213
|
+
for record in records:
|
214
|
+
tags = record.get("tags", {})
|
215
|
+
for k, v in tags.items():
|
216
|
+
if k not in all_tags:
|
217
|
+
all_tags[k] = set()
|
218
|
+
all_tags[k].add(v)
|
219
|
+
|
220
|
+
# 格式化标签显示
|
221
|
+
tag_str = ""
|
222
|
+
if all_tags:
|
223
|
+
tag_parts = []
|
224
|
+
for k, values in sorted(all_tags.items()):
|
225
|
+
# 使用内置的list函数
|
226
|
+
values_list = sorted(builtins.list(values))
|
227
|
+
if len(values_list) == 1:
|
228
|
+
tag_parts.append(f"{k}={values_list[0]}")
|
229
|
+
else:
|
230
|
+
# 转义方括号以避免Rich markup错误
|
231
|
+
tag_parts.append(f"{k}=\\[{', '.join(values_list)}\\]")
|
232
|
+
tag_str = ", ".join(tag_parts)
|
233
|
+
else:
|
234
|
+
tag_str = "-"
|
235
|
+
|
236
|
+
table.add_row(metric, unit, last_updated, str(count), tag_str)
|
210
237
|
|
211
238
|
console.print(table)
|
212
239
|
rprint(f"\n[green]总计: {len(metrics)} 个指标[/green]")
|
@@ -278,6 +305,46 @@ def export(
|
|
278
305
|
rprint("[yellow]没有找到数据[/yellow]", file=sys.stderr)
|
279
306
|
|
280
307
|
|
308
|
+
@app.command()
|
309
|
+
def remove(
|
310
|
+
metric: str = typer.Argument(..., help="要删除的指标名称"),
|
311
|
+
yes: bool = typer.Option(False, "--yes", "-y", help="跳过确认"),
|
312
|
+
):
|
313
|
+
"""删除指定的指标及其所有数据"""
|
314
|
+
if not yes:
|
315
|
+
# 显示指标信息供用户确认
|
316
|
+
stats = StatsManager(_get_stats_dir())
|
317
|
+
metrics = stats.list_metrics()
|
318
|
+
|
319
|
+
if metric not in metrics:
|
320
|
+
rprint(f"[red]错误:指标 '{metric}' 不存在[/red]")
|
321
|
+
return
|
322
|
+
|
323
|
+
# 获取指标的基本信息
|
324
|
+
info = stats._get_storage().get_metric_info(metric)
|
325
|
+
if info:
|
326
|
+
unit = info.get("unit", "-")
|
327
|
+
last_updated = info.get("last_updated", "-")
|
328
|
+
|
329
|
+
rprint(f"\n[yellow]准备删除指标:[/yellow]")
|
330
|
+
rprint(f" 名称: {metric}")
|
331
|
+
rprint(f" 单位: {unit}")
|
332
|
+
rprint(f" 最后更新: {last_updated}")
|
333
|
+
|
334
|
+
confirm = typer.confirm(f"\n确定要删除指标 '{metric}' 及其所有数据吗?")
|
335
|
+
if not confirm:
|
336
|
+
rprint("[yellow]已取消操作[/yellow]")
|
337
|
+
return
|
338
|
+
|
339
|
+
stats = StatsManager(_get_stats_dir())
|
340
|
+
success = stats.remove_metric(metric)
|
341
|
+
|
342
|
+
if success:
|
343
|
+
rprint(f"[green]✓[/green] 已成功删除指标: {metric}")
|
344
|
+
else:
|
345
|
+
rprint(f"[red]✗[/red] 删除失败:指标 '{metric}' 不存在")
|
346
|
+
|
347
|
+
|
281
348
|
@app.command()
|
282
349
|
def demo():
|
283
350
|
"""运行演示,展示统计模块的功能"""
|