jarvis-ai-assistant 0.1.55__py3-none-any.whl → 0.1.56__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 CHANGED
@@ -1,3 +1,3 @@
1
1
  """Jarvis AI Assistant"""
2
2
 
3
- __version__ = "0.1.55"
3
+ __version__ = "0.1.56"
@@ -0,0 +1,38 @@
1
+ from playwright.sync_api import sync_playwright
2
+ from urllib.parse import quote
3
+
4
+ def bing_search(query):
5
+ try:
6
+ with sync_playwright() as p:
7
+ browser = p.chromium.launch()
8
+ page = browser.new_page()
9
+ page.goto(
10
+ f"https://www.bing.com/search?form=QBRE&q={quote(query)}&cc=US"
11
+ )
12
+
13
+ page.wait_for_selector("#b_results", timeout=10000)
14
+
15
+ summaries = page.evaluate("""() => {
16
+ const liElements = Array.from(
17
+ document.querySelectorAll("#b_results > .b_algo")
18
+ );
19
+ return liElements.map((li) => {
20
+ const abstractElement = li.querySelector(".b_caption > p");
21
+ const linkElement = li.querySelector("a");
22
+ const href = linkElement.getAttribute("href");
23
+ const title = linkElement.textContent;
24
+ const abstract = abstractElement ? abstractElement.textContent : "";
25
+ return { href, title, abstract };
26
+ });
27
+ }""")
28
+
29
+ browser.close()
30
+ print(summaries)
31
+ return summaries
32
+ except Exception as error:
33
+ print("An error occurred:", error)
34
+
35
+ if __name__ == "__main__":
36
+ # results = bing_search("北京到西雅图的距离")
37
+ results = bing_search("北京到西雅图的距离")
38
+ print(results)
jarvis/tools/registry.py CHANGED
@@ -101,6 +101,7 @@ class ToolRegistry:
101
101
  )
102
102
  PrettyOutput.print(f"从 {file_path} 加载工具: {tool_instance.name}: {tool_instance.description}", OutputType.INFO)
103
103
  tool_found = True
104
+ break
104
105
 
105
106
  if not tool_found:
106
107
  PrettyOutput.print(f"文件中未找到有效的工具类: {file_path}", OutputType.WARNING)
