beswarm 0.2.48__tar.gz → 0.2.50__tar.gz
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-0.2.48 → beswarm-0.2.50}/PKG-INFO +1 -1
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/knowledge_graph.py +91 -4
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/tools/__init__.py +13 -1
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/tools/graph.py +75 -3
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm.egg-info/PKG-INFO +1 -1
- {beswarm-0.2.48 → beswarm-0.2.50}/pyproject.toml +1 -1
- {beswarm-0.2.48 → beswarm-0.2.50}/test/test_graph.py +86 -10
- {beswarm-0.2.48 → beswarm-0.2.50}/MANIFEST.in +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/README.md +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/__init__.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/agents/chatgroup.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/agents/planact.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/main.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/setup.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/__init__.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/core/__init__.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/core/log_config.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/core/models.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/core/request.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/core/response.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/core/test/test_base_api.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/core/test/test_geminimask.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/core/test/test_image.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/core/test/test_payload.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/core/utils.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/models/__init__.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/models/audio.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/models/base.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/models/chatgpt.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/models/claude.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/models/duckduckgo.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/models/gemini.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/models/groq.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/models/vertex.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/plugins/__init__.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/plugins/arXiv.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/plugins/config.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/plugins/excute_command.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/plugins/get_time.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/plugins/image.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/plugins/list_directory.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/plugins/read_file.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/plugins/read_image.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/plugins/readonly.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/plugins/registry.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/plugins/run_python.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/plugins/websearch.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/plugins/write_file.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/utils/__init__.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/utils/prompt.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/src/aient/utils/scripts.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/chatgpt.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/claude.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_API.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_Deepbricks.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_Web_crawler.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_aiwaves.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_aiwaves_arxiv.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_ask_gemini.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_class.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_claude.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_claude_zh_char.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_ddg_search.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_download_pdf.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_gemini.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_get_token_dict.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_google_search.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_jieba.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_json.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_logging.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_ollama.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_plugin.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_py_run.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_requests.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_search.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_tikitoken.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_token.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_url.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_whisper.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_wildcard.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/aient/test/test_yjh.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/bemcp/bemcp/__init__.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/bemcp/bemcp/decorator.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/bemcp/bemcp/main.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/bemcp/bemcp/utils.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/bemcp/test/client.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/bemcp/test/server.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/broker.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/core.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/prompt.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/README.md +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/arduino-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/c-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/chatito-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/commonlisp-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/cpp-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/csharp-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/d-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/dart-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/elisp-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/elixir-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/elm-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/gleam-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/go-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/java-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/javascript-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/lua-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/pony-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/properties-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/python-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/r-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/racket-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/ruby-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/rust-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/solidity-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/swift-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/udev-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/README.md +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/c-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/c_sharp-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/cpp-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/dart-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/elisp-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/elixir-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/elm-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/go-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/hcl-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/java-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/javascript-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/kotlin-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/ocaml-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/php-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/python-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/ql-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/ruby-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/rust-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/scala-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-languages/typescript-tags.scm +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/taskmanager.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/tools/click.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/tools/completion.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/tools/edit_file.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/tools/planner.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/tools/repomap.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/tools/request_input.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/tools/screenshot.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/tools/search_arxiv.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/tools/search_web.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/tools/subtasks.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/tools/worker.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/tools/write_csv.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm/utils.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm.egg-info/SOURCES.txt +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm.egg-info/dependency_links.txt +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm.egg-info/requires.txt +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/beswarm.egg-info/top_level.txt +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/setup.cfg +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/test/test_TaskManager.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/test/test_broker.py +0 -0
- {beswarm-0.2.48 → beswarm-0.2.50}/test/test_new_TaskManager.py +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import uuid
|
|
2
2
|
import networkx as nx
|
|
3
3
|
from pathlib import Path
|
|
4
|
+
from .aient.src.aient.utils.scripts import unescape_html
|
|
4
5
|
|
|
5
6
|
class KnowledgeGraphManager:
|
|
6
7
|
"""
|
|
@@ -48,7 +49,7 @@ class KnowledgeGraphManager:
|
|
|
48
49
|
def _create_new_graph(self):
|
|
49
50
|
"""创建一个带有根节点的新图谱并保存。"""
|
|
50
51
|
self.graph = nx.DiGraph()
|
|
51
|
-
self.graph.add_node("root", name=".", description="知识图谱根节点")
|
|
52
|
+
self.graph.add_node("root", name=".", description="知识图谱根节点", tags="")
|
|
52
53
|
self._save_graph()
|
|
53
54
|
|
|
54
55
|
def set_publish_topic(self, publish_topic):
|
|
@@ -68,6 +69,7 @@ class KnowledgeGraphManager:
|
|
|
68
69
|
if path is None or not path.strip() or path.strip() in ['.', '/']:
|
|
69
70
|
return "root"
|
|
70
71
|
|
|
72
|
+
path = unescape_html(path)
|
|
71
73
|
segments = [s for s in path.strip('/').split('/') if s and s != '.']
|
|
72
74
|
current_node_id = "root"
|
|
73
75
|
|
|
@@ -102,8 +104,11 @@ class KnowledgeGraphManager:
|
|
|
102
104
|
|
|
103
105
|
return current_node_id
|
|
104
106
|
|
|
105
|
-
def add_node(self, parent_path: str, node_name: str, description: str = "") -> str:
|
|
107
|
+
def add_node(self, parent_path: str, node_name: str, description: str = "", tags: list[str] = None) -> str:
|
|
106
108
|
"""在指定父节点下添加一个新节点。"""
|
|
109
|
+
parent_path = unescape_html(parent_path)
|
|
110
|
+
node_name = unescape_html(node_name)
|
|
111
|
+
description = unescape_html(description)
|
|
107
112
|
if not node_name.strip():
|
|
108
113
|
return "❌ 错误:节点名称不能为空。"
|
|
109
114
|
if '/' in node_name:
|
|
@@ -118,13 +123,60 @@ class KnowledgeGraphManager:
|
|
|
118
123
|
return f"❌ 错误:在 '{parent_path}' 下已存在名为 '{node_name}' 的节点。"
|
|
119
124
|
|
|
120
125
|
new_node_id = str(uuid.uuid4())
|
|
121
|
-
|
|
126
|
+
# 将标签列表转换为内部存储的字符串格式
|
|
127
|
+
tags_str = ",".join(sorted(list(set(filter(None, tags or [])))))
|
|
128
|
+
self.graph.add_node(new_node_id, name=node_name, description=description, tags=tags_str)
|
|
122
129
|
self.graph.add_edge(parent_id, new_node_id)
|
|
123
130
|
self._save_graph()
|
|
124
131
|
return f"✅ 成功在 '{parent_path}' 下添加节点 '{node_name}'。"
|
|
125
132
|
|
|
133
|
+
def _get_tags(self, node_id: str) -> list[str]:
|
|
134
|
+
"""获取节点的标签列表。"""
|
|
135
|
+
tags_str = self.graph.nodes[node_id].get('tags', '')
|
|
136
|
+
return tags_str.split(',') if tags_str else []
|
|
137
|
+
|
|
138
|
+
def _set_tags(self, node_id: str, tags: list[str]):
|
|
139
|
+
"""设置节点的标签列表。"""
|
|
140
|
+
# 移除重复项并排序
|
|
141
|
+
unique_tags = sorted(list(set(filter(None, tags))))
|
|
142
|
+
self.graph.nodes[node_id]['tags'] = ",".join(unique_tags)
|
|
143
|
+
|
|
144
|
+
def add_tags_to_node(self, node_path: str, tags_to_add: list[str]) -> str:
|
|
145
|
+
"""向指定节点添加一个或多个标签。"""
|
|
146
|
+
node_path = unescape_html(node_path)
|
|
147
|
+
node_id = self._get_node_id_by_path(node_path)
|
|
148
|
+
if node_id is None:
|
|
149
|
+
return f"❌ 错误:路径 '{node_path}' 不存在。"
|
|
150
|
+
|
|
151
|
+
current_tags = self._get_tags(node_id)
|
|
152
|
+
current_tags.extend(tags_to_add)
|
|
153
|
+
self._set_tags(node_id, current_tags)
|
|
154
|
+
self._save_graph()
|
|
155
|
+
return f"✅ 成功向节点 '{node_path}' 添加标签: {' '.join([f'#{t}' for t in tags_to_add])}"
|
|
156
|
+
|
|
157
|
+
def remove_tags_from_node(self, node_path: str, tags_to_remove: list[str]) -> str:
|
|
158
|
+
"""从指定节点移除一个或多个标签。"""
|
|
159
|
+
node_path = unescape_html(node_path)
|
|
160
|
+
node_id = self._get_node_id_by_path(node_path)
|
|
161
|
+
if node_id is None:
|
|
162
|
+
return f"❌ 错误:路径 '{node_path}' 不存在。"
|
|
163
|
+
|
|
164
|
+
current_tags = self._get_tags(node_id)
|
|
165
|
+
if not current_tags:
|
|
166
|
+
return f"ℹ️ 节点 '{node_path}' 没有任何标签可供移除。"
|
|
167
|
+
|
|
168
|
+
new_tags = [tag for tag in current_tags if tag not in tags_to_remove]
|
|
169
|
+
|
|
170
|
+
if len(new_tags) == len(current_tags):
|
|
171
|
+
return f"ℹ️ 在节点 '{node_path}' 上未找到指定的标签: {' '.join([f'#{t}' for t in tags_to_remove])}"
|
|
172
|
+
|
|
173
|
+
self._set_tags(node_id, new_tags)
|
|
174
|
+
self._save_graph()
|
|
175
|
+
return f"✅ 成功从节点 '{node_path}' 移除标签。"
|
|
176
|
+
|
|
126
177
|
def delete_node(self, node_path: str) -> str:
|
|
127
178
|
"""删除一个节点及其所有子孙节点。"""
|
|
179
|
+
node_path = unescape_html(node_path)
|
|
128
180
|
if node_path is None or node_path.strip() in ['.', '/']:
|
|
129
181
|
return "❌ 错误:不能删除根节点。"
|
|
130
182
|
|
|
@@ -141,6 +193,8 @@ class KnowledgeGraphManager:
|
|
|
141
193
|
|
|
142
194
|
def rename_node(self, node_path: str, new_name: str) -> str:
|
|
143
195
|
"""重命名一个节点。"""
|
|
196
|
+
node_path = unescape_html(node_path)
|
|
197
|
+
new_name = unescape_html(new_name)
|
|
144
198
|
if not new_name.strip():
|
|
145
199
|
return "❌ 错误:新名称不能为空。"
|
|
146
200
|
if '/' in new_name:
|
|
@@ -163,6 +217,8 @@ class KnowledgeGraphManager:
|
|
|
163
217
|
|
|
164
218
|
def move_node(self, source_path: str, target_parent_path: str) -> str:
|
|
165
219
|
"""将一个节点移动到另一个父节点下。"""
|
|
220
|
+
source_path = unescape_html(source_path)
|
|
221
|
+
target_parent_path = unescape_html(target_parent_path)
|
|
166
222
|
source_id = self._get_node_id_by_path(source_path)
|
|
167
223
|
if source_id is None:
|
|
168
224
|
return f"❌ 错误:源路径 '{source_path}' 不存在。"
|
|
@@ -187,6 +243,30 @@ class KnowledgeGraphManager:
|
|
|
187
243
|
self._save_graph()
|
|
188
244
|
return f"✅ 成功将节点 '{source_path}' 移动到 '{target_parent_path}' 下。"
|
|
189
245
|
|
|
246
|
+
def get_node_details(self, node_path: str) -> str:
|
|
247
|
+
"""获取指定路径节点的所有详细信息。"""
|
|
248
|
+
node_path = unescape_html(node_path)
|
|
249
|
+
node_id = self._get_node_id_by_path(node_path)
|
|
250
|
+
if node_id is None:
|
|
251
|
+
return f"❌ 错误:路径 '{node_path}' 不存在。"
|
|
252
|
+
|
|
253
|
+
node_data = self.graph.nodes[node_id]
|
|
254
|
+
description = node_data.get('description', '无描述。')
|
|
255
|
+
tags = self._get_tags(node_id)
|
|
256
|
+
|
|
257
|
+
# 路径就用用户输入的,因为这才是用户识别它的方式
|
|
258
|
+
details = [f"节点: {node_path}"]
|
|
259
|
+
details.append(f"描述: {description}")
|
|
260
|
+
|
|
261
|
+
if tags:
|
|
262
|
+
# 格式化标签为 '#技术细节, #激活函数'
|
|
263
|
+
formatted_tags = " ".join([f"#{t}" for t in tags])
|
|
264
|
+
details.append(f"标签: {formatted_tags}")
|
|
265
|
+
else:
|
|
266
|
+
details.append("标签: 无")
|
|
267
|
+
|
|
268
|
+
return "\n".join(details)
|
|
269
|
+
|
|
190
270
|
def render_tree(self) -> str:
|
|
191
271
|
"""渲染整个知识图谱为树状结构的文本。"""
|
|
192
272
|
if not self.graph or "root" not in self.graph:
|
|
@@ -204,6 +284,13 @@ class KnowledgeGraphManager:
|
|
|
204
284
|
is_last = (i == len(children) - 1)
|
|
205
285
|
connector = "└── " if is_last else "├── "
|
|
206
286
|
node_name = self.graph.nodes[child_id].get('name', '[Unnamed Node]')
|
|
287
|
+
|
|
288
|
+
# 显示标签,过滤掉以'source'开头的标签
|
|
289
|
+
tags = self._get_tags(child_id)
|
|
290
|
+
display_tags = [t for t in tags if not t.startswith('source')]
|
|
291
|
+
if display_tags:
|
|
292
|
+
node_name += f" {' '.join([f'#{t}' for t in display_tags])}"
|
|
293
|
+
|
|
207
294
|
tree_lines.append(f"{prefix}{connector}{node_name}")
|
|
208
295
|
new_prefix = prefix + " " if is_last else prefix + "│ "
|
|
209
|
-
self._build_tree_string_recursive(child_id, new_prefix, tree_lines)
|
|
296
|
+
self._build_tree_string_recursive(child_id, new_prefix, tree_lines)
|
|
@@ -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
|
|
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",
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
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)
|
|
@@ -44,7 +44,7 @@ class KnowledgeGraphManager:
|
|
|
44
44
|
def _create_new_graph(self):
|
|
45
45
|
"""创建一个带有根节点的新图谱。"""
|
|
46
46
|
self.graph = nx.DiGraph()
|
|
47
|
-
self.graph.add_node("root", name=".", description="知识图谱根节点")
|
|
47
|
+
self.graph.add_node("root", name=".", description="知识图谱根节点", tags="")
|
|
48
48
|
|
|
49
49
|
def _save_graph(self):
|
|
50
50
|
"""将当前图的状态保存到文件。"""
|
|
@@ -73,7 +73,7 @@ class KnowledgeGraphManager:
|
|
|
73
73
|
return None
|
|
74
74
|
return current_node_id
|
|
75
75
|
|
|
76
|
-
def add_node(self, parent_path: str, node_name: str, description: str = "") -> str:
|
|
76
|
+
def add_node(self, parent_path: str, node_name: str, description: str = "", tags: list[str] = None) -> str:
|
|
77
77
|
"""在指定父节点下添加一个新节点。"""
|
|
78
78
|
if not node_name.strip():
|
|
79
79
|
return "❌ 错误:节点名称不能为空。"
|
|
@@ -89,12 +89,54 @@ class KnowledgeGraphManager:
|
|
|
89
89
|
return f"❌ 错误:在 '{parent_path}' 下已存在名为 '{node_name}' 的节点。"
|
|
90
90
|
|
|
91
91
|
new_node_id = str(uuid.uuid4())
|
|
92
|
-
|
|
92
|
+
tags_str = ",".join(sorted(list(set(filter(None, tags or [])))))
|
|
93
|
+
self.graph.add_node(new_node_id, name=node_name, description=description, tags=tags_str)
|
|
93
94
|
self.graph.add_edge(parent_id, new_node_id)
|
|
94
95
|
|
|
95
96
|
self._save_graph()
|
|
96
97
|
return f"✅ 成功在 '{parent_path}' 下添加节点 '{node_name}'。"
|
|
97
98
|
|
|
99
|
+
def _get_tags(self, node_id: str) -> list[str]:
|
|
100
|
+
"""获取节点的标签列表。"""
|
|
101
|
+
tags_str = self.graph.nodes[node_id].get('tags', '')
|
|
102
|
+
return tags_str.split(',') if tags_str else []
|
|
103
|
+
|
|
104
|
+
def _set_tags(self, node_id: str, tags: list[str]):
|
|
105
|
+
"""设置节点的标签列表。"""
|
|
106
|
+
unique_tags = sorted(list(set(filter(None, tags))))
|
|
107
|
+
self.graph.nodes[node_id]['tags'] = ",".join(unique_tags)
|
|
108
|
+
|
|
109
|
+
def add_tags_to_node(self, node_path: str, tags_to_add: list[str]) -> str:
|
|
110
|
+
"""向指定节点添加一个或多个标签。"""
|
|
111
|
+
node_id = self._get_node_id_by_path(node_path)
|
|
112
|
+
if node_id is None:
|
|
113
|
+
return f"❌ 错误:路径 '{node_path}' 不存在。"
|
|
114
|
+
|
|
115
|
+
current_tags = self._get_tags(node_id)
|
|
116
|
+
current_tags.extend(tags_to_add)
|
|
117
|
+
self._set_tags(node_id, current_tags)
|
|
118
|
+
self._save_graph()
|
|
119
|
+
return f"✅ 成功向节点 '{node_path}' 添加标签: {', '.join(tags_to_add)}。"
|
|
120
|
+
|
|
121
|
+
def remove_tags_from_node(self, node_path: str, tags_to_remove: list[str]) -> str:
|
|
122
|
+
"""从指定节点移除一个或多个标签。"""
|
|
123
|
+
node_id = self._get_node_id_by_path(node_path)
|
|
124
|
+
if node_id is None:
|
|
125
|
+
return f"❌ 错误:路径 '{node_path}' 不存在。"
|
|
126
|
+
|
|
127
|
+
current_tags = self._get_tags(node_id)
|
|
128
|
+
if not current_tags:
|
|
129
|
+
return f"ℹ️ 节点 '{node_path}' 没有任何标签可供移除。"
|
|
130
|
+
|
|
131
|
+
new_tags = [tag for tag in current_tags if tag not in tags_to_remove]
|
|
132
|
+
|
|
133
|
+
if len(new_tags) == len(current_tags):
|
|
134
|
+
return f"ℹ️ 在节点 '{node_path}' 上未找到指定的标签: {', '.join(tags_to_remove)}。"
|
|
135
|
+
|
|
136
|
+
self._set_tags(node_id, new_tags)
|
|
137
|
+
self._save_graph()
|
|
138
|
+
return f"✅ 成功从节点 '{node_path}' 移除标签。"
|
|
139
|
+
|
|
98
140
|
def delete_node(self, node_path: str) -> str:
|
|
99
141
|
"""删除一个节点及其所有子孙节点。"""
|
|
100
142
|
if node_path is None or node_path.strip() in ['.', '/']:
|
|
@@ -161,17 +203,17 @@ class KnowledgeGraphManager:
|
|
|
161
203
|
self._save_graph()
|
|
162
204
|
return f"✅ 成功将节点 '{source_path}' 移动到 '{target_parent_path}' 下。"
|
|
163
205
|
|
|
164
|
-
def render_tree(self) -> str:
|
|
206
|
+
def render_tree(self, show_source_tags=False) -> str:
|
|
165
207
|
"""渲染整个知识图谱为树状结构的文本。"""
|
|
166
208
|
if not self.graph or "root" not in self.graph:
|
|
167
209
|
return "图谱为空或未正确初始化。"
|
|
168
210
|
|
|
169
211
|
tree_lines = [self.graph.nodes["root"]["name"]]
|
|
170
212
|
# 调用递归函数来构建树
|
|
171
|
-
self._build_tree_string_recursive("root", "", tree_lines)
|
|
213
|
+
self._build_tree_string_recursive("root", "", tree_lines, show_source_tags)
|
|
172
214
|
return "\n".join(tree_lines)
|
|
173
215
|
|
|
174
|
-
def _build_tree_string_recursive(self, parent_id, prefix, tree_lines):
|
|
216
|
+
def _build_tree_string_recursive(self, parent_id, prefix, tree_lines, show_source_tags=False):
|
|
175
217
|
"""递归辅助函数,用于构建树状图字符串。"""
|
|
176
218
|
children = sorted(list(self.graph.successors(parent_id)), key=lambda n: self.graph.nodes[n]['name'])
|
|
177
219
|
|
|
@@ -180,6 +222,17 @@ class KnowledgeGraphManager:
|
|
|
180
222
|
is_last = (i == num_children - 1)
|
|
181
223
|
connector = "└── " if is_last else "├── "
|
|
182
224
|
node_name = self.graph.nodes[child_id].get('name', '[Unnamed Node]')
|
|
225
|
+
|
|
226
|
+
# 显示标签,过滤掉以'source'开头的标签
|
|
227
|
+
tags = self._get_tags(child_id)
|
|
228
|
+
if show_source_tags:
|
|
229
|
+
display_tags = tags
|
|
230
|
+
else:
|
|
231
|
+
display_tags = [t for t in tags if not t.startswith('source')]
|
|
232
|
+
|
|
233
|
+
if display_tags:
|
|
234
|
+
node_name += f" {' '.join([f'#{t}' for t in display_tags])}"
|
|
235
|
+
|
|
183
236
|
tree_lines.append(f"{prefix}{connector}{node_name}")
|
|
184
237
|
|
|
185
238
|
new_prefix = prefix + " " if is_last else prefix + "│ "
|
|
@@ -195,7 +248,10 @@ def print_menu():
|
|
|
195
248
|
print(f"{colors.FAIL}3. ❌ 删除节点{colors.ENDC}")
|
|
196
249
|
print(f"{colors.OKBLUE}4. ✏️ 重命名节点{colors.ENDC}")
|
|
197
250
|
print(f"{colors.OKBLUE}5. ➡️ 移动节点{colors.ENDC}")
|
|
198
|
-
print(f"{colors.
|
|
251
|
+
print(f"{colors.OKCYAN}6. 🏷️ 添加标签{colors.ENDC}")
|
|
252
|
+
print(f"{colors.OKCYAN}7. 🗑️ 移除标签{colors.ENDC}")
|
|
253
|
+
print(f"{colors.OKBLUE}8. ℹ️ 查看节点详细信息{colors.ENDC}")
|
|
254
|
+
print(f"{colors.WARNING}9. 💥 删除图谱文件并重置{colors.ENDC}")
|
|
199
255
|
print("0. 退出")
|
|
200
256
|
print("-"*50)
|
|
201
257
|
|
|
@@ -215,7 +271,9 @@ def main_test_loop():
|
|
|
215
271
|
parent_path = input("请输入父节点路径 (例如 'a/b', 根节点为'.'): ")
|
|
216
272
|
node_name = input("请输入新节点名称: ")
|
|
217
273
|
description = input("请输入节点描述 (可选): ")
|
|
218
|
-
|
|
274
|
+
tags_str = input("请输入标签, 以逗号分隔 (可选): ")
|
|
275
|
+
tags = [tag.strip() for tag in tags_str.split(',') if tag.strip()]
|
|
276
|
+
result = kgm.add_node(parent_path, node_name, description, tags)
|
|
219
277
|
print(f"\n{result}")
|
|
220
278
|
elif choice == '3':
|
|
221
279
|
node_path = input("请输入要删除的节点路径 (例如 'a/b'): ")
|
|
@@ -232,6 +290,24 @@ def main_test_loop():
|
|
|
232
290
|
result = kgm.move_node(source_path, target_parent_path)
|
|
233
291
|
print(f"\n{result}")
|
|
234
292
|
elif choice == '6':
|
|
293
|
+
node_path = input("请输入要添加标签的节点路径: ")
|
|
294
|
+
tags_str = input("请输入要添加的标签 (以逗号分隔): ")
|
|
295
|
+
tags_to_add = [tag.strip() for tag in tags_str.split(',') if tag.strip()]
|
|
296
|
+
result = kgm.add_tags_to_node(node_path, tags_to_add)
|
|
297
|
+
print(f"\n{result}")
|
|
298
|
+
elif choice == '7':
|
|
299
|
+
node_path = input("请输入要移除标签的节点路径: ")
|
|
300
|
+
tags_str = input("请输入要移除的标签 (以逗号分隔): ")
|
|
301
|
+
tags_to_remove = [tag.strip() for tag in tags_str.split(',') if tag.strip()]
|
|
302
|
+
result = kgm.remove_tags_from_node(node_path, tags_to_remove)
|
|
303
|
+
print(f"\n{result}")
|
|
304
|
+
elif choice == '8':
|
|
305
|
+
node_path = input("请输入要查看详情的节点路径: ")
|
|
306
|
+
details = kgm.get_node_details(node_path)
|
|
307
|
+
print("\n--- 节点详细信息 ---")
|
|
308
|
+
print(details)
|
|
309
|
+
print("------------------------")
|
|
310
|
+
elif choice == '9':
|
|
235
311
|
if kgm.storage_path.exists():
|
|
236
312
|
confirm = input(f"⚠️ 确定要删除 '{kgm.storage_path}' 并重置吗? (y/n): ").lower()
|
|
237
313
|
if confirm == 'y':
|
|
@@ -246,9 +322,9 @@ def main_test_loop():
|
|
|
246
322
|
print("退出程序。")
|
|
247
323
|
break
|
|
248
324
|
else:
|
|
249
|
-
print("无效输入,请输入0-
|
|
325
|
+
print("无效输入,请输入0-9之间的数字。")
|
|
250
326
|
|
|
251
327
|
input("\n按回车键继续...")
|
|
252
328
|
|
|
253
329
|
if __name__ == "__main__":
|
|
254
|
-
main_test_loop()
|
|
330
|
+
main_test_loop()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/arduino-tags.scm
RENAMED
|
File without changes
|
|
File without changes
|
{beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/chatito-tags.scm
RENAMED
|
File without changes
|
{beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/commonlisp-tags.scm
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/javascript-tags.scm
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/properties-tags.scm
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{beswarm-0.2.48 → beswarm-0.2.50}/beswarm/queries/tree-sitter-language-pack/solidity-tags.scm
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|