beswarm 0.1.99__tar.gz → 0.2.1__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.
- {beswarm-0.1.99 → beswarm-0.2.1}/PKG-INFO +1 -1
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/setup.py +1 -1
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/core/request.py +8 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/core/response.py +9 -12
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/plugins/excute_command.py +9 -4
- beswarm-0.2.1/beswarm/bemcp/bemcp/decorator.py +83 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/bemcp/bemcp/main.py +6 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/bemcp/bemcp/utils.py +1 -1
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/bemcp/test/server.py +2 -2
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/prompt.py +1 -1
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/tools/worker.py +22 -1
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm.egg-info/PKG-INFO +1 -1
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm.egg-info/SOURCES.txt +1 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/pyproject.toml +1 -1
- {beswarm-0.1.99 → beswarm-0.2.1}/MANIFEST.in +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/README.md +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/__init__.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/main.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/__init__.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/core/__init__.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/core/log_config.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/core/models.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/core/test/test_base_api.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/core/test/test_geminimask.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/core/test/test_image.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/core/test/test_payload.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/core/utils.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/models/__init__.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/models/audio.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/models/base.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/models/chatgpt.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/models/claude.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/models/duckduckgo.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/models/gemini.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/models/groq.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/models/vertex.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/plugins/__init__.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/plugins/arXiv.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/plugins/config.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/plugins/get_time.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/plugins/image.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/plugins/list_directory.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/plugins/read_file.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/plugins/read_image.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/plugins/readonly.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/plugins/registry.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/plugins/run_python.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/plugins/websearch.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/plugins/write_file.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/utils/__init__.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/utils/prompt.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/src/aient/utils/scripts.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/chatgpt.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/claude.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_API.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_Deepbricks.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_Web_crawler.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_aiwaves.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_aiwaves_arxiv.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_ask_gemini.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_class.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_claude.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_claude_zh_char.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_ddg_search.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_download_pdf.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_gemini.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_get_token_dict.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_google_search.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_jieba.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_json.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_logging.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_ollama.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_plugin.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_py_run.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_requests.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_search.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_tikitoken.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_token.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_url.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_whisper.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_wildcard.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/aient/test/test_yjh.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/bemcp/bemcp/__init__.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/bemcp/test/client.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/README.md +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/arduino-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/c-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/chatito-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/commonlisp-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/cpp-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/csharp-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/d-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/dart-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/elisp-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/elixir-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/elm-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/gleam-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/go-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/java-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/javascript-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/lua-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/pony-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/properties-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/python-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/r-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/racket-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/ruby-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/rust-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/solidity-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/swift-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/udev-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/README.md +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/c-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/c_sharp-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/cpp-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/dart-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/elisp-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/elixir-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/elm-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/go-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/hcl-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/java-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/javascript-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/kotlin-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/ocaml-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/php-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/python-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/ql-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/ruby-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/rust-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/scala-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-languages/typescript-tags.scm +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/tools/__init__.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/tools/click.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/tools/edit_file.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/tools/planner.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/tools/repomap.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/tools/screenshot.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/tools/search_arxiv.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/tools/search_web.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/tools/think.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm/utils.py +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm.egg-info/dependency_links.txt +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm.egg-info/requires.txt +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/beswarm.egg-info/top_level.txt +0 -0
- {beswarm-0.1.99 → beswarm-0.2.1}/setup.cfg +0 -0
@@ -4,7 +4,7 @@ from setuptools import setup, find_packages
|
|
4
4
|
|
5
5
|
setup(
|
6
6
|
name="aient",
|
7
|
-
version="1.1.
|
7
|
+
version="1.1.40",
|
8
8
|
description="Aient: The Awakening of Agent.",
|
9
9
|
long_description=Path.open(Path("README.md"), encoding="utf-8").read(),
|
10
10
|
long_description_content_type="text/markdown",
|
@@ -240,6 +240,10 @@ async def get_gemini_payload(request, engine, provider, api_key=None):
|
|
240
240
|
val = int(m.group(1))
|
241
241
|
if val < 0:
|
242
242
|
val = 0
|
243
|
+
elif val > 32768 and "gemini-2.5-pro" in original_model:
|
244
|
+
val = 32768
|
245
|
+
elif val < 128 and "gemini-2.5-pro" in original_model:
|
246
|
+
val = 128
|
243
247
|
elif val > 24576:
|
244
248
|
val = 24576
|
245
249
|
payload["generationConfig"]["thinkingConfig"]["thinkingBudget"] = val
|
@@ -532,6 +536,10 @@ async def get_vertex_gemini_payload(request, engine, provider, api_key=None):
|
|
532
536
|
val = int(m.group(1))
|
533
537
|
if val < 0:
|
534
538
|
val = 0
|
539
|
+
elif val > 32768 and "gemini-2.5-pro" in original_model:
|
540
|
+
val = 32768
|
541
|
+
elif val < 128 and "gemini-2.5-pro" in original_model:
|
542
|
+
val = 128
|
535
543
|
elif val > 24576:
|
536
544
|
val = 24576
|
537
545
|
payload["generationConfig"]["thinkingConfig"]["thinkingBudget"] = val
|
@@ -568,6 +568,7 @@ async def fetch_response(client, url, headers, payload, engine, model):
|
|
568
568
|
|
569
569
|
elif engine == "gemini" or engine == "vertex-gemini" or engine == "aws":
|
570
570
|
response_json = response.json()
|
571
|
+
# print("response_json", json.dumps(response_json, indent=4, ensure_ascii=False))
|
571
572
|
|
572
573
|
if isinstance(response_json, str):
|
573
574
|
import ast
|
@@ -579,7 +580,7 @@ async def fetch_response(client, url, headers, payload, engine, model):
|
|
579
580
|
else:
|
580
581
|
logger.error(f"error fetch_response: Unknown response_json type: {type(response_json)}")
|
581
582
|
parsed_data = response_json
|
582
|
-
|
583
|
+
|
583
584
|
content = ""
|
584
585
|
reasoning_content = ""
|
585
586
|
image_base64 = ""
|
@@ -596,15 +597,6 @@ async def fetch_response(client, url, headers, payload, engine, model):
|
|
596
597
|
reasoning_content += chunk
|
597
598
|
else:
|
598
599
|
content += chunk
|
599
|
-
# for item in parsed_data:
|
600
|
-
# chunk = safe_get(item, "candidates", 0, "content", "parts", 0, "text")
|
601
|
-
# is_think = safe_get(item, "candidates", 0, "content", "parts", 0, "thought", default=False)
|
602
|
-
# # logger.info(f"chunk: {repr(chunk)}")
|
603
|
-
# if chunk:
|
604
|
-
# if is_think:
|
605
|
-
# reasoning_content += chunk
|
606
|
-
# else:
|
607
|
-
# content += chunk
|
608
600
|
|
609
601
|
usage_metadata = safe_get(parsed_data, -1, "usageMetadata")
|
610
602
|
prompt_tokens = safe_get(usage_metadata, "promptTokenCount", default=0)
|
@@ -618,8 +610,13 @@ async def fetch_response(client, url, headers, payload, engine, model):
|
|
618
610
|
logger.error(f"Unknown role: {role}, parsed_data: {parsed_data}")
|
619
611
|
role = "assistant"
|
620
612
|
|
621
|
-
|
622
|
-
|
613
|
+
has_think = safe_get(parsed_data, 0, "candidates", 0, "content", "parts", 0, "thought", default=False)
|
614
|
+
if has_think:
|
615
|
+
function_message_parts_index = -1
|
616
|
+
else:
|
617
|
+
function_message_parts_index = 0
|
618
|
+
function_call_name = safe_get(parsed_data, -1, "candidates", 0, "content", "parts", function_message_parts_index, "functionCall", "name", default=None)
|
619
|
+
function_call_content = safe_get(parsed_data, -1, "candidates", 0, "content", "parts", function_message_parts_index, "functionCall", "args", default=None)
|
623
620
|
|
624
621
|
timestamp = int(datetime.timestamp(datetime.now()))
|
625
622
|
yield await generate_no_stream_response(timestamp, model, content=content, tools_id=None, function_call_name=function_call_name, function_call_content=function_call_content, role=role, total_tokens=total_tokens, prompt_tokens=prompt_tokens, completion_tokens=candidates_tokens, reasoning_content=reasoning_content, image_base64=image_base64)
|
@@ -68,14 +68,19 @@ def get_python_executable(command: str) -> str:
|
|
68
68
|
@register_tool()
|
69
69
|
def excute_command(command):
|
70
70
|
"""
|
71
|
-
执行命令并返回输出结果 (标准输出会实时打印到控制台)
|
72
|
-
|
71
|
+
执行命令并返回输出结果 (标准输出会实时打印到控制台)。
|
72
|
+
|
73
|
+
重要规则:
|
74
|
+
- **克隆仓库**: 使用 `git clone` 时,必须指定一个新的子目录作为目标,以避免在非空工作目录中出错。
|
75
|
+
- **正确示例**: `git clone https://github.com/user/repo_name.git repo_name`
|
76
|
+
- **错误用法**: `git clone https://github.com/user/repo_name.git .`
|
77
|
+
- **禁止**: 禁止用于查看pdf,禁止使用 `pdftotext` 命令。
|
73
78
|
|
74
79
|
参数:
|
75
|
-
command:
|
80
|
+
command: 要执行的命令,例如克隆仓库、安装依赖、运行代码等。
|
76
81
|
|
77
82
|
返回:
|
78
|
-
|
83
|
+
命令执行的最终状态和收集到的输出/错误信息。
|
79
84
|
"""
|
80
85
|
try:
|
81
86
|
command = unescape_html(command)
|
@@ -0,0 +1,83 @@
|
|
1
|
+
import asyncio
|
2
|
+
import functools
|
3
|
+
from typing import Any, Callable, TypeVar
|
4
|
+
|
5
|
+
try:
|
6
|
+
from mcp.shared.exceptions import McpError
|
7
|
+
except ImportError:
|
8
|
+
# Define a dummy exception if mcp is not available,
|
9
|
+
# although it should be in the target environment.
|
10
|
+
class McpError(Exception):
|
11
|
+
pass
|
12
|
+
|
13
|
+
try:
|
14
|
+
from anyio import BrokenResourceError
|
15
|
+
except ImportError:
|
16
|
+
class BrokenResourceError(Exception):
|
17
|
+
pass
|
18
|
+
|
19
|
+
F = TypeVar('F', bound=Callable[..., Any])
|
20
|
+
|
21
|
+
def async_retry(max_retries: int = 2, delay: float = 1.0):
|
22
|
+
"""
|
23
|
+
A decorator to automatically retry an async function if it raises an exception.
|
24
|
+
|
25
|
+
Args:
|
26
|
+
max_retries: The maximum number of retries.
|
27
|
+
delay: The delay between retries in seconds.
|
28
|
+
"""
|
29
|
+
def decorator(func: F) -> F:
|
30
|
+
@functools.wraps(func)
|
31
|
+
async def wrapper(*args: Any, **kwargs: Any) -> Any:
|
32
|
+
last_exception = None
|
33
|
+
# The number of attempts is max_retries + 1 (the initial attempt)
|
34
|
+
for attempt in range(max_retries + 1):
|
35
|
+
try:
|
36
|
+
return await func(*args, **kwargs)
|
37
|
+
except Exception as e:
|
38
|
+
last_exception = e
|
39
|
+
if attempt < max_retries:
|
40
|
+
print(f"Attempt {attempt + 1} failed with error: {e}. Retrying in {delay}s...")
|
41
|
+
await asyncio.sleep(delay)
|
42
|
+
else:
|
43
|
+
print(f"All {max_retries + 1} attempts failed.")
|
44
|
+
if last_exception is not None:
|
45
|
+
raise last_exception
|
46
|
+
return wrapper # type: ignore
|
47
|
+
return decorator
|
48
|
+
|
49
|
+
|
50
|
+
def reconnect_on_connection_error(func: F) -> F:
|
51
|
+
"""
|
52
|
+
A decorator for MCPClient methods that automatically tries to reconnect
|
53
|
+
and retry the call if a connection-related error is caught.
|
54
|
+
It handles McpError and anyio.BrokenResourceError.
|
55
|
+
"""
|
56
|
+
@functools.wraps(func)
|
57
|
+
async def wrapper(self, *args: Any, **kwargs: Any) -> Any:
|
58
|
+
try:
|
59
|
+
return await func(self, *args, **kwargs)
|
60
|
+
except (McpError, BrokenResourceError) as e:
|
61
|
+
is_connection_error = False
|
62
|
+
if isinstance(e, McpError):
|
63
|
+
error_str = str(e).lower()
|
64
|
+
if "connection closed" in error_str or "peer closed connection" in error_str:
|
65
|
+
is_connection_error = True
|
66
|
+
elif isinstance(e, BrokenResourceError):
|
67
|
+
is_connection_error = True
|
68
|
+
|
69
|
+
if is_connection_error:
|
70
|
+
print(f"Connection error detected ({type(e).__name__}): {e}. Attempting to reconnect...")
|
71
|
+
try:
|
72
|
+
await self.disconnect()
|
73
|
+
await self.connect()
|
74
|
+
print("Reconnected successfully. Retrying the operation...")
|
75
|
+
return await func(self, *args, **kwargs)
|
76
|
+
except Exception as reconnect_e:
|
77
|
+
print(f"Failed to reconnect and retry: {reconnect_e}")
|
78
|
+
# If reconnect fails, raise the original connection error
|
79
|
+
raise e
|
80
|
+
else:
|
81
|
+
# Not a connection-related McpError, re-raise it.
|
82
|
+
raise
|
83
|
+
return wrapper # type: ignore
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import asyncio
|
2
2
|
from typing import Any, Dict, List, Optional
|
3
3
|
from contextlib import AsyncExitStack
|
4
|
+
from bemcp.decorator import async_retry, reconnect_on_connection_error
|
4
5
|
|
5
6
|
from mcp import ClientSession, StdioServerParameters
|
6
7
|
from mcp.client.stdio import stdio_client
|
@@ -36,6 +37,7 @@ class MCPClient:
|
|
36
37
|
"""Disconnects from the MCP server and cleans up resources."""
|
37
38
|
return await self.__aexit__(None, None, None)
|
38
39
|
|
40
|
+
@async_retry(max_retries=2)
|
39
41
|
async def __aenter__(self):
|
40
42
|
"""Connects to the MCP server and initializes resources."""
|
41
43
|
if self.session:
|
@@ -68,6 +70,7 @@ class MCPClient:
|
|
68
70
|
self._exit_stack = None
|
69
71
|
print("Disconnected from server.")
|
70
72
|
|
73
|
+
@reconnect_on_connection_error
|
71
74
|
async def list_tools(self) -> List[types.Tool]:
|
72
75
|
"""Lists available tools from the server."""
|
73
76
|
if not self.session:
|
@@ -75,12 +78,14 @@ class MCPClient:
|
|
75
78
|
response = await self.session.list_tools()
|
76
79
|
return response.tools
|
77
80
|
|
81
|
+
@reconnect_on_connection_error
|
78
82
|
async def call_tool(self, name: str, args: Dict[str, Any]) -> types.CallToolResult:
|
79
83
|
"""Calls a tool on the server."""
|
80
84
|
if not self.session:
|
81
85
|
raise ConnectionError("Not connected to any server.")
|
82
86
|
return await self.session.call_tool(name, args)
|
83
87
|
|
88
|
+
@reconnect_on_connection_error
|
84
89
|
async def list_resources(self) -> List[types.Resource]:
|
85
90
|
"""Lists available resources from the server."""
|
86
91
|
if not self.session:
|
@@ -88,6 +93,7 @@ class MCPClient:
|
|
88
93
|
response = await self.session.list_resources()
|
89
94
|
return response.resources
|
90
95
|
|
96
|
+
@reconnect_on_connection_error
|
91
97
|
async def read_resource(self, uri: str) -> types.ReadResourceResult:
|
92
98
|
"""Reads a resource from the server."""
|
93
99
|
if not self.session:
|
@@ -7,7 +7,7 @@ worker_system_prompt = """
|
|
7
7
|
5. **核心工作循环:单步执行模式**
|
8
8
|
作为指令的**执行者**,而非任务的**规划师**,你必须严格遵循以下单步工作流程:
|
9
9
|
**执行指令**
|
10
|
-
- **严格遵从:** 只执行 user
|
10
|
+
- **严格遵从:** 只执行 user 当前下达的明确指令。在 user 明确给出下一步指令前,绝不擅自行动或推测、执行任何未明确要求的后续步骤。
|
11
11
|
- **严禁越权:** 禁止执行任何 user 未指定的步骤。`<goal>` 标签中的内容仅为背景信息,不得据此进行任务规划或推测。
|
12
12
|
**汇报结果**
|
13
13
|
- **聚焦单步:** 指令完成后,仅汇报该步骤的执行结果与产出。
|
@@ -32,6 +32,7 @@ async def worker(goal, tools, work_dir, cache_messages=None):
|
|
32
32
|
str: 当任务成功完成时,返回字符串 "任务已完成"。
|
33
33
|
"""
|
34
34
|
start_time = datetime.now()
|
35
|
+
os.chdir(Path(work_dir).absolute())
|
35
36
|
finish_flag = 0
|
36
37
|
|
37
38
|
mcp_list = [item for item in tools if isinstance(item, dict)]
|
@@ -166,6 +167,16 @@ async def worker(goal, tools, work_dir, cache_messages=None):
|
|
166
167
|
next_instruction = (
|
167
168
|
"任务描述:\n"
|
168
169
|
f"<goal>{goal}</goal>\n\n"
|
170
|
+
"你作为指令的**执行者**,而非任务的**规划师**,你必须严格遵循以下单步工作流程:\n"
|
171
|
+
"**执行指令**\n"
|
172
|
+
" - **严格遵从:** 只执行我当前下达的明确指令。在我明确给出下一步指令前,绝不擅自行动或推测、执行任何未明确要求的后续步骤。\n"
|
173
|
+
" - **严禁越权:** 禁止执行任何我未指定的步骤。`<goal>` 标签中的内容仅为背景信息,不得据此进行任务规划或推测。\n"
|
174
|
+
"**汇报结果**\n"
|
175
|
+
" - **聚焦单步:** 指令完成后,仅汇报该步骤的执行结果与产出。\n"
|
176
|
+
"**暂停等待**\n"
|
177
|
+
" - **原地待命:** 汇报后,任务暂停。在收到我新的指令前,严禁发起任何新的工具调用或操作。\n"
|
178
|
+
" - **请求指令:** 回复的最后必须明确请求我提供下一步指令。\n"
|
179
|
+
"**注意:** 禁止完成超出下面我未规定的步骤,`<goal>` 标签中的内容仅为背景信息。"
|
169
180
|
"现在开始执行第一步:\n"
|
170
181
|
f"{next_instruction}"
|
171
182
|
)
|
@@ -208,6 +219,7 @@ async def worker(goal, tools, work_dir, cache_messages=None):
|
|
208
219
|
|
209
220
|
async def worker_gen(goal, tools, work_dir, cache_messages=None):
|
210
221
|
start_time = datetime.now()
|
222
|
+
os.chdir(Path(work_dir).absolute())
|
211
223
|
finish_flag = 0
|
212
224
|
|
213
225
|
mcp_list = [item for item in tools if isinstance(item, dict)]
|
@@ -309,7 +321,6 @@ async def worker_gen(goal, tools, work_dir, cache_messages=None):
|
|
309
321
|
extracted_content = f"<latest_file_content>{match.group(1)}</latest_file_content>\n\n"
|
310
322
|
else:
|
311
323
|
extracted_content = ""
|
312
|
-
|
313
324
|
if isinstance(conversation_history[0]["content"], str):
|
314
325
|
conversation_history[0]["content"] = extracted_content + conversation_history[0]["content"]
|
315
326
|
elif isinstance(conversation_history[0]["content"], list) and extracted_content:
|
@@ -343,6 +354,16 @@ async def worker_gen(goal, tools, work_dir, cache_messages=None):
|
|
343
354
|
next_instruction = (
|
344
355
|
"任务描述:\n"
|
345
356
|
f"<goal>{goal}</goal>\n\n"
|
357
|
+
"你作为指令的**执行者**,而非任务的**规划师**,你必须严格遵循以下单步工作流程:\n"
|
358
|
+
"**执行指令**\n"
|
359
|
+
" - **严格遵从:** 只执行我当前下达的明确指令。在我明确给出下一步指令前,绝不擅自行动或推测、执行任何未明确要求的后续步骤。\n"
|
360
|
+
" - **严禁越权:** 禁止执行任何我未指定的步骤。`<goal>` 标签中的内容仅为背景信息,不得据此进行任务规划或推测。\n"
|
361
|
+
"**汇报结果**\n"
|
362
|
+
" - **聚焦单步:** 指令完成后,仅汇报该步骤的执行结果与产出。\n"
|
363
|
+
"**暂停等待**\n"
|
364
|
+
" - **原地待命:** 汇报后,任务暂停。在收到我新的指令前,严禁发起任何新的工具调用或操作。\n"
|
365
|
+
" - **请求指令:** 回复的最后必须明确请求我提供下一步指令。\n"
|
366
|
+
"**注意:** 禁止完成超出下面我未规定的步骤,`<goal>` 标签中的内容仅为背景信息。"
|
346
367
|
"现在开始执行第一步:\n"
|
347
368
|
f"{next_instruction}"
|
348
369
|
)
|
@@ -80,6 +80,7 @@ beswarm/aient/test/test_whisper.py
|
|
80
80
|
beswarm/aient/test/test_wildcard.py
|
81
81
|
beswarm/aient/test/test_yjh.py
|
82
82
|
beswarm/bemcp/bemcp/__init__.py
|
83
|
+
beswarm/bemcp/bemcp/decorator.py
|
83
84
|
beswarm/bemcp/bemcp/main.py
|
84
85
|
beswarm/bemcp/bemcp/utils.py
|
85
86
|
beswarm/bemcp/test/client.py
|
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.1.99 → beswarm-0.2.1}/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.1.99 → beswarm-0.2.1}/beswarm/queries/tree-sitter-language-pack/javascript-tags.scm
RENAMED
File without changes
|
File without changes
|
File without changes
|
{beswarm-0.1.99 → beswarm-0.2.1}/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.1.99 → beswarm-0.2.1}/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
|