beswarm 0.2.47__py3-none-any.whl → 0.2.49__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 beswarm might be problematic. Click here for more details.

beswarm/agents/planact.py CHANGED
@@ -48,7 +48,6 @@ class BaseAgent:
48
48
  """Handle graph update messages."""
49
49
  if message.get("message") == "graph_updated":
50
50
  self.graph_tree = message.get("graph")
51
- print("handle_graph_update self.graph_tree", self.graph_tree)
52
51
 
53
52
  def dispose(self):
54
53
  """Cancels the subscription and cleans up resources."""
@@ -200,7 +199,6 @@ class WorkerAgent(BaseAgent):
200
199
  and "<knowledge_graph_tree>" in raw_message["content"] and self.graph_tree:
201
200
  raw_message["content"] = replace_xml_content(raw_message["content"], "knowledge_graph_tree", self.graph_tree)
202
201
  self.agent.conversation["default"][index] = raw_message
203
- print("self.agent.conversation['default'][index]", self.agent.conversation["default"][index])
204
202
 
205
203
  instruction = message["instruction"]
206
204
  if "find_and_click_element" in json.dumps(self.tools_json):
@@ -48,7 +48,7 @@ class KnowledgeGraphManager:
48
48
  def _create_new_graph(self):
49
49
  """创建一个带有根节点的新图谱并保存。"""
50
50
  self.graph = nx.DiGraph()
51
- self.graph.add_node("root", name=".", description="知识图谱根节点")
51
+ self.graph.add_node("root", name=".", description="知识图谱根节点", tags="")
52
52
  self._save_graph()
53
53
 
54
54
  def set_publish_topic(self, publish_topic):
@@ -102,7 +102,7 @@ class KnowledgeGraphManager:
102
102
 
103
103
  return current_node_id
104
104
 
105
- def add_node(self, parent_path: str, node_name: str, description: str = "") -> str:
105
+ def add_node(self, parent_path: str, node_name: str, description: str = "", tags: list[str] = None) -> str:
106
106
  """在指定父节点下添加一个新节点。"""
107
107
  if not node_name.strip():
108
108
  return "❌ 错误:节点名称不能为空。"
@@ -118,11 +118,55 @@ class KnowledgeGraphManager:
118
118
  return f"❌ 错误:在 '{parent_path}' 下已存在名为 '{node_name}' 的节点。"
119
119
 
120
120
  new_node_id = str(uuid.uuid4())
121
- self.graph.add_node(new_node_id, name=node_name, description=description)
121
+ # 将标签列表转换为内部存储的字符串格式
122
+ tags_str = ",".join(sorted(list(set(filter(None, tags or [])))))
123
+ self.graph.add_node(new_node_id, name=node_name, description=description, tags=tags_str)
122
124
  self.graph.add_edge(parent_id, new_node_id)
123
125
  self._save_graph()
124
126
  return f"✅ 成功在 '{parent_path}' 下添加节点 '{node_name}'。"
125
127
 
