jarvis-ai-assistant 0.3.14__py3-none-any.whl → 0.3.15__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 CHANGED
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """Jarvis AI Assistant"""
3
3
 
4
- __version__ = "0.3.14"
4
+ __version__ = "0.3.15"
@@ -233,18 +233,21 @@ class CodeAgent:
233
233
  else:
234
234
  print("ℹ️ .jarvis已在.gitignore中")
235
235
 
236
- def _handle_git_changes(self) -> None:
236
+ def _handle_git_changes(self, prefix: str, suffix: str) -> None:
237
237
  """处理git仓库中的未提交修改"""
238
238
  print("🔄 正在检查未提交的修改...")
239
239
  if has_uncommitted_changes():
240
240
  print("⏳ 发现未提交修改,正在处理...")
241
241
  git_commiter = GitCommitTool()
242
- git_commiter.execute({})
242
+ git_commiter.execute({
243
+ "prefix": prefix,
244
+ "suffix": suffix
245
+ })
243
246
  print("✅ 未提交修改已处理完成")
244
247
  else:
245
248
  print("✅ 没有未提交的修改")
246
249
 
247
- def _init_env(self) -> None:
250
+ def _init_env(self, prefix: str, suffix: str) -> None:
248
251
  """初始化环境,组合以下功能:
249
252
  1. 查找git根目录
250
253
  2. 检查并更新.gitignore文件
@@ -254,7 +257,7 @@ class CodeAgent:
254
257
  print("🚀 正在初始化环境...")
255
258
  git_dir = self._find_git_root()
256
259
  self._update_gitignore(git_dir)
257
- self._handle_git_changes()
260
+ self._handle_git_changes(prefix, suffix)
258
261
  # 配置git对换行符变化不敏感
259
262
  self._configure_line_ending_settings()
260
263
  print("✅ 环境初始化完成")
@@ -473,7 +476,11 @@ class CodeAgent:
473
476
  return commits
474
477
 
475
478
  def _handle_commit_confirmation(
476
- self, commits: List[Tuple[str, str]], start_commit: Optional[str]
479
+ self,
480
+ commits: List[Tuple[str, str]],
481
+ start_commit: Optional[str],
482
+ prefix: str,
483
+ suffix: str,
477
484
  ) -> None:
478
485
  """处理提交确认和可能的重置"""
479
486
  if commits and user_confirm("是否接受以上提交记录?", True):
@@ -489,7 +496,10 @@ class CodeAgent:
489
496
  check=True,
490
497
  )
491
498
  git_commiter = GitCommitTool()
492
- git_commiter.execute({})
499
+ git_commiter.execute({
500
+ "prefix": prefix,
501
+ "suffix": suffix
502
+ })
493
503
 
494
504
  # 在用户接受commit后,根据配置决定是否保存记忆
495
505
  if self.agent.force_save_memory:
@@ -498,7 +508,7 @@ class CodeAgent:
498
508
  os.system(f"git reset --hard {str(start_commit)}") # 确保转换为字符串
499
509
  PrettyOutput.print("已重置到初始提交", OutputType.INFO)
500
510
 
501
- def run(self, user_input: str) -> Optional[str]:
511
+ def run(self, user_input: str, prefix: str = "", suffix: str = "") -> Optional[str]:
502
512
  """使用给定的用户输入运行代码代理。
503
513
 
504
514
  参数:
@@ -508,7 +518,7 @@ class CodeAgent:
508
518
  str: 描述执行结果的输出,成功时返回None
