jarvis-ai-assistant 0.1.222__py3-none-any.whl → 0.7.0__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 (162) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +1143 -245
  3. jarvis/jarvis_agent/agent_manager.py +97 -0
  4. jarvis/jarvis_agent/builtin_input_handler.py +12 -10
  5. jarvis/jarvis_agent/config_editor.py +57 -0
  6. jarvis/jarvis_agent/edit_file_handler.py +392 -99
  7. jarvis/jarvis_agent/event_bus.py +48 -0
  8. jarvis/jarvis_agent/events.py +157 -0
  9. jarvis/jarvis_agent/file_context_handler.py +79 -0
  10. jarvis/jarvis_agent/file_methodology_manager.py +117 -0
  11. jarvis/jarvis_agent/jarvis.py +1117 -147
  12. jarvis/jarvis_agent/main.py +78 -34
  13. jarvis/jarvis_agent/memory_manager.py +195 -0
  14. jarvis/jarvis_agent/methodology_share_manager.py +174 -0
  15. jarvis/jarvis_agent/prompt_manager.py +82 -0
  16. jarvis/jarvis_agent/prompts.py +46 -9
  17. jarvis/jarvis_agent/protocols.py +4 -1
  18. jarvis/jarvis_agent/rewrite_file_handler.py +141 -0
  19. jarvis/jarvis_agent/run_loop.py +146 -0
  20. jarvis/jarvis_agent/session_manager.py +9 -9
  21. jarvis/jarvis_agent/share_manager.py +228 -0
  22. jarvis/jarvis_agent/shell_input_handler.py +23 -3
  23. jarvis/jarvis_agent/stdio_redirect.py +295 -0
  24. jarvis/jarvis_agent/task_analyzer.py +212 -0
  25. jarvis/jarvis_agent/task_manager.py +154 -0
  26. jarvis/jarvis_agent/task_planner.py +496 -0
  27. jarvis/jarvis_agent/tool_executor.py +8 -4
  28. jarvis/jarvis_agent/tool_share_manager.py +139 -0
  29. jarvis/jarvis_agent/user_interaction.py +42 -0
  30. jarvis/jarvis_agent/utils.py +54 -0
  31. jarvis/jarvis_agent/web_bridge.py +189 -0
  32. jarvis/jarvis_agent/web_output_sink.py +53 -0
  33. jarvis/jarvis_agent/web_server.py +751 -0
  34. jarvis/jarvis_c2rust/__init__.py +26 -0
  35. jarvis/jarvis_c2rust/cli.py +613 -0
  36. jarvis/jarvis_c2rust/collector.py +258 -0
  37. jarvis/jarvis_c2rust/library_replacer.py +1122 -0
  38. jarvis/jarvis_c2rust/llm_module_agent.py +1300 -0
  39. jarvis/jarvis_c2rust/optimizer.py +960 -0
  40. jarvis/jarvis_c2rust/scanner.py +1681 -0
  41. jarvis/jarvis_c2rust/transpiler.py +2325 -0
  42. jarvis/jarvis_code_agent/build_validation_config.py +133 -0
  43. jarvis/jarvis_code_agent/code_agent.py +1605 -178
  44. jarvis/jarvis_code_agent/code_analyzer/__init__.py +62 -0
  45. jarvis/jarvis_code_agent/code_analyzer/base_language.py +74 -0
  46. jarvis/jarvis_code_agent/code_analyzer/build_validator/__init__.py +44 -0
  47. jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +102 -0
  48. jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +59 -0
  49. jarvis/jarvis_code_agent/code_analyzer/build_validator/detector.py +125 -0
  50. jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +69 -0
  51. jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +38 -0
  52. jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +44 -0
  53. jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +38 -0
  54. jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +50 -0
  55. jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +93 -0
  56. jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +129 -0
  57. jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +54 -0
  58. jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +154 -0
  59. jarvis/jarvis_code_agent/code_analyzer/build_validator.py +43 -0
  60. jarvis/jarvis_code_agent/code_analyzer/context_manager.py +363 -0
  61. jarvis/jarvis_code_agent/code_analyzer/context_recommender.py +18 -0
  62. jarvis/jarvis_code_agent/code_analyzer/dependency_analyzer.py +132 -0
  63. jarvis/jarvis_code_agent/code_analyzer/file_ignore.py +330 -0
  64. jarvis/jarvis_code_agent/code_analyzer/impact_analyzer.py +781 -0
  65. jarvis/jarvis_code_agent/code_analyzer/language_registry.py +185 -0
  66. jarvis/jarvis_code_agent/code_analyzer/language_support.py +89 -0
  67. jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +31 -0
  68. jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +231 -0
  69. jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +183 -0
  70. jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +219 -0
  71. jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +209 -0
  72. jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +451 -0
  73. jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +77 -0
  74. jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +48 -0
  75. jarvis/jarvis_code_agent/lint.py +275 -13
  76. jarvis/jarvis_code_agent/utils.py +142 -0
  77. jarvis/jarvis_code_analysis/checklists/loader.py +20 -6
  78. jarvis/jarvis_code_analysis/code_review.py +583 -548
  79. jarvis/jarvis_data/config_schema.json +339 -28
  80. jarvis/jarvis_git_squash/main.py +22 -13
  81. jarvis/jarvis_git_utils/git_commiter.py +171 -55
  82. jarvis/jarvis_mcp/sse_mcp_client.py +22 -15
  83. jarvis/jarvis_mcp/stdio_mcp_client.py +4 -4
  84. jarvis/jarvis_mcp/streamable_mcp_client.py +36 -16
  85. jarvis/jarvis_memory_organizer/memory_organizer.py +753 -0
  86. jarvis/jarvis_methodology/main.py +48 -63
  87. jarvis/jarvis_multi_agent/__init__.py +302 -43
  88. jarvis/jarvis_multi_agent/main.py +70 -24
  89. jarvis/jarvis_platform/ai8.py +40 -23
  90. jarvis/jarvis_platform/base.py +210 -49
  91. jarvis/jarvis_platform/human.py +11 -1
  92. jarvis/jarvis_platform/kimi.py +82 -76
  93. jarvis/jarvis_platform/openai.py +73 -1
  94. jarvis/jarvis_platform/registry.py +8 -15
  95. jarvis/jarvis_platform/tongyi.py +115 -101
  96. jarvis/jarvis_platform/yuanbao.py +89 -63
  97. jarvis/jarvis_platform_manager/main.py +194 -132
  98. jarvis/jarvis_platform_manager/service.py +122 -86
  99. jarvis/jarvis_rag/cli.py +156 -53
  100. jarvis/jarvis_rag/embedding_manager.py +155 -12
  101. jarvis/jarvis_rag/llm_interface.py +10 -13
  102. jarvis/jarvis_rag/query_rewriter.py +63 -12
  103. jarvis/jarvis_rag/rag_pipeline.py +222 -40
  104. jarvis/jarvis_rag/reranker.py +26 -3
  105. jarvis/jarvis_rag/retriever.py +270 -14
  106. jarvis/jarvis_sec/__init__.py +3605 -0
  107. jarvis/jarvis_sec/checkers/__init__.py +32 -0
  108. jarvis/jarvis_sec/checkers/c_checker.py +2680 -0
  109. jarvis/jarvis_sec/checkers/rust_checker.py +1108 -0
  110. jarvis/jarvis_sec/cli.py +116 -0
  111. jarvis/jarvis_sec/report.py +257 -0
  112. jarvis/jarvis_sec/status.py +264 -0
  113. jarvis/jarvis_sec/types.py +20 -0
  114. jarvis/jarvis_sec/workflow.py +219 -0
  115. jarvis/jarvis_smart_shell/main.py +405 -137
  116. jarvis/jarvis_stats/__init__.py +13 -0
  117. jarvis/jarvis_stats/cli.py +387 -0
  118. jarvis/jarvis_stats/stats.py +711 -0
  119. jarvis/jarvis_stats/storage.py +612 -0
  120. jarvis/jarvis_stats/visualizer.py +282 -0
  121. jarvis/jarvis_tools/ask_user.py +1 -0
  122. jarvis/jarvis_tools/base.py +18 -2
  123. jarvis/jarvis_tools/clear_memory.py +239 -0
  124. jarvis/jarvis_tools/cli/main.py +220 -144
  125. jarvis/jarvis_tools/execute_script.py +52 -12
  126. jarvis/jarvis_tools/file_analyzer.py +17 -12
  127. jarvis/jarvis_tools/generate_new_tool.py +46 -24
  128. jarvis/jarvis_tools/read_code.py +277 -18
  129. jarvis/jarvis_tools/read_symbols.py +141 -0
  130. jarvis/jarvis_tools/read_webpage.py +86 -13
  131. jarvis/jarvis_tools/registry.py +294 -90
  132. jarvis/jarvis_tools/retrieve_memory.py +227 -0
  133. jarvis/jarvis_tools/save_memory.py +194 -0
  134. jarvis/jarvis_tools/search_web.py +62 -28
  135. jarvis/jarvis_tools/sub_agent.py +205 -0
  136. jarvis/jarvis_tools/sub_code_agent.py +217 -0
  137. jarvis/jarvis_tools/virtual_tty.py +330 -62
  138. jarvis/jarvis_utils/builtin_replace_map.py +4 -5
  139. jarvis/jarvis_utils/clipboard.py +90 -0
  140. jarvis/jarvis_utils/config.py +607 -50
  141. jarvis/jarvis_utils/embedding.py +3 -0
  142. jarvis/jarvis_utils/fzf.py +57 -0
  143. jarvis/jarvis_utils/git_utils.py +251 -29
  144. jarvis/jarvis_utils/globals.py +174 -17
  145. jarvis/jarvis_utils/http.py +58 -79
  146. jarvis/jarvis_utils/input.py +899 -153
  147. jarvis/jarvis_utils/methodology.py +210 -83
  148. jarvis/jarvis_utils/output.py +220 -137
  149. jarvis/jarvis_utils/utils.py +1906 -135
  150. jarvis_ai_assistant-0.7.0.dist-info/METADATA +465 -0
  151. jarvis_ai_assistant-0.7.0.dist-info/RECORD +192 -0
  152. {jarvis_ai_assistant-0.1.222.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/entry_points.txt +8 -2
  153. jarvis/jarvis_git_details/main.py +0 -265
  154. jarvis/jarvis_platform/oyi.py +0 -357
  155. jarvis/jarvis_tools/edit_file.py +0 -255
  156. jarvis/jarvis_tools/rewrite_file.py +0 -195
  157. jarvis_ai_assistant-0.1.222.dist-info/METADATA +0 -767
  158. jarvis_ai_assistant-0.1.222.dist-info/RECORD +0 -110
  159. /jarvis/{jarvis_git_details → jarvis_memory_organizer}/__init__.py +0 -0
  160. {jarvis_ai_assistant-0.1.222.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/WHEEL +0 -0
  161. {jarvis_ai_assistant-0.1.222.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/licenses/LICENSE +0 -0
  162. {jarvis_ai_assistant-0.1.222.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/top_level.txt +0 -0
@@ -9,20 +9,26 @@
9
9
  """
10
10
  import os
11
11
 
12
- # 全局变量:保存最后一条消息
13
- last_message: str = ""
14
- from typing import Any, Set
12
+ # 全局变量:保存消息历史
13
+ from typing import Any, Dict, List, Optional
15
14
 
16
- import colorama
17
- from rich.console import Console
18
- from rich.theme import Theme
15
+ message_history: List[str] = []
16
+ MAX_HISTORY_SIZE = 50
17
+
18
+ # 短期记忆存储
19
+ short_term_memories: List[Dict[str, Any]] = []
20
+ MAX_SHORT_TERM_MEMORIES = 100
21
+
22
+ import colorama # noqa: E402
23
+ from rich.console import Console # noqa: E402
24
+ from rich.theme import Theme # noqa: E402
19
25
 
20
26
  # 初始化colorama以支持跨平台的彩色文本
21
27
  colorama.init()
22
28
  # 禁用tokenizers并行以避免多进程问题
23
29
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
24
30
  # 全局代理管理
25
- global_agents: Set[str] = set()
31
+ global_agents: Dict[str, Any] = {}
26
32
  current_agent_name: str = ""
27
33
  # 表示与大模型交互的深度(>0表示正在交互)
28
34
  g_in_chat: int = 0
@@ -66,6 +72,19 @@ def make_agent_name(agent_name: str) -> str:
66
72
  return agent_name
67
73
 
68
74
 
75
+ def get_agent(agent_name: str) -> Any:
76
+ """
77
+ 获取指定名称的代理实例。
78
+
79
+ 参数:
80
+ agent_name: 代理名称
81
+
82
+ 返回:
83
+ Any: 代理实例,如果不存在则返回None
84
+ """
85
+ return global_agents.get(agent_name)
86
+
87
+
69
88
  def set_agent(agent_name: str, agent: Any) -> None:
70
89
  """
71
90
  设置当前代理并将其添加到全局代理集合中。
@@ -74,7 +93,7 @@ def set_agent(agent_name: str, agent: Any) -> None:
74
93
  agent_name: 代理名称
75
94
  agent: 代理对象
76
95
  """
77
- global_agents.add(agent_name)
96
+ global_agents[agent_name] = agent
78
97
  global current_agent_name
79
98
  current_agent_name = agent_name
80
99
 
@@ -101,7 +120,7 @@ def delete_agent(agent_name: str) -> None:
101
120
  agent_name: 要删除的代理名称
102
121
  """
103
122
  if agent_name in global_agents:
104
- global_agents.remove(agent_name)
123
+ del global_agents[agent_name]
105
124
  global current_agent_name
106
125
  current_agent_name = ""
107
126
 
@@ -156,13 +175,18 @@ def get_interrupt() -> int:
156
175
 
157
176
  def set_last_message(message: str) -> None:
158
177
  """
159
- 设置最后一条消息。
178
+ 将消息添加到历史记录中。
160
179
 
161
180
  参数:
162
181
  message: 要保存的消息
163
182
  """
164
- global last_message
165
- last_message = message
183
+ global message_history
184
+ if message:
185
+ # 避免重复添加
186
+ if not message_history or message_history[-1] != message:
187
+ message_history.append(message)
188
+ if len(message_history) > MAX_HISTORY_SIZE:
189
+ message_history.pop(0)
166
190
 
167
191
 
168
192
  def get_last_message() -> str:
@@ -170,13 +194,146 @@ def get_last_message() -> str:
170
194
  获取最后一条消息。
171
195
 
172
196
  返回:
173
- str: 最后一条消息
197
+ str: 最后一条消息,如果历史记录为空则返回空字符串
174
198
  """
175
- return last_message
199
+ global message_history
200
+ if message_history:
201
+ return message_history[-1]
202
+ return ""
203
+
204
+
205
+ def get_message_history() -> List[str]:
176
206
  """
177
- 获取当前中断信号状态。
207
+ 获取完整的消息历史记录。
178
208
 
179
209
  返回:
180
- int: 当前中断计数
210
+ List[str]: 消息历史列表
181
211
  """
182
- return g_interrupt
212
+ global message_history
213
+ return message_history
214
+
215
+
216
+ def add_short_term_memory(memory_data: Dict[str, Any]) -> None:
217
+ """
218
+ 添加短期记忆到全局存储。
219
+
220
+ 参数:
221
+ memory_data: 包含记忆信息的字典
222
+ """
223
+ global short_term_memories
224
+ short_term_memories.append(memory_data)
225
+ # 如果超过最大数量,删除最旧的记忆
226
+ if len(short_term_memories) > MAX_SHORT_TERM_MEMORIES:
227
+ short_term_memories.pop(0)
228
+
229
+
230
+ def get_short_term_memories(tags: Optional[List[str]] = None) -> List[Dict[str, Any]]:
231
+ """
232
+ 获取短期记忆,可选择按标签过滤。
233
+
234
+ 参数:
235
+ tags: 用于过滤的标签列表(可选)
236
+
237
+ 返回:
238
+ List[Dict[str, Any]]: 符合条件的短期记忆列表,按创建时间降序排列
239
+ """
240
+ global short_term_memories
241
+
242
+ # 获取记忆副本
243
+ memories_copy = short_term_memories.copy()
244
+
245
+ # 按标签过滤(如果提供了标签)
246
+ if tags:
247
+ filtered_memories = []
248
+ for memory in memories_copy:
249
+ memory_tags = memory.get("tags", [])
250
+ if any(tag in memory_tags for tag in tags):
251
+ filtered_memories.append(memory)
252
+ memories_copy = filtered_memories
253
+
254
+ # 按创建时间排序(最新的在前)
255
+ memories_copy.sort(key=lambda x: x.get("created_at", ""), reverse=True)
256
+
257
+ return memories_copy
258
+
259
+
260
+ def clear_short_term_memories() -> None:
261
+ """
262
+ 清空所有短期记忆。
263
+ """
264
+ global short_term_memories
265
+ short_term_memories.clear()
266
+
267
+
268
+ def get_all_memory_tags() -> Dict[str, List[str]]:
269
+ """
270
+ 获取所有记忆类型中的标签集合。
271
+ 每个类型最多返回200个标签,超过时随机提取。
272
+
273
+ 返回:
274
+ Dict[str, List[str]]: 按记忆类型分组的标签列表
275
+ """
276
+ from pathlib import Path
277
+ import json
278
+ import random
279
+ from jarvis.jarvis_utils.config import get_data_dir
280
+
281
+ tags_by_type: Dict[str, List[str]] = {
282
+ "short_term": [],
283
+ "project_long_term": [],
284
+ "global_long_term": [],
285
+ }
286
+
287
+ MAX_TAGS_PER_TYPE = 200
288
+
289
+ # 获取短期记忆标签
290
+ short_term_tags = set()
291
+ for memory in short_term_memories:
292
+ short_term_tags.update(memory.get("tags", []))
293
+ short_term_tags_list = sorted(list(short_term_tags))
294
+ if len(short_term_tags_list) > MAX_TAGS_PER_TYPE:
295
+ tags_by_type["short_term"] = sorted(
296
+ random.sample(short_term_tags_list, MAX_TAGS_PER_TYPE)
297
+ )
298
+ else:
299
+ tags_by_type["short_term"] = short_term_tags_list
300
+
301
+ # 获取项目长期记忆标签
302
+ project_memory_dir = Path(".jarvis/memory")
303
+ if project_memory_dir.exists():
304
+ project_tags = set()
305
+ for memory_file in project_memory_dir.glob("*.json"):
306
+ try:
307
+ with open(memory_file, "r", encoding="utf-8") as f:
308
+ memory_data = json.load(f)
309
+ project_tags.update(memory_data.get("tags", []))
310
+ except Exception:
311
+ pass
312
+ project_tags_list = sorted(list(project_tags))
313
+ if len(project_tags_list) > MAX_TAGS_PER_TYPE:
314
+ tags_by_type["project_long_term"] = sorted(
315
+ random.sample(project_tags_list, MAX_TAGS_PER_TYPE)
316
+ )
317
+ else:
318
+ tags_by_type["project_long_term"] = project_tags_list
319
+
320
+ # 获取全局长期记忆标签
321
+ global_memory_dir = Path(get_data_dir()) / "memory" / "global_long_term"
322
+ if global_memory_dir.exists():
323
+ global_tags = set()
324
+ for memory_file in global_memory_dir.glob("*.json"):
325
+ try:
326
+ with open(memory_file, "r", encoding="utf-8") as f:
327
+ memory_data = json.load(f)
328
+ global_tags.update(memory_data.get("tags", []))
329
+ except Exception:
330
+ pass
331
+ global_tags_list = sorted(list(global_tags))
332
+ if len(global_tags_list) > MAX_TAGS_PER_TYPE:
333
+ tags_by_type["global_long_term"] = sorted(
334
+ random.sample(global_tags_list, MAX_TAGS_PER_TYPE)
335
+ )
336
+ else:
337
+ tags_by_type["global_long_term"] = global_tags_list
338
+
339
+ return tags_by_type
@@ -1,140 +1,120 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- import httpx
4
- from typing import Any, Dict, Optional, Union, AsyncGenerator, Generator
3
+ import requests # type: ignore[import-untyped]
4
+ from typing import Any, Dict, Optional, Generator
5
5
 
6
6
 
7
- def get_httpx_client() -> httpx.Client:
7
+ def get_requests_session() -> requests.Session:
8
8
  """
9
- 获取一个配置好的 httpx.Client 对象
9
+ 获取一个配置好的 requests.Session 对象
10
10
 
11
11
  返回:
12
- httpx.Client 对象
12
+ requests.Session 对象
13
13
  """
14
- client = httpx.Client(
15
- timeout=httpx.Timeout(None), # 永不超时
16
- headers={
14
+ session = requests.Session()
15
+ session.headers.update(
16
+ {
17
17
  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
18
- },
18
+ }
19
19
  )
20
- return client
20
+ return session
21
21
 
22
22
 
23
- def get_async_httpx_client() -> httpx.AsyncClient:
24
- """
25
- 获取一个配置好的 httpx.AsyncClient 对象
26
-
27
- 返回:
28
- httpx.AsyncClient 对象
29
- """
30
- client = httpx.AsyncClient(
31
- timeout=httpx.Timeout(None), # 永不超时
32
- headers={
33
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
34
- },
35
- )
36
- return client
37
-
38
-
39
- # 增强版本的 HTTP 请求方法(使用 httpx 实现,带重试机制,解决连接中断问题)
23
+ # 增强版本的 HTTP 请求方法(使用 requests 实现)
40
24
  def post(
41
25
  url: str,
42
26
  data: Optional[Any] = None,
43
27
  json: Optional[Dict[str, Any]] = None,
44
28
  **kwargs,
45
- ) -> httpx.Response:
29
+ ) -> requests.Response:
46
30
  """
47
- 发送增强版永不超时的 POST 请求,使用 httpx 实现,包含重试机制
31
+ 发送增强版永不超时的 POST 请求,使用 requests 实现
48
32
 
49
33
  参数:
50
34
  url: 请求的 URL
51
35
  data: (可选) 请求体数据 (表单数据或原始数据)
52
36
  json: (可选) JSON 数据,会自动设置 Content-Type
53
- **kwargs: 其他传递给 httpx.post 的参数
37
+ **kwargs: 其他传递给 requests.post 的参数
54
38
 
55
39
  返回:
56
- httpx.Response 对象
40
+ requests.Response 对象
57
41
 
58
42
  注意:
59
- 此方法使用 httpx 实现,包含自动重试机制,适用于解决"Response ended prematurely"等连接问题
43
+ 此方法使用 requests 实现。要实现重试,请考虑使用 Session 和 HTTPAdapter。
44
+ 永不超时通过 timeout=None 设置。
60
45
  """
61
- client = get_httpx_client()
62
- try:
63
- response = client.post(url=url, data=data, json=json, **kwargs)
46
+ kwargs.setdefault("timeout", None)
47
+ with get_requests_session() as session:
48
+ response = session.post(url=url, data=data, json=json, **kwargs)
64
49
  response.raise_for_status()
65
50
  return response
66
- finally:
67
- client.close()
68
51
 
69
52
 
70
- def get(url: str, **kwargs) -> httpx.Response:
53
+ def get(url: str, **kwargs) -> requests.Response:
71
54
  """
72
- 发送增强版永不超时的 GET 请求,使用 httpx 实现,包含重试机制
55
+ 发送增强版永不超时的 GET 请求,使用 requests 实现
73
56
 
74
57
  参数:
75
58
  url: 请求的 URL
76
- **kwargs: 其他传递给 httpx.get 的参数
59
+ **kwargs: 其他传递给 requests.get 的参数
77
60
 
78
61
  返回:
79
- httpx.Response 对象
62
+ requests.Response 对象
80
63
 
81
64
  注意:
82
- 此方法使用 httpx 实现,包含自动重试机制,适用于解决"Response ended prematurely"等连接问题
65
+ 此方法使用 requests 实现。
66
+ 永不超时通过 timeout=None 设置。
83
67
  """
84
- client = get_httpx_client()
85
- try:
86
- response = client.get(url=url, **kwargs)
68
+ kwargs.setdefault("timeout", None)
69
+ with get_requests_session() as session:
70
+ response = session.get(url=url, **kwargs)
87
71
  response.raise_for_status()
88
72
  return response
89
- finally:
90
- client.close()
91
73
 
92
74
 
93
- def put(url: str, data: Optional[Any] = None, **kwargs) -> httpx.Response:
75
+ def put(url: str, data: Optional[Any] = None, **kwargs) -> requests.Response:
94
76
  """
95
- 发送增强版永不超时的 PUT 请求,使用 httpx 实现,包含重试机制
77
+ 发送增强版永不超时的 PUT 请求,使用 requests 实现
96
78
 
97
79
  参数:
98
80
  url: 请求的 URL
99
81
  data: (可选) 请求体数据 (表单数据或原始数据)
100
- **kwargs: 其他传递给 httpx.put 的参数
82
+ **kwargs: 其他传递给 requests.put 的参数
101
83
 
102
84
  返回:
103
- httpx.Response 对象
85
+ requests.Response 对象
104
86
 
105
87
  注意:
106
- 此方法使用 httpx 实现,包含自动重试机制,适用于解决"Response ended prematurely"等连接问题
88
+ 此方法使用 requests 实现。
89
+ 永不超时通过 timeout=None 设置。
107
90
  """
108
- client = get_httpx_client()
109
- try:
110
- response = client.put(url=url, data=data, **kwargs)
91
+ kwargs.setdefault("timeout", None)
92
+ with get_requests_session() as session:
93
+ response = session.put(url=url, data=data, **kwargs)
111
94
  response.raise_for_status()
112
95
  return response
113
- finally:
114
- client.close()
115
96
 
116
97
 
117
- def delete(url: str, **kwargs) -> httpx.Response:
98
+ def delete(url: str, **kwargs) -> requests.Response:
118
99
  """
119
- 发送增强版永不超时的 DELETE 请求,使用 httpx 实现,包含重试机制
100
+ 发送增强版永不超时的 DELETE 请求,使用 requests 实现
120
101
 
121
102
  参数:
122
103
  url: 请求的 URL
123
- **kwargs: 其他传递给 httpx.delete 的参数
104
+ **kwargs: 其他传递给 requests.delete 的参数
124
105
 
125
106
  返回:
126
- httpx.Response 对象
107
+ requests.Response 对象
127
108
 
128
109
  注意:
129
- 此方法使用 httpx 实现,包含自动重试机制,适用于解决"Response ended prematurely"等连接问题
110
+ 此方法使用 requests 实现。
111
+ 永不超时通过 timeout=None 设置。
130
112
  """
131
- client = get_httpx_client()
132
- try:
133
- response = client.delete(url=url, **kwargs)
113
+ kwargs.setdefault("timeout", None)
114
+ with get_requests_session() as session:
115
+ response = session.delete(url=url, **kwargs)
134
116
  response.raise_for_status()
135
117
  return response
136
- finally:
137
- client.close()
138
118
 
139
119
 
140
120
  # 同步流式POST请求方法
@@ -143,27 +123,26 @@ def stream_post(
143
123
  data: Optional[Any] = None,
144
124
  json: Optional[Dict[str, Any]] = None,
145
125
  **kwargs,
146
- ) -> Generator[bytes, None, None]:
126
+ ) -> Generator[str, None, None]:
147
127
  """
148
- 发送流式 POST 请求,使用 httpx 实现,返回标准 Generator
128
+ 发送流式 POST 请求,使用 requests 实现,返回解码后的字符串行生成器
149
129
 
150
130
  参数:
151
131
  url: 请求的 URL
152
132
  data: (可选) 请求体数据 (表单数据或原始数据)
153
133
  json: (可选) JSON 数据,会自动设置 Content-Type
154
- **kwargs: 其他传递给 httpx.post 的参数
134
+ **kwargs: 其他传递给 requests.post 的参数
155
135
 
156
136
  返回:
157
- Generator[bytes, None, None]: 字节流生成器
137
+ Generator[str, None, None]: 字符串行生成器
158
138
 
159
139
  注意:
160
- 此方法使用 httpx 实现流式请求,适用于处理大文件下载或流式响应
140
+ 此方法使用 requests 实现流式请求,适用于处理大文件下载或流式响应
161
141
  """
162
- client = get_httpx_client()
163
- try:
164
- with client.stream("POST", url, data=data, json=json, **kwargs) as response:
142
+ kwargs.setdefault("timeout", None)
143
+ with get_requests_session() as session:
144
+ with session.post(url, data=data, json=json, stream=True, **kwargs) as response:
165
145
  response.raise_for_status()
166
- for chunk in response.iter_bytes():
167
- yield chunk
168
- finally:
169
- client.close()
146
+ for line in response.iter_lines(chunk_size=1):
147
+ if line:
148
+ yield line.decode("utf-8", errors="ignore")