128
+ def _get_tags(self, node_id: str) -> list[str]:
129
+ """获取节点的标签列表。"""
130
+ tags_str = self.graph.nodes[node_id].get('tags', '')
131
+ return tags_str.split(',') if tags_str else []
132
+
133
+ def _set_tags(self, node_id: str, tags: list[str]):
134
+ """设置节点的标签列表。"""
135
+ # 移除重复项并排序
136
+ unique_tags = sorted(list(set(filter(None, tags))))
137
+ self.graph.nodes[node_id]['tags'] = ",".join(unique_tags)
138
+
139
+ def add_tags_to_node(self, node_path: str, tags_to_add: list[str]) -> str:
140
+ """向指定节点添加一个或多个标签。"""
141
+ node_id = self._get_node_id_by_path(node_path)
142
+ if node_id is None:
143
+ return f"❌ 错误:路径 '{node_path}' 不存在。"
144
+
145
+ current_tags = self._get_tags(node_id)
146
+ current_tags.extend(tags_to_add)
147
+ self._set_tags(node_id, current_tags)
148
+ self._save_graph()
149
+ return f"✅ 成功向节点 '{node_path}' 添加标签: {' '.join([f'#{t}' for t in tags_to_add])}"
150
+
151
+ def remove_tags_from_node(self, node_path: str, tags_to_remove: list[str]) -> str:
152
+ """从指定节点移除一个或多个标签。"""
153
+ node_id = self._get_node_id_by_path(node_path)
154
+ if node_id is None:
155
+ return f"❌ 错误:路径 '{node_path}' 不存在。"
156
+
157
+ current_tags = self._get_tags(node_id)
158
+ if not current_tags:
159
+ return f"ℹ️ 节点 '{node_path}' 没有任何标签可供移除。"
160
+
161
+ new_tags = [tag for tag in current_tags if tag not in tags_to_remove]
162
+
163
+ if len(new_tags) == len(current_tags):
164
+ return f"ℹ️ 在节点 '{node_path}' 上未找到指定的标签: {' '.join([f'#{t}' for t in tags_to_remove])}"
165
+
166
+ self._set_tags(node_id, new_tags)
167
+ self._save_graph()
168
+ return f"✅ 成功从节点 '{node_path}' 移除标签。"
169
+
126
170
  def delete_node(self, node_path: str) -> str:
127
171
  """删除一个节点及其所有子孙节点。"""
128
172
  if node_path is None or node_path.strip() in ['.', '/']:
@@ -187,6 +231,29 @@ class KnowledgeGraphManager:
187
231
  self._save_graph()
188
232
  return f"✅ 成功将节点 '{source_path}' 移动到 '{target_parent_path}' 下。"
189
233
 
234
+ def get_node_details(self, node_path: str) -> str:
235
+ """获取指定路径节点的所有详细信息。"""
236
+ node_id = self._get_node_id_by_path(node_path)
237
+ if node_id is None:
238
+ return f"❌ 错误:路径 '{node_path}' 不存在。"
239
+
240
+ node_data = self.graph.nodes[node_id]
241
+ description = node_data.get('description', '无描述。')
242
+ tags = self._get_tags(node_id)
243
+
244
+ # 路径就用用户输入的,因为这才是用户识别它的方式
245
+ details = [f"节点: {node_path}"]
246
+ details.append(f"描述: {description}")
247
+
248
+ if tags:
249
+ # 格式化标签为 '#技术细节, #激活函数'
250
+ formatted_tags = " ".join([f"#{t}" for t in tags])
251
+ details.append(f"标签: {formatted_tags}")
252
+ else:
253
+ details.append("标签: 无")
254
+
255
+ return "\n".join(details)
256
+
190
257
  def render_tree(self) -> str:
191
258
  """渲染整个知识图谱为树状结构的文本。"""
192
259
  if not self.graph or "root" not in self.graph:
@@ -204,6 +271,13 @@ class KnowledgeGraphManager:
204
271
  is_last = (i == len(children) - 1)
205
272
  connector = "└── " if is_last else "├── "
206
273
  node_name = self.graph.nodes[child_id].get('name', '[Unnamed Node]')
274
+
275
+ # 显示标签,过滤掉以'source'开头的标签
276
+ tags = self._get_tags(child_id)
277
+ display_tags = [t for t in tags if not t.startswith('source')]
278
+ if display_tags:
279
+ node_name += f" {' '.join([f'#{t}' for t in display_tags])}"
280
+
207
281
  tree_lines.append(f"{prefix}{connector}{node_name}")
208
282
  new_prefix = prefix + " " if is_last else prefix + "│ "
209
- self._build_tree_string_recursive(child_id, new_prefix, tree_lines)
283
+ self._build_tree_string_recursive(child_id, new_prefix, tree_lines)
beswarm/tools/__init__.py CHANGED
@@ -4,7 +4,16 @@ from .completion import task_complete
4
4
  from .search_arxiv import search_arxiv
5
5
  from .repomap import get_code_repo_map
6
6
  from .write_csv import append_row_to_csv