509
519
  """
510
520
  try:
511
- self._init_env()
521
+ self._init_env(prefix, suffix)
512
522
  start_commit = get_latest_commit_hash()
513
523
 
514
524
  # 获取项目统计信息并附加到用户输入
@@ -557,7 +567,7 @@ class CodeAgent:
557
567
  self._handle_uncommitted_changes()
558
568
  end_commit = get_latest_commit_hash()
559
569
  commits = self._show_commit_history(start_commit, end_commit)
560
- self._handle_commit_confirmation(commits, start_commit)
570
+ self._handle_commit_confirmation(commits, start_commit, prefix, suffix)
561
571
  return None
562
572
 
563
573
  except RuntimeError as e:
@@ -671,6 +681,16 @@ def cli(
671
681
  "--restore-session",
672
682
  help="从 .jarvis/saved_session.json 恢复会话状态",
673
683
  ),
684
+ prefix: str = typer.Option(
685
+ "",
686
+ "--prefix",
687
+ help="提交信息前缀(用空格分隔)",
688
+ ),
689
+ suffix: str = typer.Option(
690
+ "",
691
+ "--suffix",
692
+ help="提交信息后缀(用换行分隔)",
693
+ ),
674
694
  ) -> None:
675
695
  """Jarvis主入口点。"""
676
696
  init_env("欢迎使用 Jarvis-CodeAgent,您的代码工程助手已准备就绪!")
@@ -731,13 +751,13 @@ def cli(
731
751
  )
732
752
 
733
753
  if requirement:
734
- agent.run(requirement)
754
+ agent.run(requirement, prefix=prefix, suffix=suffix)
735
755
  else:
736
756
  while True:
737
757
  user_input = get_multiline_input("请输入你的需求(输入空行退出):")
738
758
  if not user_input:
739
759
  raise typer.Exit(code=0)
740
- agent.run(user_input)
760
+ agent.run(user_input, prefix=prefix, suffix=suffix)
741
761
 
742
762
  except typer.Exit:
743
763
  raise
@@ -4,7 +4,7 @@ import threading
4
4
  from typing import Any, Callable, Dict, List
5
5
  from urllib.parse import urljoin
6
6
 
7
- import requests
7
+ import requests # type: ignore[import-untyped]
8
8
 
9
9
  from jarvis.jarvis_mcp import McpClient
10
10
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
@@ -25,6 +25,8 @@ class StreamableMcpClient(McpClient):
25
25
  self.base_url = config.get("base_url", "")
26
26
  if not self.base_url:
27
27
  raise ValueError("No base_url specified in config")
28
+ # Normalize base_url to ensure trailing slash for urljoin correctness
29
+ self.base_url = self.base_url.rstrip("/") + "/"
28
30
 
29
31
  # 设置HTTP客户端
30
32
  self.session = requests.Session()
@@ -43,6 +45,8 @@ class StreamableMcpClient(McpClient):
43
45
  # 添加额外的HTTP头
44
46
  extra_headers = config.get("headers", {})
45
47
  self.session.headers.update(extra_headers)
48
+ # Request timeouts (connect, read) in seconds; can be overridden via config["timeout"]
49
+ self.timeout = config.get("timeout", (10, 300))
46
50
 
47
51
  # 请求相关属性
48
52
  self.pending_requests: Dict[str, threading.Event] = {} # 存储等待响应的请求 {id: Event}
@@ -141,7 +145,9 @@ class StreamableMcpClient(McpClient):
141
145
 
142
146
  # 发送请求到Streamable HTTP端点
143
147
  mcp_url = urljoin(self.base_url, "mcp")
144
- response = self.session.post(mcp_url, json=request, stream=True) # 启用流式传输
148
+ response = self.session.post(
149
+ mcp_url, json=request, stream=True, timeout=self.timeout
150
+ ) # 启用流式传输
145
151
  response.raise_for_status()
146
152
 
147
153
  # 处理流式响应
@@ -149,17 +155,21 @@ class StreamableMcpClient(McpClient):
149
155
  for line in response.iter_lines(decode_unicode=True):
150
156
  if line:
151
157
  try:
152
- data = json.loads(line)
158
+ line_data = line
159
+ if isinstance(line_data, str) and line_data.startswith("data:"):
160
+ # Handle SSE-formatted lines like "data: {...}"
161
+ line_data = line_data.split(":", 1)[1].strip()
162
+ data = json.loads(line_data)
153
163
  if "id" in data and data["id"] == req_id:
154
164
  # 这是我们的请求响应
155
165
  result = data
156
166
  break
157
167
  elif "method" in data:
158
168
  # 这是一个通知
159
- method = data.get("method", "")
169
+ notify_method = data.get("method", "")
160
170
  params = data.get("params", {})
161
- if method in self.notification_handlers:
162
- for handler in self.notification_handlers[method]:
171
+ if notify_method in self.notification_handlers:
172
+ for handler in self.notification_handlers[notify_method]:
163
173
  try:
164
174
  handler(params)
165
175
  except Exception as e:
@@ -171,6 +181,8 @@ class StreamableMcpClient(McpClient):
171
181
  PrettyOutput.print(f"无法解析响应: {line}", OutputType.WARNING)
172
182
  continue
173
183
 
184
+ # Ensure response is closed after streaming
185
+ response.close()
174
186
  if result is None:
175
187
  raise RuntimeError(f"未收到响应: {method}")
176
188
 
@@ -198,8 +210,9 @@ class StreamableMcpClient(McpClient):
198
210
 
199
211
  # 发送通知到Streamable HTTP端点
200
212
  mcp_url = urljoin(self.base_url, "mcp")
201
- response = self.session.post(mcp_url, json=notification)
213
+ response = self.session.post(mcp_url, json=notification, timeout=self.timeout)
202
214
  response.raise_for_status()
215
+ response.close()
203
216
 
204
217
  except Exception as e:
205
218
  PrettyOutput.print(f"发送通知失败: {str(e)}", OutputType.ERROR)
@@ -7,6 +7,7 @@ import asyncio
7
7
  import json
8
8
  import os
9
9
  import time
10
+ import threading
10
11
  import uuid
11
12
  from datetime import datetime
12
13
  from typing import Any, Dict, List, Optional, Union
@@ -72,8 +73,16 @@ def start_service(
72
73
  ) -> None:
73
74
  """Start OpenAI-compatible API server."""
74
75
  # Create logs directory if it doesn't exist
75
- logs_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "logs")
76
- os.makedirs(logs_dir, exist_ok=True)
76
+ # Prefer environment variable, then user directory, fall back to CWD
77
+ logs_dir = os.environ.get("JARVIS_LOG_DIR")
78
+ if not logs_dir:
79
+ logs_dir = os.path.join(os.path.expanduser("~"), ".jarvis", "logs")
80
+ try:
81
+ os.makedirs(logs_dir, exist_ok=True)
82
+ except Exception:
83
+ # As a last resort, use current working directory
84
+ logs_dir = os.path.join(os.getcwd(), "logs")
85
+ os.makedirs(logs_dir, exist_ok=True)
77
86
 
78
87
  app = FastAPI(title="Jarvis API Server")
79
88
 
@@ -81,7 +90,7 @@ def start_service(
81
90
  app.add_middleware(
82
91
  CORSMiddleware,
83
92
  allow_origins=["*"],
84
- allow_credentials=True,
93
+ allow_credentials=False,
85
94
  allow_methods=["*"],
86
95
  allow_headers=["*"],
87
96
  )
@@ -228,23 +237,23 @@ def start_service(
228
237
  "messages": [{"role": m.role, "content": m.content} for m in messages],
229
238
  }
230
239
 
231
- # Log the conversation
232
- log_conversation(
233
- conversation_id,
234
- [{"role": m.role, "content": m.content} for m in messages],
235
- model,
236
- )
240
+ # Logging moved to post-response to avoid duplicates
237
241
 
238
242
  if stream:
239
243
  # Return streaming response
240
244
  return StreamingResponse(
241
245
  stream_chat_response(platform, message_text, model), # type: ignore
242
246
  media_type="text/event-stream",
247
+ headers={"Cache-Control": "no-cache", "Connection": "keep-alive"},
243
248
  )
244
249
 
245
250
  # Get chat response
246
251
  try:
247
- response_text = platform.chat_until_success(message_text)
252
+ # Run potentially blocking call in a thread to avoid blocking the event loop
253
+ loop = asyncio.get_running_loop()
254
+ response_text = await loop.run_in_executor(
255
+ None, lambda: platform.chat_until_success(message_text)
256
+ )
248
257
 
249
258
  # Create response in OpenAI format
250
259
  completion_id = f"chatcmpl-{str(uuid.uuid4())}"
@@ -287,11 +296,31 @@ def start_service(
287
296
  raise HTTPException(status_code=500, detail=str(exc))
288
297
 
289
298
  async def stream_chat_response(platform: Any, message: str, model_name: str) -> Any:
290
- """Stream chat response in OpenAI-compatible format."""
299
+ """Stream chat response in OpenAI-compatible format without blocking the event loop."""
291
300
  completion_id = f"chatcmpl-{str(uuid.uuid4())}"
292
301
  created_time = int(time.time())
293
302
  conversation_id = str(uuid.uuid4())
294
303
 
304
+ loop = asyncio.get_running_loop()
305
+ queue: asyncio.Queue = asyncio.Queue()
306
+ SENTINEL = object()
307
+
308
+ def producer() -> None:
309
+ try:
310
+ for chunk in platform.chat(message):
311
+ if chunk:
312
+ asyncio.run_coroutine_threadsafe(queue.put(chunk), loop)
313
+ except Exception as exc:
314
+ # Use a special dict to pass error across thread boundary
315
+ asyncio.run_coroutine_threadsafe(
316
+ queue.put({"__error__": str(exc)}), loop
317
+ )
318
+ finally:
319
+ asyncio.run_coroutine_threadsafe(queue.put(SENTINEL), loop)
320
+
321
+ # Start producer thread
322
+ threading.Thread(target=producer, daemon=True).start()
323
+
295
324
  # Send the initial chunk with the role
296
325
  initial_data = {
297
326
  "id": completion_id,
@@ -304,36 +333,20 @@ def start_service(
304
333
  }
305
334
  yield f"data: {json.dumps(initial_data)}\n\n"
306
335
 
307
- try:
308
- # Use the streaming-capable chat method
309
- response_generator = platform.chat(message)
310
-
311
- full_response = ""
312
- has_content = False
313
-
314
- # Iterate over the generator and stream chunks
315
- for chunk in response_generator:
316
- if chunk:
317
- has_content = True
318
- full_response += chunk
319
- chunk_data = {
320
- "id": completion_id,
321
- "object": "chat.completion.chunk",
322
- "created": created_time,
323
- "model": model_name,
324
- "choices": [
325
- {
326
- "index": 0,
327
- "delta": {"content": chunk},
328
- "finish_reason": None,
329
- }
330
- ],
331
- }
332
- yield f"data: {json.dumps(chunk_data)}\n\n"
336
+ full_response = ""
337
+ has_content = False
338
+
339
+ while True:
340
+ item = await queue.get()
341
+ if item is SENTINEL:
342
+ break
343
+
344
+ if isinstance(item, dict) and "__error__" in item:
345
+ error_msg = f"Error during streaming: {item['__error__']}"
346
+ PrettyOutput.print(error_msg, OutputType.ERROR)
333
347
 
334
- if not has_content:
335
- no_response_message = "No response from model."
336
- chunk_data = {
348
+ # Send error information in the stream
349
+ error_chunk = {
337
350
  "id": completion_id,
338
351
  "object": "chat.completion.chunk",
339
352
  "created": created_time,
@@ -341,41 +354,45 @@ def start_service(
341
354
  "choices": [
342
355
  {
343
356
  "index": 0,
344
- "delta": {"content": no_response_message},
345
- "finish_reason": None,
357
+ "delta": {"content": error_msg},
358
+ "finish_reason": "stop",
346
359
  }
347
360
  ],
348
361
  }
349
- yield f"data: {json.dumps(chunk_data)}\n\n"
350
- full_response = no_response_message
362
+ yield f"data: {json.dumps(error_chunk)}\n\n"
363
+ yield "data: [DONE]\n\n"
364
+
365
+ # Log the error
366
+ log_conversation(
367
+ conversation_id,
368
+ [{"role": "user", "content": message}],
369
+ model_name,
370
+ response=f"ERROR: {error_msg}",
371
+ )
372
+ return
351
373
 
352
- # Send the final chunk with finish_reason
353
- final_data = {
374
+ # Normal chunk
375
+ chunk = item
376
+ has_content = True
377
+ full_response += chunk
378
+ chunk_data = {
354
379
  "id": completion_id,
355
380
  "object": "chat.completion.chunk",
356
381
  "created": created_time,
357
382
  "model": model_name,
358
- "choices": [{"index": 0, "delta": {}, "finish_reason": "stop"}],
383
+ "choices": [
384
+ {
385
+ "index": 0,
386
+ "delta": {"content": chunk},
387
+ "finish_reason": None,
388
+ }
389
+ ],
359
390
  }
360
- yield f"data: {json.dumps(final_data)}\n\n"
391
+ yield f"data: {json.dumps(chunk_data)}\n\n"
361
392
 
362
- # Send the [DONE] marker
363
- yield "data: [DONE]\n\n"
364
-
365
- # Log the full conversation
366
- log_conversation(
367
- conversation_id,
368
- [{"role": "user", "content": message}],
369
- model_name,
370
- full_response,
371
- )
372
-
373
- except Exception as exc:
374
- error_msg = f"Error during streaming: {str(exc)}"
375
- PrettyOutput.print(error_msg, OutputType.ERROR)
376
-
377
- # Send error information in the stream
378
- error_chunk = {
393
+ if not has_content:
394
+ no_response_message = "No response from model."
395
+ chunk_data = {
379
396
  "id": completion_id,
380
397
  "object": "chat.completion.chunk",
381
398
  "created": created_time,
@@ -383,21 +400,34 @@ def start_service(
383
400
  "choices": [
384
401
  {
385
402
  "index": 0,
386
- "delta": {"content": error_msg},
387
- "finish_reason": "stop",
403
+ "delta": {"content": no_response_message},
404
+ "finish_reason": None,
388
405
  }
389
406
  ],
390
407
  }
391
- yield f"data: {json.dumps(error_chunk)}\n\n"
392
- yield "data: [DONE]\n\n"
408
+ yield f"data: {json.dumps(chunk_data)}\n\n"
409
+ full_response = no_response_message
393
410
 
394
- # Log the error
395
- log_conversation(
396
- conversation_id,
397
- [{"role": "user", "content": message}],
398
- model_name,
399
- response=f"ERROR: {error_msg}",
400
- )
411
+ # Send the final chunk with finish_reason
412
+ final_data = {
413
+ "id": completion_id,
414
+ "object": "chat.completion.chunk",
415
+ "created": created_time,
416
+ "model": model_name,
417
+ "choices": [{"index": 0, "delta": {}, "finish_reason": "stop"}],
418
+ }
419
+ yield f"data: {json.dumps(final_data)}\n\n"
420
+
421
+ # Send the [DONE] marker
422
+ yield "data: [DONE]\n\n"
423
+
424
+ # Log the full conversation
425
+ log_conversation(
426
+ conversation_id,
427
+ [{"role": "user", "content": message}],
428
+ model_name,
429
+ full_response,
430
+ )
401
431
 
402
432
  # Run the server
403
433
  uvicorn.run(app, host=host, port=port)
@@ -79,7 +79,7 @@ want: 当前的git状态,期望获取xxx的提交记录
79
79
  name: execute_script
80
80
  arguments:
81
81
  interpreter: bash
82
- script_cotent: |2
82
+ script_content: |2
83
83
  git status --porcelain
84
84
  {ct("TOOL_CALL")}
85
85
  </string_format>
@@ -630,7 +630,9 @@ class ToolRegistry(OutputHandlerProtocol):
630
630
  content: 包含工具调用的内容
631
631
 
632
632
  返回:
633
- List[Dict]: 包含名称和参数的提取工具调用列表
633
+ Tuple[Dict[str, Dict[str, Any]], str]:
634
+ - 第一个元素是提取的工具调用字典
635
+ - 第二个元素是错误消息字符串(成功时为"")
634
636
 
635
637
  异常:
636
638
  Exception: 如果工具调用缺少必要字段
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.3.14
3
+ Version: 0.3.15
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
@@ -1,4 +1,4 @@
1
- jarvis/__init__.py,sha256=VWGr6Ejq9BZqFLJznrElHDghpbCaBnkgpyMgrmU4ysk,74
1
+ jarvis/__init__.py,sha256=pgHuAj3RKAHzddxR4-Pj5AIL9SywaQNWi0v2Ayu1tvQ,74
2
2
  jarvis/jarvis_agent/__init__.py,sha256=CkFa66l5lM0-_zlzApwBxTYbrnbC4_NqdD4QuK3H1VQ,32614
3
3
  jarvis/jarvis_agent/agent_manager.py,sha256=YzpMiF0H2-eyk2kn2o24Bkj3bXsQx7Pv2vfD4gWepo0,2893
4
4
  jarvis/jarvis_agent/builtin_input_handler.py,sha256=wS-FqpT3pIXwHn1dfL3SpXonUKWgVThbQueUIeyRc2U,2917
@@ -21,7 +21,7 @@ jarvis/jarvis_agent/task_manager.py,sha256=HJm4_SMpsFbQMUUsAZeHm7cZuhNbz28YW-DRL
21
21
  jarvis/jarvis_agent/tool_executor.py,sha256=k73cKhZEZpljvui4ZxALlFEIE-iLzJ32Softsmiwzqk,1896
22
22
  jarvis/jarvis_agent/tool_share_manager.py,sha256=R5ONIQlDXX9pFq3clwHFhEW8BAJ3ECaR2DqWCEC9tzM,5205
23
23
  jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- jarvis/jarvis_code_agent/code_agent.py,sha256=GPmCMlAERHC3yPy0LEv3ATdPsZm99MUz1XxcNB9_p2o,29972
24
+ jarvis/jarvis_code_agent/code_agent.py,sha256=Sw3I_IrUjHCSe2UbgmbSEZUk4uM4EOThabJtS7OmulU,30637
25
25
  jarvis/jarvis_code_agent/lint.py,sha256=LZPsfyZPMo7Wm7LN4osZocuNJwZx1ojacO3MlF870x8,4009
26
26
  jarvis/jarvis_code_analysis/code_review.py,sha256=OLoMtXz7Kov6cVTdBoxq_OsX_j0rb7Rk3or5tKgiLpo,36023
27
27
  jarvis/jarvis_code_analysis/checklists/__init__.py,sha256=LIXAYa1sW3l7foP6kohLWnE98I_EQ0T7z5bYKHq6rJA,78
@@ -52,7 +52,7 @@ jarvis/jarvis_git_utils/git_commiter.py,sha256=GpSnVa72b9yWoJBbK1Qp_Kb4iimwVW6K7
52
52
  jarvis/jarvis_mcp/__init__.py,sha256=OPMtjD-uq9xAaKCRIDyKIosaFfBe1GBPu1az-mQ0rVM,2048
53
53
  jarvis/jarvis_mcp/sse_mcp_client.py,sha256=neKrgFxwLDPWjVrl9uDt1ricNwbLZbv1ZEFh0IkmqZk,22656
54
54
  jarvis/jarvis_mcp/stdio_mcp_client.py,sha256=APYUksYKlMx7AVNODKOLrTkKZPnp4kqTQIYIuNDDKko,11286
55
- jarvis/jarvis_mcp/streamable_mcp_client.py,sha256=sP0KEsxVcXGht0eA7a_m-ECtZAk39s4PL9OUdm35x2Y,14467
55
+ jarvis/jarvis_mcp/streamable_mcp_client.py,sha256=P5keAhI7SsVjAq3nU9J7pp2Tk4pJDxjdPAb6ZcVPLEc,15279
56
56
  jarvis/jarvis_memory_organizer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
57
  jarvis/jarvis_memory_organizer/memory_organizer.py,sha256=4tf6Bs8u6Drj4repvuY3-XeH2Sb6ajVMFcW-rQEiGEY,26502
58
58
  jarvis/jarvis_methodology/main.py,sha256=6QF8hH3vB6rfxim0fPR34uVPf41zVpb4ZLqrFN2qONg,10983
@@ -69,7 +69,7 @@ jarvis/jarvis_platform/tongyi.py,sha256=KXEMfylTU91kHisXSaiz8dxzNXK_d7XD9vjuw4yX
69
69
  jarvis/jarvis_platform/yuanbao.py,sha256=32hjk1Ju1tqrMpF47JsSuaxej5K-gUPxjsDu9g0briY,23575
70
70
  jarvis/jarvis_platform_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
71
  jarvis/jarvis_platform_manager/main.py,sha256=5k7D-tBsNjXPH07eO4f-0gwyUY7STGSNBSl1PbLq15A,20966
72
- jarvis/jarvis_platform_manager/service.py,sha256=myJYGSUclCEiRTf3JKs4JndwhXJeQj7MQQy4i13jMt0,13767
72
+ jarvis/jarvis_platform_manager/service.py,sha256=DnuRJjD7RvunGt3LpMfUDr-Bps-Nb--frkeaC0nwxj0,14874
73
73
  jarvis/jarvis_rag/__init__.py,sha256=HRTXgnQxDuaE9x-e3r6SYqhJ5d4DSI_rrIxy2IGY6qk,320
74
74
  jarvis/jarvis_rag/cache.py,sha256=Tqx_Oe-AhuWlMXHGHUaIuG6OEHoHBVZq7mL3kldtFFU,2723
75
75
  jarvis/jarvis_rag/cli.py,sha256=bIQKibp8swJDyfFBXaiX5C20LHN_2W2knO2I-MQp58c,15620
@@ -97,7 +97,7 @@ jarvis/jarvis_tools/generate_new_tool.py,sha256=uaWKlDMGjetvvwKTj0_AVTdmd14IktRb
97
97
  jarvis/jarvis_tools/methodology.py,sha256=_K4GIDUodGEma3SvNRo7Qs5rliijgNespVLyAPN35JU,5233
98
98
  jarvis/jarvis_tools/read_code.py,sha256=EnI-R-5HyIQYhMD391nZWXHIuHHBF-OJIRE0QpLcPX4,6417
99
99
  jarvis/jarvis_tools/read_webpage.py,sha256=NmDUboVZd4CGHBPRFK6dp3uqVhuGopW1bOi3TcaLDF4,2092
100
- jarvis/jarvis_tools/registry.py,sha256=TtZ415LUMfWqfcgn3G5V4e3QLLU2ILNRatkP10U0Ypw,31047
100
+ jarvis/jarvis_tools/registry.py,sha256=nOcj_WKkEEiR2CJ84REchKSaWFGjnUFD3EVwxtfVF74,31165
101
101
  jarvis/jarvis_tools/retrieve_memory.py,sha256=0UBZm4wQTXLTj5WHXR9fjsiIDQh-Z2UINVu8cJ12YYg,9488
102
102
  jarvis/jarvis_tools/rewrite_file.py,sha256=eG_WKg6cVAXmuGwUqlWkcuyay5S8DOzEi8vZCmX3O8w,7255
103
103
  jarvis/jarvis_tools/save_memory.py,sha256=DjeFb38OtK9Y_RpWYHz8vL72JdauXZTlc_Y0FUQBtiM,7486
@@ -119,9 +119,9 @@ jarvis/jarvis_utils/methodology.py,sha256=IIMU17WVSunsWXsnXROd4G77LxgYs4xEC_xm_0
119
119
  jarvis/jarvis_utils/output.py,sha256=QRLlKObQKT0KuRSeZRqYb7NlTQvsd1oZXZ41WxeWEuU,10894
120
120
  jarvis/jarvis_utils/tag.py,sha256=f211opbbbTcSyzCDwuIK_oCnKhXPNK-RknYyGzY1yD0,431
121
121
  jarvis/jarvis_utils/utils.py,sha256=LiVui9RMsbfUdzbvBBwbGNC4uniGnLp3LFsk7LXGrQE,47370
122
- jarvis_ai_assistant-0.3.14.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
123
- jarvis_ai_assistant-0.3.14.dist-info/METADATA,sha256=jPFjzOOpjbCDOcVVwpNJCWax51_2VcfMRg3AnuGnbHo,18216
124
- jarvis_ai_assistant-0.3.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
125
- jarvis_ai_assistant-0.3.14.dist-info/entry_points.txt,sha256=4GcWKFxRJD-QU14gw_3ZaW4KuEVxOcZK9i270rwPdjA,1395
126
- jarvis_ai_assistant-0.3.14.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
127
- jarvis_ai_assistant-0.3.14.dist-info/RECORD,,
122
+ jarvis_ai_assistant-0.3.15.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
123
+ jarvis_ai_assistant-0.3.15.dist-info/METADATA,sha256=oVWrBozetAj2ICvlfwVHLPfHqkVdLP2NgTUuWNJ7u14,18216
124
+ jarvis_ai_assistant-0.3.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
125
+ jarvis_ai_assistant-0.3.15.dist-info/entry_points.txt,sha256=4GcWKFxRJD-QU14gw_3ZaW4KuEVxOcZK9i270rwPdjA,1395
126
+ jarvis_ai_assistant-0.3.15.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
127
+ jarvis_ai_assistant-0.3.15.dist-info/RECORD,,