jarvis/tools/search.py ADDED
@@ -0,0 +1,129 @@
1
+ from typing import Dict, Any, List
2
+ from jarvis.models.registry import PlatformRegistry
3
+ from jarvis.utils import PrettyOutput, OutputType
4
+ from jarvis.tools.webpage import WebpageTool
5
+ from jarvis.tools.bing_search import bing_search
6
+
7
+ class SearchTool:
8
+ name = "search"
9
+ description = "使用Bing搜索引擎搜索信息,并根据问题提取关键信息"
10
+ parameters = {
11
+ "type": "object",
12
+ "properties": {
13
+ "query": {
14
+ "type": "string",
15
+ "description": "搜索关键词"
16
+ },
17
+ "question": {
18
+ "type": "string",
19
+ "description": "需要回答的具体问题,用于从搜索结果中提取相关信息"
20
+ },
21
+ "max_results": {
22
+ "type": "integer",
23
+ "description": "最大搜索结果数量",
24
+ "default": 3
25
+ }
26
+ },
27
+ "required": ["query", "question"]
28
+ }
29
+
30
+ def __init__(self):
31
+ """初始化搜索工具,需要传入语言模型用于信息提取"""
32
+ self.model = PlatformRegistry.get_global_platform_registry().get_global_platform()
33
+ self.webpage_tool = WebpageTool()
34
+
35
+ def _search(self, query: str, max_results: int) -> List[Dict]:
36
+ """执行搜索请求"""
37
+ try:
38
+ results = bing_search(query)
39
+ if not results:
40
+ return []
41
+
42
+ # 格式化搜索结果
43
+ formatted_results = []
44
+ for result in results[:max_results]:
45
+ formatted_results.append({
46
+ "title": result.get("title", ""),
47
+ "href": result.get("href", ""),
48
+ "body": result.get("abstract", "")
49
+ })
50
+ return formatted_results
51
+ except Exception as e:
52
+ PrettyOutput.print(f"搜索请求失败: {str(e)}", OutputType.ERROR)
53
+ return []
54
+
55
+ def _extract_info(self, contents: List[str], question: str) -> str:
56
+ """使用语言模型从网页内容中提取关键信息"""
57
+ prompt = f"""请根据以下搜索结果内容,回答问题:{question}
58
+
59
+ 搜索结果内容:
60
+ {'-' * 40}
61
+ {''.join(contents)}
62
+ {'-' * 40}
63
+
64
+ 请提供一个简洁、准确的答案,重点关注与问题直接相关的信息。如果搜索结果中没有相关信息,请明确说明。
65
+ 回答时注意:
66
+ 1. 保持客观性,只基于搜索结果提供信息
67
+ 2. 如果不同来源有冲突,请指出差异
68
+ 3. 适当引用信息来源
69
+ 4. 如果信息不完整或不确定,请说明"""
70
+
71
+ try:
72
+ response = self.model.chat(prompt)
73
+ return response
74
+ except Exception as e:
75
+ return f"信息提取失败: {str(e)}"
76
+
77
+ def execute(self, args: Dict) -> Dict[str, Any]:
78
+ """执行搜索并提取信息"""
79
+ try:
80
+ query = args["query"]
81
+ question = args["question"]
82
+ max_results = args.get("max_results", 3)
83
+
84
+ # 打印搜索信息
85
+ PrettyOutput.print(f"搜索查询: {query}", OutputType.INFO)
86
+ PrettyOutput.print(f"相关问题: {question}", OutputType.INFO)
87
+
88
+ # 获取搜索结果
89
+ results = self._search(query, max_results)
90
+ if not results:
91
+ return {
92
+ "success": False,
93
+ "error": "未能获取任何搜索结果"
94
+ }
95
+
96
+ # 收集网页内容
97
+ contents = []
98
+ for i, result in enumerate(results, 1):
99
+ try:
100
+ PrettyOutput.print(f"正在读取第 {i}/{len(results)} 个结果... {result['title']} - {result['href']}", OutputType.PROGRESS)
101
+ webpage_result = self.webpage_tool.execute({"url": result["href"]})
102
+ if webpage_result["success"]:
103
+ contents.append(f"\n来源 {i}:{result['href']}\n")
104
+ contents.append(webpage_result["stdout"])
105
+ except Exception as e:
106
+ PrettyOutput.print(f"读取结果 {i} 失败: {str(e)}", OutputType.WARNING)
107
+ continue
108
+
109
+ if not contents:
110
+ return {
111
+ "success": False,
112
+ "error": "未能获取任何有效的搜索结果"
113
+ }
114
+
115
+ # 提取信息
116
+ PrettyOutput.print("正在分析搜索结果...", OutputType.PROGRESS)
117
+ analysis = self._extract_info(contents, question)
118
+
119
+ return {
120
+ "success": True,
121
+ "stdout": f"搜索分析结果:\n\n{analysis}",
122
+ "stderr": ""
123
+ }
124
+
125
+ except Exception as e:
126
+ return {
127
+ "success": False,
128
+ "error": f"搜索失败: {str(e)}"
129
+ }
@@ -0,0 +1,76 @@
1
+ from typing import Dict, Any
2
+ import requests
3
+ from bs4 import BeautifulSoup
4
+ from jarvis.utils import PrettyOutput, OutputType
5
+
6
+ class WebpageTool:
7
+ name = "read_webpage"
8
+ description = "读取网页内容,提取标题和正文文本"
9
+ parameters = {
10
+ "type": "object",
11
+ "properties": {
12
+ "url": {
13
+ "type": "string",
14
+ "description": "需要读取的网页URL"
15
+ }
16
+ },
17
+ "required": ["url"]
18
+ }
19
+
20
+ def execute(self, args: Dict) -> Dict[str, Any]:
21
+ """读取网页内容"""
22
+ try:
23
+ url = args["url"]
24
+
25
+ # 设置请求头
26
+ headers = {
27
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
28
+ }
29
+
30
+ # 发送请求
31
+ PrettyOutput.print(f"正在读取网页: {url}", OutputType.INFO)
32
+ response = requests.get(url, headers=headers, timeout=10)
33
+ response.raise_for_status()
34
+
35
+ # 使用正确的编码
36
+ response.encoding = response.apparent_encoding
37
+
38
+ # 解析HTML
39
+ soup = BeautifulSoup(response.text, 'html.parser')
40
+
41
+ # 移除script和style标签
42
+ for script in soup(["script", "style"]):
43
+ script.decompose()
44
+
45
+ # 提取标题
46
+ title = soup.title.string if soup.title else ""
47
+ title = title.strip() if title else "无标题"
48
+
49
+ # 提取正文
50
+ text = soup.get_text(separator='\n', strip=True)
51
+ lines = [line.strip() for line in text.splitlines() if line.strip()]
52
+
53
+ # 构建输出
54
+ output = [
55
+ f"标题: {title}",
56
+ "",
57
+ "正文内容:",
58
+ "\n".join(lines)
59
+ ]
60
+
61
+ return {
62
+ "success": True,
63
+ "stdout": "\n".join(output),
64
+ "stderr": ""
65
+ }
66
+
67
+ except requests.RequestException as e:
68
+ return {
69
+ "success": False,
70
+ "error": f"网页请求失败: {str(e)}"
71
+ }
72
+ except Exception as e:
73
+ return {
74
+ "success": False,
75
+ "error": f"解析网页失败: {str(e)}"
76
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.55
3
+ Version: 0.1.56
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
@@ -43,6 +43,7 @@ Requires-Dist: pyyaml>=5.1
43
43
  Requires-Dist: colorama>=0.4.6
44
44
  Requires-Dist: prompt_toolkit>=3.0.0
45
45
  Requires-Dist: openai>=1.20.0
46
+ Requires-Dist: playwright>=1.41.1
46
47
  Provides-Extra: dev
47
48
  Requires-Dist: pytest; extra == "dev"
48
49
  Requires-Dist: black; extra == "dev"
@@ -1,4 +1,4 @@
1
- jarvis/__init__.py,sha256=TgQTdVOK-cueqCWiQsECrUAQWOxTSqYI1Iu7YTFBom8,50
1
+ jarvis/__init__.py,sha256=vS32islhec3FUi9M3w_YYwFmgxraLbtdULP2nR3_c68,50
2
2
  jarvis/agent.py,sha256=s8VebNef8BbKM6D9IDWWN-XenEXEL9KoYnDLGKyZY58,12347
3
3
  jarvis/main.py,sha256=gXXtnrkkvGwEswJL6qiYjVrg3bpzye-GJeAe0Nf2B9o,6509
4
4
  jarvis/utils.py,sha256=JlkuC9RtspXH2VWDmj9nR0vnb8ie1gIsKc4vC7WRco8,7321
@@ -12,15 +12,18 @@ jarvis/models/oyi.py,sha256=VwPW4UawGrMrDOCIbSs9ieNlE6N0pBtgiroyg9JCJ48,15004
12
12
  jarvis/models/registry.py,sha256=iVBjN9ImEvGHcz8WR-z8pPMJQZI907o_nccVOFANhak,7951
13
13
  jarvis/tools/__init__.py,sha256=Kj1bKj34lwRDKMKHLOrLyQElf2lHbqA2tDgP359eaDo,71
14
14
  jarvis/tools/base.py,sha256=EGRGbdfbLXDLwtyoWdvp9rlxNX7bzc20t0Vc2VkwIEY,652
15
+ jarvis/tools/bing_search.py,sha256=SvYeXM83eP9qREDcWguh0_r0m0npbcwXIyzEwwfreKU,1444
15
16
  jarvis/tools/file_ops.py,sha256=h8g0eT9UvlJf4kt0DLXvdSsjcPj7x19lxWdDApeDfpg,3842
16
17
  jarvis/tools/generator.py,sha256=vVP3eN5cCDpRXf_fn0skETkPXAW1XZFWx9pt2_ahK48,5999
17
18
  jarvis/tools/methodology.py,sha256=G3cOaHTMujGZBhDLhQEqyCV2NISizO3MXRuho1KfI6Y,5223
18
- jarvis/tools/registry.py,sha256=NbH7A4A2lyN2IoyZGFwa5Ghed2dpzbJWCAd1Dg95WBI,7183
19
+ jarvis/tools/registry.py,sha256=mlOAmUq3yzRz-7yvwrrCwbe5Lmw8eh1v8-_Fa5sezwI,7209
20
+ jarvis/tools/search.py,sha256=o7EJqEtKKDqlENkXhxDuDA73djzeEH9j4BB0n61egso,4899
19
21
  jarvis/tools/shell.py,sha256=UPKshPyOaUwTngresUw-ot1jHjQIb4wCY5nkJqa38lU,2520
20
22
  jarvis/tools/sub_agent.py,sha256=rEtAmSVY2ZjFOZEKr5m5wpACOQIiM9Zr_3dT92FhXYU,2621
21
- jarvis_ai_assistant-0.1.55.dist-info/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
22
- jarvis_ai_assistant-0.1.55.dist-info/METADATA,sha256=LTOhw_m-9kM2VF5j4rnF3sy1T8rV89BB6eRI9ulKIlY,10015
23
- jarvis_ai_assistant-0.1.55.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
24
- jarvis_ai_assistant-0.1.55.dist-info/entry_points.txt,sha256=xDf1Kjt0cr1GrASlrV1iuiMWMkAV6i-jUbcfKasR0os,89
25
- jarvis_ai_assistant-0.1.55.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
26
- jarvis_ai_assistant-0.1.55.dist-info/RECORD,,
23
+ jarvis/tools/webpage.py,sha256=d3w3Jcjcu1ESciezTkz3n3Zf-rp_l91PrVoDEZnckOo,2391
24
+ jarvis_ai_assistant-0.1.56.dist-info/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
25
+ jarvis_ai_assistant-0.1.56.dist-info/METADATA,sha256=77TKsWx_GKBmYymF7IowtGuVbe6kYcEwO5cqAnjSyTw,10049
26
+ jarvis_ai_assistant-0.1.56.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
27
+ jarvis_ai_assistant-0.1.56.dist-info/entry_points.txt,sha256=xDf1Kjt0cr1GrASlrV1iuiMWMkAV6i-jUbcfKasR0os,89
28
+ jarvis_ai_assistant-0.1.56.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
29
+ jarvis_ai_assistant-0.1.56.dist-info/RECORD,,