7
- from .graph import add_knowledge_node, delete_knowledge_node, rename_knowledge_node, move_knowledge_node, get_knowledge_graph_tree
7
+ from .graph import (
8
+ get_node_details,
9
+ add_knowledge_node,
10
+ delete_knowledge_node,
11
+ rename_knowledge_node,
12
+ move_knowledge_node,
13
+ get_knowledge_graph_tree,
14
+ add_tags_to_knowledge_node,
15
+ remove_tags_from_knowledge_node,
16
+ )
8
17
  from .request_input import request_admin_input
9
18
  from .screenshot import save_screenshot_to_file
10
19
  from .worker import worker, worker_gen, chatgroup
@@ -49,11 +58,14 @@ __all__ = [
49
58
  "list_directory",
50
59
  "get_task_result",
51
60
  "get_url_content",
61
+ "get_node_details",
52
62
  "add_knowledge_node",
53
63
  "move_knowledge_node",
54
64
  "delete_knowledge_node",
55
65
  "rename_knowledge_node",
56
66
  "get_knowledge_graph_tree",
67
+ "add_tags_to_knowledge_node",
68
+ "remove_tags_from_knowledge_node",
57
69
  "append_row_to_csv",
58
70
  "set_readonly_path",
59
71
  "get_code_repo_map",
beswarm/tools/graph.py CHANGED
@@ -1,8 +1,11 @@
1
- from ..aient.src.aient.plugins import register_tool
1
+ import ast
2
+ from typing import List
3
+
2
4
  from ..core import kgm
5
+ from ..aient.src.aient.plugins import register_tool
3
6
 
4
7
  @register_tool()
5
- def add_knowledge_node(parent_path: str, node_name: str, description: str = "") -> str:
8
+ def add_knowledge_node(parent_path: str, node_name: str, description: str = "", tags: List[str] = None) -> str:
6
9
  """
7
10
  在知识图谱的指定父路径下添加一个新节点。
8
11
 
@@ -10,11 +13,64 @@ def add_knowledge_node(parent_path: str, node_name: str, description: str = "")
10
13
  parent_path (str): 父节点的路径。路径由'/'分隔,例如 'a/b'。根节点路径为 '.' 或 '/'。
11
14
  node_name (str): 新节点的名称。名称中不能包含'/'字符。
12
15
  description (str, optional): 节点的可选描述信息。默认为空字符串。
16
+ tags (List[str], optional): 节点的标签列表。默认为 None。
13
17
 
14
18
  Returns:
15
19
  str: 操作结果的描述信息,例如成功或失败的原因。
16
20
  """
17
- return kgm.add_node(parent_path, node_name, description)
21
+ if tags:
22
+ if "[" not in tags:
23
+ if "," not in tags:
24
+ tags = f"['{tags}']"
25
+ else:
26
+ tags = f"{tags.split(',')}"
27
+ tags = ast.literal_eval(tags) if isinstance(tags, str) else tags
28
+ tags = [tag.strip().lstrip("#") for tag in tags]
29
+ return kgm.add_node(parent_path, node_name, description, tags)
30
+
31
+ @register_tool()
32
+ def add_tags_to_knowledge_node(node_path: str, tags: List[str]) -> str:
33
+ """
34
+ 向知识图谱中的指定节点添加一个或多个标签。
35
+
36
+ Args:
37
+ node_path (str): 要添加标签的节点的完整路径。
38
+ tags (List[str]): 要添加的标签列表。
39
+
40
+ Returns:
41
+ str: 操作结果的描述信息。
42
+ """
43
+ if "[" not in tags:
44
+ if "," not in tags:
45
+ tags = f"['{tags}']"
46
+ else:
47
+ tags = f"{tags.split(',')}"
48
+
49
+ tags = ast.literal_eval(tags) if isinstance(tags, str) else tags
50
+ tags = [tag.strip().lstrip("#") for tag in tags]
51
+ return kgm.add_tags_to_node(node_path, tags)
52
+
53
+ @register_tool()
54
+ def remove_tags_from_knowledge_node(node_path: str, tags: List[str]) -> str:
55
+ """
56
+ 从知识图谱中的指定节点移除一个或多个标签。
57
+
58
+ Args:
59
+ node_path (str): 要移除标签的节点的完整路径。
60
+ tags (List[str]): 要移除的标签列表。
61
+
62
+ Returns:
63
+ str: 操作结果的描述信息。
64
+ """
65
+ if "[" not in tags:
66
+ if "," not in tags:
67
+ tags = f"['{tags}']"
68
+ else:
69
+ tags = f"{tags.split(',')}"
70
+
71
+ tags = ast.literal_eval(tags) if isinstance(tags, str) else tags
72
+ tags = [tag.strip().lstrip("#") for tag in tags]
73
+ return kgm.remove_tags_from_node(node_path, tags)
18
74
 
19
75
  @register_tool()
20
76
  def delete_knowledge_node(node_path: str) -> str:
@@ -71,3 +127,19 @@ def get_knowledge_graph_tree() -> str:
71
127
  str: 表示整个知识图谱的、格式化的树状结构字符串。
72
128
  """
73
129
  return "<knowledge_graph_tree>" + kgm.render_tree() + "</knowledge_graph_tree>"
130
+
131
+ @register_tool()
132
+ def get_node_details(node_path: str) -> str:
133
+ """
134
+ 获取知识图谱中指定路径节点的所有详细信息。可以显示 get_knowledge_graph_tree 隐藏的信息。
135
+
136
+ 这个工具用于深入查看单个节点的具体内容,包括其描述和所有标签。
137
+ 它与 `get_knowledge_graph_tree`(提供全局视图)互补。
138
+
139
+ Args:
140
+ node_path (str): 要查询的节点的完整路径。
141
+
142
+ Returns:
143
+ str: 包含节点详细信息的、格式化的文本字符串。
144
+ """
145
+ return kgm.get_node_details(node_path)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: beswarm
3
- Version: 0.2.47
3
+ Version: 0.2.49
4
4
  Summary: MAS
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -1,12 +1,12 @@
1
1
  beswarm/__init__.py,sha256=HZjUOJtZR5QhMuDbq-wukQQn1VrBusNWai_ysGo-VVI,20
2
2
  beswarm/broker.py,sha256=64Y-djrKYaZfBQ8obwHOmr921QgZeu9BtScZWaYLfDo,9887
3
3
  beswarm/core.py,sha256=htssaaeIBZ_yOqvX9VtANoVWaZHt_7oWcxyDI1z0paQ,310
4
- beswarm/knowledge_graph.py,sha256=Q2hhXL2RXnAM8vvxstYetch5wX7ghTM5S7FnORSxCG0,9205
4
+ beswarm/knowledge_graph.py,sha256=uBZ31StYrfEtFTj5EtrBNGYE0cPqacegtIc_mmtFSrw,12469
5
5
  beswarm/prompt.py,sha256=n0a1a6NThIxAYSkisg1sEKjvz2w0tozpKL4BIplaAkI,32286
6
6
  beswarm/taskmanager.py,sha256=xczsnehCaOAI3SRE8wUxhzmt6i6G7ynndSWS_bAZn3k,12192
7
7
  beswarm/utils.py,sha256=S9jEtht0hTZbjZ2Hk24p4Ip41R69BogOkYS6fgPKY2Y,8219
8
8
  beswarm/agents/chatgroup.py,sha256=YHofra9kE0x7UrhqZjlP7PbWvinEew1BkjJ0XilzudM,12020
9
- beswarm/agents/planact.py,sha256=K0ttCRncqmEJIaSzq9zfnq9cpYAz8XAmgS0r9COmNIw,19752
9
+ beswarm/agents/planact.py,sha256=-JPN8L1JgVjy4G36eUHZHyLiBrN5oI8fLTbpweZsUuU,19568
10
10
  beswarm/aient/main.py,sha256=SiYAIgQlLJqYusnTVEJOx1WNkSJKMImhgn5aWjfroxg,3814
11
11
  beswarm/aient/setup.py,sha256=Mq1M05mT9_UYBK2jk5mP_sLxKQAolcuh8PYXexfj-XU,487
12
12
  beswarm/aient/src/aient/__init__.py,sha256=SRfF7oDVlOOAi6nGKiJIUK6B_arqYLO9iSMp-2IZZps,21
@@ -131,11 +131,11 @@ beswarm/queries/tree-sitter-languages/ruby-tags.scm,sha256=vIidsCeE2A0vdFN18yXKq
131
131
  beswarm/queries/tree-sitter-languages/rust-tags.scm,sha256=9ljM1nzhfPs_ZTRw7cr2P9ToOyhGcKkCoN4_HPXSWi4,1451
132
132
  beswarm/queries/tree-sitter-languages/scala-tags.scm,sha256=UxQjz80JIrrJ7Pm56uUnQyThfmQNvwk7aQzPNypB-Ao,1761
133
133
  beswarm/queries/tree-sitter-languages/typescript-tags.scm,sha256=OMdCeedPiA24ky82DpgTMKXK_l2ySTuF2zrQ2fJAi9E,1253
134
- beswarm/tools/__init__.py,sha256=fhJSEaYcfgMTW_nzUqQiyX5RLBhE-gxs8u4PpFquOdg,1868
134
+ beswarm/tools/__init__.py,sha256=5ZJeCEau1OVVOVBMv5E0DTGERsgknSxSLX8o4B1WR8k,2081
135
135
  beswarm/tools/click.py,sha256=7g6x1X7ffTInGWp7112KS-MAQ5-8wa1Ze2sIipUIbjc,20884
136
136
  beswarm/tools/completion.py,sha256=wHEJrdzjuTKQNQZhelSuPnK2YRsGbeUqZ0P6IgT3c10,605
137
137
  beswarm/tools/edit_file.py,sha256=iwWl7a8sTVq4vj0e1ny3H6UGcHfYnxALRGcLuk5hZS8,9155
138
- beswarm/tools/graph.py,sha256=-Lyhi-AsJNKQ5p9BJk6mzARd1-IDhdLyKmNAVN5PdUE,2703
138
+ beswarm/tools/graph.py,sha256=f0OmaB1UI9rdYU5KNxOUINPBvXhLo5pdznrCKNpQ3nM,5088
139
139
  beswarm/tools/planner.py,sha256=lguBCS6kpwNPoXQvqH-WySabVubT82iyWOkJnjt6dXw,1265
140
140
  beswarm/tools/repomap.py,sha256=YsTPq5MXfn_Ds5begcvHDnY_Xp2d4jH-xmWqNMHnNHY,45239
141
141
  beswarm/tools/request_input.py,sha256=gXNAJPOJektMqxJVyzNTFOeMQ7xUkO-wWMYH-r2Rdwk,942
@@ -145,7 +145,7 @@ beswarm/tools/search_web.py,sha256=LhgXOSHL9fwxg5T2AAOV4TTJkcJVLogsfRJW2faPvDE,1
145
145
  beswarm/tools/subtasks.py,sha256=zZmRCjDocbvrU8MvZvpDWpQCKNntDJ123ByBiS8pRko,9889
146
146
  beswarm/tools/worker.py,sha256=-tcLGrdLPZYxc1z66iQIB1VH7RWcR-5CgVWuDIQJBCQ,2013
147
147
  beswarm/tools/write_csv.py,sha256=-r5OghcvjCg00hY0YQbp6u31VIJLrgaqDIvczAFoqDE,1470
148
- beswarm-0.2.47.dist-info/METADATA,sha256=lhUB9qvkDusaKxyM9jvZVx2WRo107Ir_yq-qfjmEKbE,3878
149
- beswarm-0.2.47.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
150
- beswarm-0.2.47.dist-info/top_level.txt,sha256=pJw4O87wvt5882smuSO6DfByJz7FJ8SxxT8h9fHCmpo,8
151
- beswarm-0.2.47.dist-info/RECORD,,
148
+ beswarm-0.2.49.dist-info/METADATA,sha256=Pcb-9zbBrpVN7XbtvppUsAWIpd1jJlZ1NZgi9wu6tAQ,3878
149
+ beswarm-0.2.49.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
150
+ beswarm-0.2.49.dist-info/top_level.txt,sha256=pJw4O87wvt5882smuSO6DfByJz7FJ8SxxT8h9fHCmpo,8
151
+ beswarm-0.2.49.dist-info/RECORD,,