jarvis-ai-assistant 0.7.8__py3-none-any.whl → 1.0.2__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.
Files changed (279) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +567 -222
  3. jarvis/jarvis_agent/agent_manager.py +19 -12
  4. jarvis/jarvis_agent/builtin_input_handler.py +79 -11
  5. jarvis/jarvis_agent/config_editor.py +7 -2
  6. jarvis/jarvis_agent/event_bus.py +24 -13
  7. jarvis/jarvis_agent/events.py +19 -1
  8. jarvis/jarvis_agent/file_context_handler.py +67 -64
  9. jarvis/jarvis_agent/file_methodology_manager.py +38 -24
  10. jarvis/jarvis_agent/jarvis.py +186 -114
  11. jarvis/jarvis_agent/language_extractors/__init__.py +8 -1
  12. jarvis/jarvis_agent/language_extractors/c_extractor.py +7 -4
  13. jarvis/jarvis_agent/language_extractors/cpp_extractor.py +9 -4
  14. jarvis/jarvis_agent/language_extractors/go_extractor.py +7 -4
  15. jarvis/jarvis_agent/language_extractors/java_extractor.py +27 -20
  16. jarvis/jarvis_agent/language_extractors/javascript_extractor.py +22 -17
  17. jarvis/jarvis_agent/language_extractors/python_extractor.py +7 -4
  18. jarvis/jarvis_agent/language_extractors/rust_extractor.py +7 -4
  19. jarvis/jarvis_agent/language_extractors/typescript_extractor.py +22 -17
  20. jarvis/jarvis_agent/language_support_info.py +250 -219
  21. jarvis/jarvis_agent/main.py +19 -23
  22. jarvis/jarvis_agent/memory_manager.py +9 -6
  23. jarvis/jarvis_agent/methodology_share_manager.py +21 -15
  24. jarvis/jarvis_agent/output_handler.py +4 -2
  25. jarvis/jarvis_agent/prompt_builder.py +7 -6
  26. jarvis/jarvis_agent/prompt_manager.py +113 -8
  27. jarvis/jarvis_agent/prompts.py +317 -85
  28. jarvis/jarvis_agent/protocols.py +5 -2
  29. jarvis/jarvis_agent/run_loop.py +192 -32
  30. jarvis/jarvis_agent/session_manager.py +7 -3
  31. jarvis/jarvis_agent/share_manager.py +23 -13
  32. jarvis/jarvis_agent/shell_input_handler.py +12 -8
  33. jarvis/jarvis_agent/stdio_redirect.py +25 -26
  34. jarvis/jarvis_agent/task_analyzer.py +29 -23
  35. jarvis/jarvis_agent/task_list.py +869 -0
  36. jarvis/jarvis_agent/task_manager.py +26 -23
  37. jarvis/jarvis_agent/tool_executor.py +6 -5
  38. jarvis/jarvis_agent/tool_share_manager.py +24 -14
  39. jarvis/jarvis_agent/user_interaction.py +3 -3
  40. jarvis/jarvis_agent/utils.py +9 -1
  41. jarvis/jarvis_agent/web_bridge.py +37 -17
  42. jarvis/jarvis_agent/web_output_sink.py +5 -2
  43. jarvis/jarvis_agent/web_server.py +165 -36
  44. jarvis/jarvis_c2rust/__init__.py +1 -1
  45. jarvis/jarvis_c2rust/cli.py +260 -141
  46. jarvis/jarvis_c2rust/collector.py +37 -18
  47. jarvis/jarvis_c2rust/constants.py +60 -0
  48. jarvis/jarvis_c2rust/library_replacer.py +242 -1010
  49. jarvis/jarvis_c2rust/library_replacer_checkpoint.py +133 -0
  50. jarvis/jarvis_c2rust/library_replacer_llm.py +287 -0
  51. jarvis/jarvis_c2rust/library_replacer_loader.py +191 -0
  52. jarvis/jarvis_c2rust/library_replacer_output.py +134 -0
  53. jarvis/jarvis_c2rust/library_replacer_prompts.py +124 -0
  54. jarvis/jarvis_c2rust/library_replacer_utils.py +188 -0
  55. jarvis/jarvis_c2rust/llm_module_agent.py +98 -1044
  56. jarvis/jarvis_c2rust/llm_module_agent_apply.py +170 -0
  57. jarvis/jarvis_c2rust/llm_module_agent_executor.py +288 -0
  58. jarvis/jarvis_c2rust/llm_module_agent_loader.py +170 -0
  59. jarvis/jarvis_c2rust/llm_module_agent_prompts.py +268 -0
  60. jarvis/jarvis_c2rust/llm_module_agent_types.py +57 -0
  61. jarvis/jarvis_c2rust/llm_module_agent_utils.py +150 -0
  62. jarvis/jarvis_c2rust/llm_module_agent_validator.py +119 -0
  63. jarvis/jarvis_c2rust/loaders.py +28 -10
  64. jarvis/jarvis_c2rust/models.py +5 -2
  65. jarvis/jarvis_c2rust/optimizer.py +192 -1974
  66. jarvis/jarvis_c2rust/optimizer_build_fix.py +286 -0
  67. jarvis/jarvis_c2rust/optimizer_clippy.py +766 -0
  68. jarvis/jarvis_c2rust/optimizer_config.py +49 -0
  69. jarvis/jarvis_c2rust/optimizer_docs.py +183 -0
  70. jarvis/jarvis_c2rust/optimizer_options.py +48 -0
  71. jarvis/jarvis_c2rust/optimizer_progress.py +469 -0
  72. jarvis/jarvis_c2rust/optimizer_report.py +52 -0
  73. jarvis/jarvis_c2rust/optimizer_unsafe.py +309 -0
  74. jarvis/jarvis_c2rust/optimizer_utils.py +469 -0
  75. jarvis/jarvis_c2rust/optimizer_visibility.py +185 -0
  76. jarvis/jarvis_c2rust/scanner.py +229 -166
  77. jarvis/jarvis_c2rust/transpiler.py +531 -2732
  78. jarvis/jarvis_c2rust/transpiler_agents.py +503 -0
  79. jarvis/jarvis_c2rust/transpiler_build.py +1294 -0
  80. jarvis/jarvis_c2rust/transpiler_codegen.py +204 -0
  81. jarvis/jarvis_c2rust/transpiler_compile.py +146 -0
  82. jarvis/jarvis_c2rust/transpiler_config.py +178 -0
  83. jarvis/jarvis_c2rust/transpiler_context.py +122 -0
  84. jarvis/jarvis_c2rust/transpiler_executor.py +516 -0
  85. jarvis/jarvis_c2rust/transpiler_generation.py +278 -0
  86. jarvis/jarvis_c2rust/transpiler_git.py +163 -0
  87. jarvis/jarvis_c2rust/transpiler_mod_utils.py +225 -0
  88. jarvis/jarvis_c2rust/transpiler_modules.py +336 -0
  89. jarvis/jarvis_c2rust/transpiler_planning.py +394 -0
  90. jarvis/jarvis_c2rust/transpiler_review.py +1196 -0
  91. jarvis/jarvis_c2rust/transpiler_symbols.py +176 -0
  92. jarvis/jarvis_c2rust/utils.py +269 -79
  93. jarvis/jarvis_code_agent/after_change.py +233 -0
  94. jarvis/jarvis_code_agent/build_validation_config.py +37 -30
  95. jarvis/jarvis_code_agent/builtin_rules.py +68 -0
  96. jarvis/jarvis_code_agent/code_agent.py +976 -1517
  97. jarvis/jarvis_code_agent/code_agent_build.py +227 -0
  98. jarvis/jarvis_code_agent/code_agent_diff.py +246 -0
  99. jarvis/jarvis_code_agent/code_agent_git.py +525 -0
  100. jarvis/jarvis_code_agent/code_agent_impact.py +177 -0
  101. jarvis/jarvis_code_agent/code_agent_lint.py +283 -0
  102. jarvis/jarvis_code_agent/code_agent_llm.py +159 -0
  103. jarvis/jarvis_code_agent/code_agent_postprocess.py +105 -0
  104. jarvis/jarvis_code_agent/code_agent_prompts.py +46 -0
  105. jarvis/jarvis_code_agent/code_agent_rules.py +305 -0
  106. jarvis/jarvis_code_agent/code_analyzer/__init__.py +52 -48
  107. jarvis/jarvis_code_agent/code_analyzer/base_language.py +12 -10
  108. jarvis/jarvis_code_agent/code_analyzer/build_validator/__init__.py +12 -11
  109. jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +16 -12
  110. jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +26 -17
  111. jarvis/jarvis_code_agent/code_analyzer/build_validator/detector.py +558 -104
  112. jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +27 -16
  113. jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +22 -18
  114. jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +21 -16
  115. jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +20 -16
  116. jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +27 -16
  117. jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +47 -23
  118. jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +71 -37
  119. jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +162 -35
  120. jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +111 -57
  121. jarvis/jarvis_code_agent/code_analyzer/build_validator.py +18 -12
  122. jarvis/jarvis_code_agent/code_analyzer/context_manager.py +185 -183
  123. jarvis/jarvis_code_agent/code_analyzer/context_recommender.py +2 -1
  124. jarvis/jarvis_code_agent/code_analyzer/dependency_analyzer.py +24 -15
  125. jarvis/jarvis_code_agent/code_analyzer/file_ignore.py +227 -141
  126. jarvis/jarvis_code_agent/code_analyzer/impact_analyzer.py +321 -247
  127. jarvis/jarvis_code_agent/code_analyzer/language_registry.py +37 -29
  128. jarvis/jarvis_code_agent/code_analyzer/language_support.py +21 -13
  129. jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +15 -9
  130. jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +75 -45
  131. jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +87 -52
  132. jarvis/jarvis_code_agent/code_analyzer/languages/java_language.py +84 -51
  133. jarvis/jarvis_code_agent/code_analyzer/languages/javascript_language.py +94 -64
  134. jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +109 -71
  135. jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +97 -63
  136. jarvis/jarvis_code_agent/code_analyzer/languages/typescript_language.py +103 -69
  137. jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +271 -268
  138. jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +76 -64
  139. jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +92 -19
  140. jarvis/jarvis_code_agent/diff_visualizer.py +998 -0
  141. jarvis/jarvis_code_agent/lint.py +223 -524
  142. jarvis/jarvis_code_agent/rule_share_manager.py +158 -0
  143. jarvis/jarvis_code_agent/rules/clean_code.md +144 -0
  144. jarvis/jarvis_code_agent/rules/code_review.md +115 -0
  145. jarvis/jarvis_code_agent/rules/documentation.md +165 -0
  146. jarvis/jarvis_code_agent/rules/generate_rules.md +52 -0
  147. jarvis/jarvis_code_agent/rules/performance.md +158 -0
  148. jarvis/jarvis_code_agent/rules/refactoring.md +139 -0
  149. jarvis/jarvis_code_agent/rules/security.md +160 -0
  150. jarvis/jarvis_code_agent/rules/tdd.md +78 -0
  151. jarvis/jarvis_code_agent/test_rules/cpp_test.md +118 -0
  152. jarvis/jarvis_code_agent/test_rules/go_test.md +98 -0
  153. jarvis/jarvis_code_agent/test_rules/java_test.md +99 -0
  154. jarvis/jarvis_code_agent/test_rules/javascript_test.md +113 -0
  155. jarvis/jarvis_code_agent/test_rules/php_test.md +117 -0
  156. jarvis/jarvis_code_agent/test_rules/python_test.md +91 -0
  157. jarvis/jarvis_code_agent/test_rules/ruby_test.md +102 -0
  158. jarvis/jarvis_code_agent/test_rules/rust_test.md +86 -0
  159. jarvis/jarvis_code_agent/utils.py +36 -26
  160. jarvis/jarvis_code_analysis/checklists/loader.py +21 -21
  161. jarvis/jarvis_code_analysis/code_review.py +64 -33
  162. jarvis/jarvis_data/config_schema.json +285 -192
  163. jarvis/jarvis_git_squash/main.py +8 -6
  164. jarvis/jarvis_git_utils/git_commiter.py +53 -76
  165. jarvis/jarvis_mcp/__init__.py +5 -2
  166. jarvis/jarvis_mcp/sse_mcp_client.py +40 -30
  167. jarvis/jarvis_mcp/stdio_mcp_client.py +27 -19
  168. jarvis/jarvis_mcp/streamable_mcp_client.py +35 -26
  169. jarvis/jarvis_memory_organizer/memory_organizer.py +78 -55
  170. jarvis/jarvis_methodology/main.py +48 -39
  171. jarvis/jarvis_multi_agent/__init__.py +56 -23
  172. jarvis/jarvis_multi_agent/main.py +15 -18
  173. jarvis/jarvis_platform/base.py +179 -111
  174. jarvis/jarvis_platform/human.py +27 -16
  175. jarvis/jarvis_platform/kimi.py +52 -45
  176. jarvis/jarvis_platform/openai.py +101 -40
  177. jarvis/jarvis_platform/registry.py +51 -33
  178. jarvis/jarvis_platform/tongyi.py +68 -38
  179. jarvis/jarvis_platform/yuanbao.py +59 -43
  180. jarvis/jarvis_platform_manager/main.py +68 -76
  181. jarvis/jarvis_platform_manager/service.py +24 -14
  182. jarvis/jarvis_rag/README_CONFIG.md +314 -0
  183. jarvis/jarvis_rag/README_DYNAMIC_LOADING.md +311 -0
  184. jarvis/jarvis_rag/README_ONLINE_MODELS.md +230 -0
  185. jarvis/jarvis_rag/__init__.py +57 -4
  186. jarvis/jarvis_rag/cache.py +3 -1
  187. jarvis/jarvis_rag/cli.py +48 -68
  188. jarvis/jarvis_rag/embedding_interface.py +39 -0
  189. jarvis/jarvis_rag/embedding_manager.py +7 -230
  190. jarvis/jarvis_rag/embeddings/__init__.py +41 -0
  191. jarvis/jarvis_rag/embeddings/base.py +114 -0
  192. jarvis/jarvis_rag/embeddings/cohere.py +66 -0
  193. jarvis/jarvis_rag/embeddings/edgefn.py +117 -0
  194. jarvis/jarvis_rag/embeddings/local.py +260 -0
  195. jarvis/jarvis_rag/embeddings/openai.py +62 -0
  196. jarvis/jarvis_rag/embeddings/registry.py +293 -0
  197. jarvis/jarvis_rag/llm_interface.py +8 -6
  198. jarvis/jarvis_rag/query_rewriter.py +8 -9
  199. jarvis/jarvis_rag/rag_pipeline.py +61 -52
  200. jarvis/jarvis_rag/reranker.py +7 -75
  201. jarvis/jarvis_rag/reranker_interface.py +32 -0
  202. jarvis/jarvis_rag/rerankers/__init__.py +41 -0
  203. jarvis/jarvis_rag/rerankers/base.py +109 -0
  204. jarvis/jarvis_rag/rerankers/cohere.py +67 -0
  205. jarvis/jarvis_rag/rerankers/edgefn.py +140 -0
  206. jarvis/jarvis_rag/rerankers/jina.py +79 -0
  207. jarvis/jarvis_rag/rerankers/local.py +89 -0
  208. jarvis/jarvis_rag/rerankers/registry.py +293 -0
  209. jarvis/jarvis_rag/retriever.py +58 -43
  210. jarvis/jarvis_sec/__init__.py +66 -141
  211. jarvis/jarvis_sec/agents.py +21 -17
  212. jarvis/jarvis_sec/analysis.py +80 -33
  213. jarvis/jarvis_sec/checkers/__init__.py +7 -13
  214. jarvis/jarvis_sec/checkers/c_checker.py +356 -164
  215. jarvis/jarvis_sec/checkers/rust_checker.py +47 -29
  216. jarvis/jarvis_sec/cli.py +43 -21
  217. jarvis/jarvis_sec/clustering.py +430 -272
  218. jarvis/jarvis_sec/file_manager.py +99 -55
  219. jarvis/jarvis_sec/parsers.py +9 -6
  220. jarvis/jarvis_sec/prompts.py +4 -3
  221. jarvis/jarvis_sec/report.py +44 -22
  222. jarvis/jarvis_sec/review.py +180 -107
  223. jarvis/jarvis_sec/status.py +50 -41
  224. jarvis/jarvis_sec/types.py +3 -0
  225. jarvis/jarvis_sec/utils.py +160 -83
  226. jarvis/jarvis_sec/verification.py +411 -181
  227. jarvis/jarvis_sec/workflow.py +132 -21
  228. jarvis/jarvis_smart_shell/main.py +28 -41
  229. jarvis/jarvis_stats/cli.py +14 -12
  230. jarvis/jarvis_stats/stats.py +28 -19
  231. jarvis/jarvis_stats/storage.py +14 -8
  232. jarvis/jarvis_stats/visualizer.py +12 -7
  233. jarvis/jarvis_tools/base.py +5 -2
  234. jarvis/jarvis_tools/clear_memory.py +13 -9
  235. jarvis/jarvis_tools/cli/main.py +23 -18
  236. jarvis/jarvis_tools/edit_file.py +572 -873
  237. jarvis/jarvis_tools/execute_script.py +10 -7
  238. jarvis/jarvis_tools/file_analyzer.py +7 -8
  239. jarvis/jarvis_tools/meta_agent.py +287 -0
  240. jarvis/jarvis_tools/methodology.py +5 -3
  241. jarvis/jarvis_tools/read_code.py +305 -1438
  242. jarvis/jarvis_tools/read_symbols.py +50 -17
  243. jarvis/jarvis_tools/read_webpage.py +19 -18
  244. jarvis/jarvis_tools/registry.py +435 -156
  245. jarvis/jarvis_tools/retrieve_memory.py +16 -11
  246. jarvis/jarvis_tools/save_memory.py +8 -6
  247. jarvis/jarvis_tools/search_web.py +31 -31
  248. jarvis/jarvis_tools/sub_agent.py +32 -28
  249. jarvis/jarvis_tools/sub_code_agent.py +44 -60
  250. jarvis/jarvis_tools/task_list_manager.py +1811 -0
  251. jarvis/jarvis_tools/virtual_tty.py +29 -19
  252. jarvis/jarvis_utils/__init__.py +4 -0
  253. jarvis/jarvis_utils/builtin_replace_map.py +2 -1
  254. jarvis/jarvis_utils/clipboard.py +9 -8
  255. jarvis/jarvis_utils/collections.py +331 -0
  256. jarvis/jarvis_utils/config.py +699 -194
  257. jarvis/jarvis_utils/dialogue_recorder.py +294 -0
  258. jarvis/jarvis_utils/embedding.py +6 -3
  259. jarvis/jarvis_utils/file_processors.py +7 -1
  260. jarvis/jarvis_utils/fzf.py +9 -3
  261. jarvis/jarvis_utils/git_utils.py +71 -42
  262. jarvis/jarvis_utils/globals.py +116 -32
  263. jarvis/jarvis_utils/http.py +6 -2
  264. jarvis/jarvis_utils/input.py +318 -83
  265. jarvis/jarvis_utils/jsonnet_compat.py +119 -104
  266. jarvis/jarvis_utils/methodology.py +37 -28
  267. jarvis/jarvis_utils/output.py +201 -44
  268. jarvis/jarvis_utils/utils.py +986 -628
  269. {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/METADATA +49 -33
  270. jarvis_ai_assistant-1.0.2.dist-info/RECORD +304 -0
  271. jarvis/jarvis_code_agent/code_analyzer/structured_code.py +0 -556
  272. jarvis/jarvis_tools/generate_new_tool.py +0 -205
  273. jarvis/jarvis_tools/lsp_client.py +0 -1552
  274. jarvis/jarvis_tools/rewrite_file.py +0 -105
  275. jarvis_ai_assistant-0.7.8.dist-info/RECORD +0 -218
  276. {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/WHEEL +0 -0
  277. {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/entry_points.txt +0 -0
  278. {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/licenses/LICENSE +0 -0
  279. {jarvis_ai_assistant-0.7.8.dist-info → jarvis_ai_assistant-1.0.2.dist-info}/top_level.txt +0 -0
@@ -10,23 +10,27 @@
10
10
  - 注入 web_multiline_input 与 web_user_confirm 到 Agent,使输入与确认经由浏览器完成
11
11
  - 启动本服务,前端通过页面与 Agent 交互
12
12
  """
13
+
13
14
  from __future__ import annotations
14
15
 
16
+ from jarvis.jarvis_utils.output import PrettyOutput
17
+
15
18
  import asyncio
19
+ import atexit
16
20
  import json
17
21
  import os
18
22
  import signal
19
- import atexit
20
23
  from pathlib import Path
21
- from typing import Any, Dict, Callable, Optional, List
24
+ from typing import Any, Callable, Dict, List, Optional
22
25
 
23
26
  import uvicorn
24
27
  from fastapi import FastAPI, WebSocket, WebSocketDisconnect
25
- from fastapi.responses import HTMLResponse
26
28
  from fastapi.middleware.cors import CORSMiddleware
29
+ from fastapi.responses import HTMLResponse
27
30
 
28
31
  from jarvis.jarvis_agent.web_bridge import WebBridge
29
- from jarvis.jarvis_utils.globals import set_interrupt, console
32
+ from jarvis.jarvis_utils.globals import console, set_interrupt
33
+
30
34
 
31
35
  # ---------------------------
32
36
  # 应用与页面
@@ -245,10 +249,13 @@ writeLine('消息解析失败: ' + e);
245
249
 
246
250
  return app
247
251
 
252
+
248
253
  # ---------------------------
249
254
  # WebSocket 端点
250
255
  # ---------------------------
251
- async def _ws_sender_loop(ws: WebSocket, queue: "asyncio.Queue[Dict[str, Any]]") -> None:
256
+ async def _ws_sender_loop(
257
+ ws: WebSocket, queue: "asyncio.Queue[Dict[str, Any]]"
258
+ ) -> None:
252
259
  try:
253
260
  while True:
254
261
  payload = await queue.get()
@@ -257,20 +264,28 @@ async def _ws_sender_loop(ws: WebSocket, queue: "asyncio.Queue[Dict[str, Any]]")
257
264
  # 发送循环异常即退出
258
265
  pass
259
266
 
260
- def _make_sender(queue: "asyncio.Queue[Dict[str, Any]]") -> Callable[[Dict[str, Any]], None]:
267
+
268
+ def _make_sender(
269
+ queue: "asyncio.Queue[Dict[str, Any]]",
270
+ ) -> Callable[[Dict[str, Any]], None]:
261
271
  # 同步函数,供 WebBridge 注册;将消息放入异步队列,由协程发送
262
272
  def _sender(payload: Dict[str, Any]) -> None:
263
273
  try:
264
274
  queue.put_nowait(payload)
265
275
  except Exception:
266
276
  pass
277
+
267
278
  return _sender
268
279
 
269
- def _make_sender_filtered(queue: "asyncio.Queue[Dict[str, Any]]", allowed_types: Optional[list[str]] = None) -> Callable[[Dict[str, Any]], None]:
280
+
281
+ def _make_sender_filtered(
282
+ queue: "asyncio.Queue[Dict[str, Any]]", allowed_types: Optional[list[str]] = None
283
+ ) -> Callable[[Dict[str, Any]], None]:
270
284
  """
271
285
  过滤版 sender:仅将指定类型的payload放入队列(用于单独的STDIO通道)。
272
286
  """
273
287
  allowed = set(allowed_types or [])
288
+
274
289
  def _sender(payload: Dict[str, Any]) -> None:
275
290
  try:
276
291
  ptype = payload.get("type")
@@ -278,8 +293,10 @@ def _make_sender_filtered(queue: "asyncio.Queue[Dict[str, Any]]", allowed_types:
278
293
  queue.put_nowait(payload)
279
294
  except Exception:
280
295
  pass
296
+
281
297
  return _sender
282
298
 
299
+
283
300
  def _run_and_notify(agent: Any, text: str) -> None:
284
301
  try:
285
302
  agent.run(text)
@@ -289,14 +306,20 @@ def _run_and_notify(agent: Any, text: str) -> None:
289
306
  except Exception:
290
307
  pass
291
308
 
292
- def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, launch_command: Optional[List[str]] = None) -> None:
309
+
310
+ def start_web_server(
311
+ agent: Any,
312
+ host: str = "127.0.0.1",
313
+ port: int = 8765,
314
+ launch_command: Optional[List[str]] = None,
315
+ ) -> None:
293
316
  """
294
317
  启动Web服务,并将Agent绑定到应用上下文。
295
318
  - agent: 现有的 Agent 实例(已完成初始化)
296
319
  - host: Web 服务主机地址
297
320
  - port: Web 服务端口
298
321
  - launch_command: 交互式终端启动命令(列表格式,如 ["jvs", "--task", "xxx"]),
299
- 如果为 None,则从环境变量 JARVIS_WEB_LAUNCH_JSON 读取
322
+ 如果为 None,则从环境变量 web_launch_json 读取
300
323
  """
301
324
  app = _build_app()
302
325
  app.state.agent = agent # 供 WS 端点调用
@@ -319,7 +342,14 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
319
342
  bridge.add_client(sender)
320
343
  send_task = asyncio.create_task(_ws_sender_loop(ws, queue))
321
344
  try:
322
- await ws.send_text(json.dumps({"type": "output", "payload": {"text": "STDIO 通道已就绪", "output_type": "INFO"}}))
345
+ await ws.send_text(
346
+ json.dumps(
347
+ {
348
+ "type": "output",
349
+ "payload": {"text": "STDIO 通道已就绪", "output_type": "INFO"},
350
+ }
351
+ )
352
+ )
323
353
  except Exception:
324
354
  pass
325
355
  try:
@@ -334,6 +364,7 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
334
364
  if mtype == "stdin":
335
365
  try:
336
366
  from jarvis.jarvis_agent.stdio_redirect import feed_web_stdin
367
+
337
368
  text = data.get("data", "")
338
369
  if isinstance(text, str) and text:
339
370
  feed_web_stdin(text)
@@ -372,7 +403,9 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
372
403
  try:
373
404
  set_interrupt(True)
374
405
  # 可选:发送回执
375
- await ws.send_text(json.dumps({"type": "ack", "cmd": "interrupt"}))
406
+ await ws.send_text(
407
+ json.dumps({"type": "ack", "cmd": "interrupt"})
408
+ )
376
409
  except Exception:
377
410
  pass
378
411
  elif mtype == "resize":
@@ -411,9 +444,20 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
411
444
  await ws.accept()
412
445
  # 仅在非 Windows 平台提供 PTY 功能
413
446
  import sys as _sys
447
+
414
448
  if _sys.platform == "win32":
415
449
  try:
416
- await ws.send_text(json.dumps({"type": "output", "payload": {"text": "当前平台不支持交互式终端(PTY)", "output_type": "ERROR"}}))
450
+ await ws.send_text(
451
+ json.dumps(
452
+ {
453
+ "type": "output",
454
+ "payload": {
455
+ "text": "当前平台不支持交互式终端(PTY)",
456
+ "output_type": "ERROR",
457
+ },
458
+ }
459
+ )
460
+ )
417
461
  except Exception:
418
462
  pass
419
463
  try:
@@ -423,15 +467,26 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
423
467
  return
424
468
 
425
469
  import os as _os
470
+
426
471
  try:
427
- import pty as _pty
428
472
  import fcntl as _fcntl
473
+ import pty as _pty
429
474
  import select as _select
430
- import termios as _termios
431
475
  import struct as _struct
476
+ import termios as _termios
432
477
  except Exception:
433
478
  try:
434
- await ws.send_text(json.dumps({"type": "output", "payload": {"text": "服务端缺少 PTY 相关依赖,无法启动交互式终端", "output_type": "ERROR"}}))
479
+ await ws.send_text(
480
+ json.dumps(
481
+ {
482
+ "type": "output",
483
+ "payload": {
484
+ "text": "服务端缺少 PTY 相关依赖,无法启动交互式终端",
485
+ "output_type": "ERROR",
486
+ },
487
+ }
488
+ )
489
+ )
435
490
  except Exception:
436
491
  pass
437
492
  try:
@@ -456,24 +511,29 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
456
511
  # 会话结束后等待用户按回车再重启
457
512
  waiting_for_ack = False
458
513
  ack_event = asyncio.Event()
459
-
514
+
460
515
  # 在 fork 前获取启动命令(避免在子进程中访问 app.state)
461
516
  _launch_cmd = None
462
517
  try:
463
518
  if hasattr(app.state, "launch_command") and app.state.launch_command:
464
519
  _launch_cmd = app.state.launch_command
465
520
  # 调试输出
466
- if _os.environ.get("JARVIS_DEBUG_WEB_LAUNCH_CMD") == "1":
467
- print(f"🔍 Web服务器: 使用传入的启动命令: {_launch_cmd}")
521
+ if _os.environ.get("debug_web_launch_cmd") == "1":
522
+ PrettyOutput.auto_print(
523
+ f"🔍 Web服务器: 使用传入的启动命令: {_launch_cmd}"
524
+ )
468
525
  else:
469
526
  # 回退到环境变量
470
527
  import json as _json
471
- _cmd_json = _os.environ.get("JARVIS_WEB_LAUNCH_JSON", "")
528
+
529
+ _cmd_json = _os.environ.get("web_launch_json", "")
472
530
  if _cmd_json:
473
531
  try:
474
532
  _launch_cmd = _json.loads(_cmd_json)
475
- if _os.environ.get("JARVIS_DEBUG_WEB_LAUNCH_CMD") == "1":
476
- print(f"🔍 Web服务器: 从环境变量读取启动命令: {_launch_cmd}")
533
+ if _os.environ.get("debug_web_launch_cmd") == "1":
534
+ PrettyOutput.auto_print(
535
+ f"🔍 Web服务器: 从环境变量读取启动命令: {_launch_cmd}"
536
+ )
477
537
  except Exception:
478
538
  _launch_cmd = None
479
539
  except Exception:
@@ -487,16 +547,21 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
487
547
  # 子进程:执行启动命令,失败时回退到系统 shell
488
548
  # 使用在 fork 前获取的命令
489
549
  _argv = _launch_cmd
490
-
550
+
491
551
  # 如果获取到有效命令,执行它
492
- if _argv and isinstance(_argv, list) and len(_argv) > 0 and isinstance(_argv[0], str):
552
+ if (
553
+ _argv
554
+ and isinstance(_argv, list)
555
+ and len(_argv) > 0
556
+ and isinstance(_argv[0], str)
557
+ ):
493
558
  try:
494
- if _os.environ.get("JARVIS_DEBUG_WEB_LAUNCH_CMD") == "1":
495
- print(f"🔍 子进程: 执行命令: {_argv}")
559
+ if _os.environ.get("debug_web_launch_cmd") == "1":
560
+ PrettyOutput.auto_print(f"🔍 子进程: 执行命令: {_argv}")
496
561
  _os.execvp(_argv[0], _argv)
497
562
  except Exception as e:
498
- if _os.environ.get("JARVIS_DEBUG_WEB_LAUNCH_CMD") == "1":
499
- print(f"⚠️ 子进程: 执行命令失败: {e}")
563
+ if _os.environ.get("debug_web_launch_cmd") == "1":
564
+ PrettyOutput.auto_print(f"⚠️ 子进程: 执行命令失败: {e}")
500
565
  pass
501
566
  # 若未配置或执行失败,回退到 /bin/bash 或 /bin/sh
502
567
  try:
@@ -530,7 +595,17 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
530
595
  ok = _spawn_jvs_session()
531
596
  if not ok:
532
597
  try:
533
- await ws.send_text(json.dumps({"type": "output", "payload": {"text": "启动交互式终端失败", "output_type": "ERROR"}}))
598
+ await ws.send_text(
599
+ json.dumps(
600
+ {
601
+ "type": "output",
602
+ "payload": {
603
+ "text": "启动交互式终端失败",
604
+ "output_type": "ERROR",
605
+ },
606
+ }
607
+ )
608
+ )
534
609
  except Exception:
535
610
  pass
536
611
  try:
@@ -555,7 +630,14 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
555
630
  waiting_for_ack = False
556
631
  if _spawn_jvs_session():
557
632
  try:
558
- await ws.send_text(json.dumps({"type": "stdio", "text": "\r\njvs 会话已重启\r\n"}))
633
+ await ws.send_text(
634
+ json.dumps(
635
+ {
636
+ "type": "stdio",
637
+ "text": "\r\njvs 会话已重启\r\n",
638
+ }
639
+ )
640
+ )
559
641
  except Exception:
560
642
  pass
561
643
  fd = session.get("master_fd")
@@ -568,7 +650,14 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
568
650
  # 非确认流程:自动重启
569
651
  if _spawn_jvs_session():
570
652
  try:
571
- await ws.send_text(json.dumps({"type": "stdio", "text": "\r\njvs 会话已重启\r\n"}))
653
+ await ws.send_text(
654
+ json.dumps(
655
+ {
656
+ "type": "stdio",
657
+ "text": "\r\njvs 会话已重启\r\n",
658
+ }
659
+ )
660
+ )
572
661
  except Exception:
573
662
  pass
574
663
  fd = session.get("master_fd")
@@ -591,7 +680,14 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
591
680
  data = b""
592
681
  if data:
593
682
  try:
594
- await ws.send_text(json.dumps({"type": "stdio", "text": data.decode(errors="ignore")}))
683
+ await ws.send_text(
684
+ json.dumps(
685
+ {
686
+ "type": "stdio",
687
+ "text": data.decode(errors="ignore"),
688
+ }
689
+ )
690
+ )
595
691
  except Exception:
596
692
  break
597
693
  else:
@@ -609,7 +705,14 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
609
705
  # 标记等待用户回车,并提示
610
706
  waiting_for_ack = True
611
707
  try:
612
- await ws.send_text(json.dumps({"type": "stdio", "text": "\r\nAgent 已结束。按回车继续,系统将重启新的 Agent。\r\n> "}))
708
+ await ws.send_text(
709
+ json.dumps(
710
+ {
711
+ "type": "stdio",
712
+ "text": "\r\nAgent 已结束。按回车继续,系统将重启新的 Agent。\r\n> ",
713
+ }
714
+ )
715
+ )
613
716
  except Exception:
614
717
  pass
615
718
  # 不立即重启,等待顶部 fd None 分支在收到回车后处理
@@ -645,7 +748,17 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
645
748
  pass
646
749
  # 发送就绪提示
647
750
  try:
648
- await ws.send_text(json.dumps({"type": "output", "payload": {"text": "交互式终端已就绪(PTY)", "output_type": "INFO"}}))
751
+ await ws.send_text(
752
+ json.dumps(
753
+ {
754
+ "type": "output",
755
+ "payload": {
756
+ "text": "交互式终端已就绪(PTY)",
757
+ "output_type": "INFO",
758
+ },
759
+ }
760
+ )
761
+ )
649
762
  except Exception:
650
763
  pass
651
764
 
@@ -672,12 +785,22 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
672
785
  else:
673
786
  # 非回车输入时轻提示
674
787
  try:
675
- await ws.send_text(json.dumps({"type": "stdio", "text": "\r\n按回车继续。\r\n> "}))
788
+ await ws.send_text(
789
+ json.dumps(
790
+ {
791
+ "type": "stdio",
792
+ "text": "\r\n按回车继续。\r\n> ",
793
+ }
794
+ )
795
+ )
676
796
  except Exception:
677
797
  pass
678
798
  else:
679
799
  # 原样写入(保留控制字符);前端可按需发送回车
680
- _os.write(session.get("master_fd") or -1, text.encode(errors="ignore"))
800
+ _os.write(
801
+ session.get("master_fd") or -1,
802
+ text.encode(errors="ignore"),
803
+ )
681
804
  except Exception:
682
805
  pass
683
806
  elif mtype == "resize":
@@ -723,6 +846,7 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
723
846
  pid_val = session.get("pid")
724
847
  if isinstance(pid_val, int):
725
848
  import signal as _signal
849
+
726
850
  try:
727
851
  _os.kill(pid_val, _signal.SIGTERM)
728
852
  except Exception:
@@ -734,7 +858,7 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
734
858
  except Exception:
735
859
  pass
736
860
 
737
- print(f"✅ 启动 Jarvis Web 服务: http://{host}:{port}")
861
+ PrettyOutput.auto_print(f"✅ 启动 Jarvis Web 服务: http://{host}:{port}")
738
862
  # 在服务端进程内也写入并维护 PID 文件,增强可检测性与可清理性
739
863
  try:
740
864
  pidfile = Path(os.path.expanduser("~/.jarvis")) / f"jarvis_web_{port}.pid"
@@ -746,16 +870,19 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
746
870
  pidfile.write_text(str(os.getpid()), encoding="utf-8")
747
871
  except Exception:
748
872
  pass
873
+
749
874
  # 退出时清理 PID 文件
750
875
  def _cleanup_pidfile() -> None:
751
876
  try:
752
877
  pidfile.unlink(missing_ok=True)
753
878
  except Exception:
754
879
  pass
880
+
755
881
  try:
756
882
  atexit.register(_cleanup_pidfile)
757
883
  except Exception:
758
884
  pass
885
+
759
886
  # 处理 SIGTERM/SIGINT,清理后退出
760
887
  def _signal_handler(signum: int, frame: Any) -> None:
761
888
  try:
@@ -765,6 +892,7 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
765
892
  os._exit(0)
766
893
  except Exception:
767
894
  pass
895
+
768
896
  try:
769
897
  signal.signal(signal.SIGTERM, _signal_handler)
770
898
  except Exception:
@@ -777,6 +905,7 @@ def start_web_server(agent: Any, host: str = "127.0.0.1", port: int = 8765, laun
777
905
  pass
778
906
  # 配置 uvicorn 日志级别,隐藏连接信息和访问日志
779
907
  import logging
908
+
780
909
  # 禁用 uvicorn 的访问日志
781
910
  logging.getLogger("uvicorn.access").setLevel(logging.WARNING)
782
911
  # 禁用 uvicorn 的常规日志(连接信息等)
@@ -23,4 +23,4 @@ Jarvis C2Rust 工具集。
23
23
  - 所有路径均推荐使用 <project_root>/.jarvis/c2rust 下的标准文件名,便于断点续跑与复用。
24
24
  """
25
25
 
26
- __all__ = ["scanner", "optimizer"]
26
+ __all__ = ["scanner", "optimizer"]