beswarm 0.1.61__tar.gz → 0.1.63__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.61 → beswarm-0.1.63}/PKG-INFO +1 -1
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/setup.py +1 -1
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/core/request.py +18 -5
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/core/response.py +22 -3
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/core/utils.py +23 -4
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/tools/__init__.py +2 -1
- beswarm-0.1.63/beswarm/tools/worker.py +271 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm.egg-info/PKG-INFO +1 -1
- {beswarm-0.1.61 → beswarm-0.1.63}/pyproject.toml +1 -1
- beswarm-0.1.61/beswarm/tools/worker.py +0 -130
- {beswarm-0.1.61 → beswarm-0.1.63}/MANIFEST.in +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/README.md +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/__init__.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/main.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/__init__.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/core/__init__.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/core/log_config.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/core/models.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/core/test/test_base_api.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/core/test/test_geminimask.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/core/test/test_image.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/core/test/test_payload.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/models/__init__.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/models/audio.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/models/base.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/models/chatgpt.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/models/claude.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/models/duckduckgo.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/models/gemini.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/models/groq.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/models/vertex.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/plugins/__init__.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/plugins/arXiv.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/plugins/config.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/plugins/excute_command.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/plugins/get_time.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/plugins/image.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/plugins/list_directory.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/plugins/read_file.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/plugins/read_image.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/plugins/registry.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/plugins/run_python.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/plugins/websearch.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/plugins/write_file.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/prompt/__init__.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/prompt/agent.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/utils/__init__.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/utils/prompt.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/src/aient/utils/scripts.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/chatgpt.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/claude.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_API.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_Deepbricks.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_Web_crawler.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_aiwaves.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_aiwaves_arxiv.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_ask_gemini.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_class.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_claude.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_claude_zh_char.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_ddg_search.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_download_pdf.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_gemini.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_get_token_dict.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_google_search.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_jieba.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_json.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_logging.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_ollama.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_plugin.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_py_run.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_requests.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_search.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_tikitoken.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_token.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_url.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_whisper.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_wildcard.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/aient/test/test_yjh.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/README.md +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/arduino-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/c-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/chatito-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/commonlisp-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/cpp-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/csharp-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/d-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/dart-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/elisp-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/elixir-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/elm-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/gleam-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/go-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/java-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/javascript-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/lua-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/pony-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/properties-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/python-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/r-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/racket-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/ruby-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/rust-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/solidity-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/swift-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/udev-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/README.md +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/c-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/c_sharp-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/cpp-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/dart-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/elisp-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/elixir-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/elm-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/go-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/hcl-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/java-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/javascript-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/kotlin-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/ocaml-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/php-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/python-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/ql-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/ruby-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/rust-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/scala-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-languages/typescript-tags.scm +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/tools/click.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/tools/edit_file.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/tools/planner.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/tools/repomap.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/tools/search_arxiv.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/tools/search_web.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/tools/think.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm/utils.py +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm.egg-info/SOURCES.txt +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm.egg-info/dependency_links.txt +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm.egg-info/requires.txt +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/beswarm.egg-info/top_level.txt +0 -0
- {beswarm-0.1.61 → beswarm-0.1.63}/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.17",
|
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",
|
@@ -4,7 +4,7 @@ import httpx
|
|
4
4
|
import base64
|
5
5
|
import urllib.parse
|
6
6
|
|
7
|
-
from .models import RequestModel
|
7
|
+
from .models import RequestModel, Message
|
8
8
|
from .utils import (
|
9
9
|
c3s,
|
10
10
|
c3o,
|
@@ -50,7 +50,12 @@ async def get_gemini_payload(request, engine, provider, api_key=None):
|
|
50
50
|
systemInstruction = None
|
51
51
|
system_prompt = ""
|
52
52
|
function_arguments = None
|
53
|
-
|
53
|
+
|
54
|
+
try:
|
55
|
+
request_messages = [Message(role="user", content=request.prompt)]
|
56
|
+
except:
|
57
|
+
request_messages = request.messages
|
58
|
+
for msg in request_messages:
|
54
59
|
if msg.role == "assistant":
|
55
60
|
msg.role = "model"
|
56
61
|
tool_calls = None
|
@@ -104,9 +109,10 @@ async def get_gemini_payload(request, engine, provider, api_key=None):
|
|
104
109
|
elif msg.role == "system":
|
105
110
|
content[0]["text"] = re.sub(r"_+", "_", content[0]["text"])
|
106
111
|
system_prompt = system_prompt + "\n\n" + content[0]["text"]
|
107
|
-
|
112
|
+
if system_prompt.strip():
|
113
|
+
systemInstruction = {"parts": [{"text": system_prompt}]}
|
108
114
|
|
109
|
-
if any(off_model in original_model for off_model in gemini_max_token_65k_models):
|
115
|
+
if any(off_model in original_model for off_model in gemini_max_token_65k_models) or original_model == "gemini-2.0-flash-preview-image-generation":
|
110
116
|
safety_settings = "OFF"
|
111
117
|
else:
|
112
118
|
safety_settings = "BLOCK_NONE"
|
@@ -160,6 +166,7 @@ async def get_gemini_payload(request, engine, provider, api_key=None):
|
|
160
166
|
'top_logprobs',
|
161
167
|
'response_format',
|
162
168
|
'stream_options',
|
169
|
+
'prompt',
|
163
170
|
]
|
164
171
|
generation_config = {}
|
165
172
|
|
@@ -214,6 +221,12 @@ async def get_gemini_payload(request, engine, provider, api_key=None):
|
|
214
221
|
else:
|
215
222
|
payload["generationConfig"]["maxOutputTokens"] = 8192
|
216
223
|
|
224
|
+
if original_model == "gemini-2.0-flash-preview-image-generation":
|
225
|
+
payload["generationConfig"]["response_modalities"] = [
|
226
|
+
"Text",
|
227
|
+
"Image",
|
228
|
+
]
|
229
|
+
|
217
230
|
if "gemini-2.5" in original_model:
|
218
231
|
payload["generationConfig"]["thinkingConfig"] = {
|
219
232
|
"includeThoughts": True,
|
@@ -241,7 +254,7 @@ async def get_gemini_payload(request, engine, provider, api_key=None):
|
|
241
254
|
if key == request.model:
|
242
255
|
for k, v in value.items():
|
243
256
|
payload[k] = v
|
244
|
-
elif all(_model not in request.model.lower() for _model in ["gemini", "gpt", "claude"]):
|
257
|
+
elif all(_model not in request.model.lower() for _model in ["gemini", "gpt", "claude", "deepseek"]) and "-" not in key:
|
245
258
|
payload[key] = value
|
246
259
|
|
247
260
|
return url, headers, payload
|
@@ -36,6 +36,7 @@ async def fetch_gemini_response_stream(client, url, headers, payload, model):
|
|
36
36
|
candidatesTokenCount = 0
|
37
37
|
totalTokenCount = 0
|
38
38
|
parts_json = ""
|
39
|
+
image_base64 = ""
|
39
40
|
# line_index = 0
|
40
41
|
# last_text_line = 0
|
41
42
|
# if "thinking" in model:
|
@@ -53,6 +54,8 @@ async def fetch_gemini_response_stream(client, url, headers, payload, model):
|
|
53
54
|
if line and '\"finishReason\": \"' in line:
|
54
55
|
if "stop" not in line.lower():
|
55
56
|
logger.error(f"finishReason: {line}")
|
57
|
+
sse_string = await generate_sse_response(timestamp, model, stop="stop")
|
58
|
+
yield sse_string
|
56
59
|
is_finish = True
|
57
60
|
if is_finish and '\"promptTokenCount\": ' in line:
|
58
61
|
json_data = parse_json_safely( "{" + line + "}")
|
@@ -67,17 +70,25 @@ async def fetch_gemini_response_stream(client, url, headers, payload, model):
|
|
67
70
|
if (line and '"parts": [' in line or parts_json != "") and is_finish == False:
|
68
71
|
parts_json += line
|
69
72
|
if parts_json != "" and line and '],' == line.strip():
|
70
|
-
tmp_parts_json = "{" + parts_json.split("} ] },")[0].strip().rstrip("}], ").replace("\n", "\\n").lstrip("{") + "}]}"
|
73
|
+
# tmp_parts_json = "{" + parts_json.split("} ] },")[0].strip().rstrip("}], ").replace("\n", "\\n").lstrip("{") + "}]}"
|
74
|
+
tmp_parts_json = "{" + parts_json.split("} ] },")[0].strip().rstrip("}], ").replace("\n", "\\n").lstrip("{")
|
75
|
+
if "inlineData" in tmp_parts_json:
|
76
|
+
tmp_parts_json = tmp_parts_json + "}}]}"
|
77
|
+
else:
|
78
|
+
tmp_parts_json = tmp_parts_json + "}]}"
|
71
79
|
try:
|
72
80
|
json_data = json.loads(tmp_parts_json)
|
73
81
|
|
74
82
|
content = safe_get(json_data, "parts", 0, "text", default="")
|
83
|
+
b64_json = safe_get(json_data, "parts", 0, "inlineData", "data", default="")
|
84
|
+
if b64_json:
|
85
|
+
image_base64 = b64_json
|
75
86
|
|
76
87
|
is_thinking = safe_get(json_data, "parts", 0, "thought", default=False)
|
77
88
|
if is_thinking:
|
78
89
|
sse_string = await generate_sse_response(timestamp, model, reasoning_content=content)
|
79
90
|
yield sse_string
|
80
|
-
|
91
|
+
elif not image_base64:
|
81
92
|
sse_string = await generate_sse_response(timestamp, model, content=content)
|
82
93
|
yield sse_string
|
83
94
|
except json.JSONDecodeError:
|
@@ -93,6 +104,10 @@ async def fetch_gemini_response_stream(client, url, headers, payload, model):
|
|
93
104
|
|
94
105
|
function_full_response += line
|
95
106
|
|
107
|
+
if image_base64:
|
108
|
+
yield await generate_no_stream_response(timestamp, model, content=content, tools_id=None, function_call_name=None, function_call_content=None, role=None, total_tokens=totalTokenCount, prompt_tokens=promptTokenCount, completion_tokens=candidatesTokenCount, image_base64=image_base64)
|
109
|
+
return
|
110
|
+
|
96
111
|
if need_function_call:
|
97
112
|
function_call = json.loads(function_full_response)
|
98
113
|
function_call_name = function_call["functionCall"]["name"]
|
@@ -535,9 +550,13 @@ async def fetch_response(client, url, headers, payload, engine, model):
|
|
535
550
|
# print("parsed_data", json.dumps(parsed_data, indent=4, ensure_ascii=False))
|
536
551
|
content = ""
|
537
552
|
reasoning_content = ""
|
553
|
+
image_base64 = ""
|
538
554
|
parts_list = safe_get(parsed_data, 0, "candidates", 0, "content", "parts", default=[])
|
539
555
|
for item in parts_list:
|
540
556
|
chunk = safe_get(item, "text")
|
557
|
+
b64_json = safe_get(item, "inlineData", "data", default="")
|
558
|
+
if b64_json:
|
559
|
+
image_base64 = b64_json
|
541
560
|
is_think = safe_get(item, "thought", default=False)
|
542
561
|
# logger.info(f"chunk: {repr(chunk)}")
|
543
562
|
if chunk:
|
@@ -571,7 +590,7 @@ async def fetch_response(client, url, headers, payload, engine, model):
|
|
571
590
|
function_call_content = safe_get(parsed_data, -1, "candidates", 0, "content", "parts", 0, "functionCall", "args", default=None)
|
572
591
|
|
573
592
|
timestamp = int(datetime.timestamp(datetime.now()))
|
574
|
-
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)
|
593
|
+
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)
|
575
594
|
|
576
595
|
elif engine == "claude":
|
577
596
|
response_json = response.json()
|
@@ -112,7 +112,7 @@ def get_engine(provider, endpoint=None, original_model=""):
|
|
112
112
|
if provider.get("engine"):
|
113
113
|
engine = provider["engine"]
|
114
114
|
|
115
|
-
if endpoint == "/v1/images/generations" or "stable-diffusion" in original_model:
|
115
|
+
if engine != "gemini" and (endpoint == "/v1/images/generations" or "stable-diffusion" in original_model):
|
116
116
|
engine = "dalle"
|
117
117
|
stream = False
|
118
118
|
|
@@ -449,7 +449,7 @@ end_of_line = "\n\n"
|
|
449
449
|
|
450
450
|
import random
|
451
451
|
import string
|
452
|
-
async def generate_sse_response(timestamp, model, content=None, tools_id=None, function_call_name=None, function_call_content=None, role=None, total_tokens=0, prompt_tokens=0, completion_tokens=0, reasoning_content=None):
|
452
|
+
async def generate_sse_response(timestamp, model, content=None, tools_id=None, function_call_name=None, function_call_content=None, role=None, total_tokens=0, prompt_tokens=0, completion_tokens=0, reasoning_content=None, stop=None):
|
453
453
|
random.seed(timestamp)
|
454
454
|
random_str = ''.join(random.choices(string.ascii_letters + string.digits, k=29))
|
455
455
|
|
@@ -467,7 +467,7 @@ async def generate_sse_response(timestamp, model, content=None, tools_id=None, f
|
|
467
467
|
"index": 0,
|
468
468
|
"delta": delta_content,
|
469
469
|
"logprobs": None,
|
470
|
-
"finish_reason": None if content else "stop"
|
470
|
+
"finish_reason": None if content or reasoning_content else "stop"
|
471
471
|
}
|
472
472
|
],
|
473
473
|
"usage": None,
|
@@ -484,14 +484,19 @@ async def generate_sse_response(timestamp, model, content=None, tools_id=None, f
|
|
484
484
|
total_tokens = prompt_tokens + completion_tokens
|
485
485
|
sample_data["usage"] = {"prompt_tokens": prompt_tokens, "completion_tokens": completion_tokens, "total_tokens": total_tokens}
|
486
486
|
sample_data["choices"] = []
|
487
|
+
if stop:
|
488
|
+
sample_data["choices"][0]["delta"] = {}
|
489
|
+
sample_data["choices"][0]["finish_reason"] = stop
|
490
|
+
|
487
491
|
json_data = json.dumps(sample_data, ensure_ascii=False)
|
492
|
+
# print("json_data", json.dumps(sample_data, indent=4, ensure_ascii=False))
|
488
493
|
|
489
494
|
# 构建SSE响应
|
490
495
|
sse_response = f"data: {json_data}" + end_of_line
|
491
496
|
|
492
497
|
return sse_response
|
493
498
|
|
494
|
-
async def generate_no_stream_response(timestamp, model, content=None, tools_id=None, function_call_name=None, function_call_content=None, role=None, total_tokens=0, prompt_tokens=0, completion_tokens=0, reasoning_content=None):
|
499
|
+
async def generate_no_stream_response(timestamp, model, content=None, tools_id=None, function_call_name=None, function_call_content=None, role=None, total_tokens=0, prompt_tokens=0, completion_tokens=0, reasoning_content=None, image_base64=None):
|
495
500
|
random.seed(timestamp)
|
496
501
|
random_str = ''.join(random.choices(string.ascii_letters + string.digits, k=29))
|
497
502
|
message = {
|
@@ -554,11 +559,25 @@ async def generate_no_stream_response(timestamp, model, content=None, tools_id=N
|
|
554
559
|
"system_fingerprint": "fp_4691090a87"
|
555
560
|
}
|
556
561
|
|
562
|
+
if image_base64:
|
563
|
+
sample_data = {
|
564
|
+
"created": timestamp,
|
565
|
+
"data": [{
|
566
|
+
"b64_json": image_base64
|
567
|
+
}],
|
568
|
+
# "usage": {
|
569
|
+
# "total_tokens": 100,
|
570
|
+
# "input_tokens": 50,
|
571
|
+
# "output_tokens": 50,
|
572
|
+
# }
|
573
|
+
}
|
574
|
+
|
557
575
|
if total_tokens:
|
558
576
|
total_tokens = prompt_tokens + completion_tokens
|
559
577
|
sample_data["usage"] = {"prompt_tokens": prompt_tokens, "completion_tokens": completion_tokens, "total_tokens": total_tokens}
|
560
578
|
|
561
579
|
json_data = json.dumps(sample_data, ensure_ascii=False)
|
580
|
+
# print("json_data", json.dumps(sample_data, indent=4, ensure_ascii=False))
|
562
581
|
|
563
582
|
return json_data
|
564
583
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from .think import think
|
2
2
|
from .edit_file import edit_file
|
3
|
-
from .worker import worker
|
3
|
+
from .worker import worker, worker_gen
|
4
4
|
|
5
5
|
from .search_arxiv import search_arxiv
|
6
6
|
from .repomap import get_code_repo_map
|
@@ -26,6 +26,7 @@ __all__ = [
|
|
26
26
|
"think",
|
27
27
|
"edit_file",
|
28
28
|
"worker",
|
29
|
+
"worker_gen",
|
29
30
|
"search_arxiv",
|
30
31
|
"get_code_repo_map",
|
31
32
|
# aient.plugins
|
@@ -0,0 +1,271 @@
|
|
1
|
+
import os
|
2
|
+
import re
|
3
|
+
import copy
|
4
|
+
import json
|
5
|
+
import platform
|
6
|
+
from datetime import datetime
|
7
|
+
|
8
|
+
from ..aient.src.aient.models import chatgpt
|
9
|
+
from ..aient.src.aient.plugins import register_tool, get_function_call_list
|
10
|
+
from ..aient.src.aient.prompt import system_prompt, instruction_system_prompt
|
11
|
+
from ..utils import extract_xml_content, get_current_screen_image_message
|
12
|
+
|
13
|
+
@register_tool()
|
14
|
+
async def worker(goal, tools, work_dir, cache_messages=None):
|
15
|
+
"""
|
16
|
+
启动一个 **工作智能体 (Worker Agent)** 来自动完成指定的任务目标 (`goal`)。
|
17
|
+
|
18
|
+
这个工作智能体接收一个清晰的任务描述、一组可供调用的工具 (`tools`),以及一个工作目录 (`work_dir`)。
|
19
|
+
它会利用语言模型的能力,结合可用的工具,自主规划并逐步执行必要的操作,直到最终完成指定的任务目标。
|
20
|
+
核心功能是根据输入的目标,驱动整个任务执行流程。
|
21
|
+
|
22
|
+
Args:
|
23
|
+
goal (str): 需要完成的具体任务目标描述。工作智能体将围绕此目标进行工作。必须清晰、具体。
|
24
|
+
tools (list[str]): 一个包含可用工具函数对象的列表。工作智能体在执行任务时可能会调用这些工具来与环境交互(例如读写文件、执行命令等)。
|
25
|
+
work_dir (str): 工作目录的绝对路径。工作智能体将在此目录上下文中执行操作。
|
26
|
+
|
27
|
+
Returns:
|
28
|
+
str: 当任务成功完成时,返回字符串 "任务已完成"。
|
29
|
+
"""
|
30
|
+
|
31
|
+
tools_json = [value for _, value in get_function_call_list(tools).items()]
|
32
|
+
work_agent_system_prompt = system_prompt.format(
|
33
|
+
os_version=platform.platform(),
|
34
|
+
workspace_path=work_dir,
|
35
|
+
shell=os.getenv('SHELL', 'Unknown'),
|
36
|
+
tools_list=tools_json
|
37
|
+
)
|
38
|
+
|
39
|
+
work_agent_config = {
|
40
|
+
"api_key": os.getenv("API_KEY"),
|
41
|
+
"api_url": os.getenv("BASE_URL"),
|
42
|
+
"engine": os.getenv("MODEL"),
|
43
|
+
"system_prompt": work_agent_system_prompt,
|
44
|
+
"print_log": True,
|
45
|
+
# "max_tokens": 8000,
|
46
|
+
"temperature": 0.5,
|
47
|
+
"function_call_max_loop": 100,
|
48
|
+
}
|
49
|
+
if cache_messages:
|
50
|
+
work_agent_config["cache_messages"] = cache_messages
|
51
|
+
|
52
|
+
instruction_agent_config = {
|
53
|
+
"api_key": os.getenv("API_KEY"),
|
54
|
+
"api_url": os.getenv("BASE_URL"),
|
55
|
+
"engine": os.getenv("MODEL"),
|
56
|
+
"system_prompt": instruction_system_prompt.format(os_version=platform.platform(), tools_list=tools_json, workspace_path=work_dir, current_time=datetime.now().strftime("%Y-%m-%d %H:%M:%S")),
|
57
|
+
"print_log": False,
|
58
|
+
# "max_tokens": 4000,
|
59
|
+
"temperature": 0.7,
|
60
|
+
"use_plugins": False,
|
61
|
+
}
|
62
|
+
|
63
|
+
# 工作agent初始化
|
64
|
+
work_agent = chatgpt(**work_agent_config)
|
65
|
+
async def instruction_agent_task():
|
66
|
+
while True:
|
67
|
+
|
68
|
+
instruction_prompt = f"""
|
69
|
+
</work_agent_conversation_end>
|
70
|
+
任务目标: {goal}
|
71
|
+
|
72
|
+
在 tag <work_agent_conversation_start>...</work_agent_conversation_end> 之前的对话历史都是工作智能体的对话历史。
|
73
|
+
|
74
|
+
根据以上对话历史和目标,请生成下一步指令。如果任务已完成,请回复"任务已完成"。
|
75
|
+
"""
|
76
|
+
# 让指令agent分析对话历史并生成新指令
|
77
|
+
instruction_agent = chatgpt(**instruction_agent_config)
|
78
|
+
conversation_history = copy.deepcopy(work_agent.conversation["default"])
|
79
|
+
|
80
|
+
cache_dir = os.path.join(work_dir, ".beswarm")
|
81
|
+
os.makedirs(cache_dir, exist_ok=True)
|
82
|
+
cache_file = os.path.join(cache_dir, "work_agent_conversation_history.json")
|
83
|
+
with open(cache_file, "w", encoding="utf-8") as f:
|
84
|
+
f.write(json.dumps(conversation_history, ensure_ascii=False, indent=4))
|
85
|
+
|
86
|
+
work_agent_system_prompt = conversation_history.pop(0)
|
87
|
+
if conversation_history:
|
88
|
+
# 获取原始内容
|
89
|
+
original_content = work_agent_system_prompt["content"]
|
90
|
+
|
91
|
+
# 定义正则表达式
|
92
|
+
regex = r"<latest_file_content>(.*?)</latest_file_content>"
|
93
|
+
|
94
|
+
# 进行匹配
|
95
|
+
match = re.search(regex, original_content, re.DOTALL)
|
96
|
+
|
97
|
+
# 提取内容或设置为空字符串
|
98
|
+
if match:
|
99
|
+
extracted_content = f"<latest_file_content>{match.group(1)}</latest_file_content>\n\n"
|
100
|
+
else:
|
101
|
+
extracted_content = ""
|
102
|
+
|
103
|
+
conversation_history[0]["content"] = extracted_content + conversation_history[0]["content"]
|
104
|
+
|
105
|
+
instruction_agent.conversation["default"][1:] = conversation_history
|
106
|
+
if "find_and_click_element" in str(tools_json):
|
107
|
+
instruction_prompt = await get_current_screen_image_message(instruction_prompt)
|
108
|
+
next_instruction = await instruction_agent.ask_async(instruction_prompt)
|
109
|
+
print("\n🤖 指令智能体生成的下一步指令:", next_instruction)
|
110
|
+
if "fetch_gpt_response_stream HTTP Error', 'status_code': 404" in next_instruction:
|
111
|
+
raise Exception(f"Model: {instruction_agent_config['engine']} not found!")
|
112
|
+
if "'status_code': 413" in next_instruction:
|
113
|
+
raise Exception(f"The request body is too long, please try again.")
|
114
|
+
next_instruction = extract_xml_content(next_instruction, "instructions")
|
115
|
+
if not next_instruction:
|
116
|
+
print("\n❌ 指令智能体生成的指令不符合要求,请重新生成。")
|
117
|
+
continue
|
118
|
+
else:
|
119
|
+
if conversation_history == []:
|
120
|
+
next_instruction = (
|
121
|
+
"任务描述:\n"
|
122
|
+
f"{goal}\n\n"
|
123
|
+
"现在开始执行第一步:\n"
|
124
|
+
f"{next_instruction}"
|
125
|
+
)
|
126
|
+
break
|
127
|
+
return next_instruction
|
128
|
+
|
129
|
+
need_instruction = True
|
130
|
+
while True:
|
131
|
+
next_instruction = ''
|
132
|
+
if need_instruction:
|
133
|
+
next_instruction = await instruction_agent_task()
|
134
|
+
|
135
|
+
# 检查任务是否完成
|
136
|
+
if "任务已完成" in next_instruction:
|
137
|
+
print("\n✅ 任务已完成!")
|
138
|
+
break
|
139
|
+
if "find_and_click_element" in str(tools_json):
|
140
|
+
next_instruction = await get_current_screen_image_message(next_instruction)
|
141
|
+
result = await work_agent.ask_async(next_instruction)
|
142
|
+
if result.strip() == '' or result.strip() == '</content>\n</write_to_file>':
|
143
|
+
print("\n❌ 工作智能体回复为空,请重新生成指令。")
|
144
|
+
need_instruction = False
|
145
|
+
continue
|
146
|
+
print("✅ 工作智能体回复:", result)
|
147
|
+
need_instruction = True
|
148
|
+
|
149
|
+
return "任务已完成"
|
150
|
+
|
151
|
+
async def worker_gen(goal, tools, work_dir, cache_messages=None):
|
152
|
+
tools_json = [value for _, value in get_function_call_list(tools).items()]
|
153
|
+
work_agent_system_prompt = system_prompt.format(
|
154
|
+
os_version=platform.platform(),
|
155
|
+
workspace_path=work_dir,
|
156
|
+
shell=os.getenv('SHELL', 'Unknown'),
|
157
|
+
tools_list=tools_json
|
158
|
+
)
|
159
|
+
|
160
|
+
work_agent_config = {
|
161
|
+
"api_key": os.getenv("API_KEY"),
|
162
|
+
"api_url": os.getenv("BASE_URL"),
|
163
|
+
"engine": os.getenv("MODEL"),
|
164
|
+
"system_prompt": work_agent_system_prompt,
|
165
|
+
"print_log": True,
|
166
|
+
# "max_tokens": 8000,
|
167
|
+
"temperature": 0.5,
|
168
|
+
"function_call_max_loop": 100,
|
169
|
+
}
|
170
|
+
if cache_messages:
|
171
|
+
work_agent_config["cache_messages"] = cache_messages
|
172
|
+
|
173
|
+
instruction_agent_config = {
|
174
|
+
"api_key": os.getenv("API_KEY"),
|
175
|
+
"api_url": os.getenv("BASE_URL"),
|
176
|
+
"engine": os.getenv("MODEL"),
|
177
|
+
"system_prompt": instruction_system_prompt.format(os_version=platform.platform(), tools_list=tools_json, workspace_path=work_dir, current_time=datetime.now().strftime("%Y-%m-%d %H:%M:%S")),
|
178
|
+
"print_log": False,
|
179
|
+
# "max_tokens": 4000,
|
180
|
+
"temperature": 0.7,
|
181
|
+
"use_plugins": False,
|
182
|
+
}
|
183
|
+
|
184
|
+
# 工作agent初始化
|
185
|
+
work_agent = chatgpt(**work_agent_config)
|
186
|
+
async def instruction_agent_task():
|
187
|
+
while True:
|
188
|
+
|
189
|
+
instruction_prompt = f"""
|
190
|
+
</work_agent_conversation_end>
|
191
|
+
任务目标: {goal}
|
192
|
+
|
193
|
+
在 tag <work_agent_conversation_start>...</work_agent_conversation_end> 之前的对话历史都是工作智能体的对话历史。
|
194
|
+
|
195
|
+
根据以上对话历史和目标,请生成下一步指令。如果任务已完成,请回复"任务已完成"。
|
196
|
+
"""
|
197
|
+
# 让指令agent分析对话历史并生成新指令
|
198
|
+
instruction_agent = chatgpt(**instruction_agent_config)
|
199
|
+
conversation_history = copy.deepcopy(work_agent.conversation["default"])
|
200
|
+
|
201
|
+
cache_dir = os.path.join(work_dir, ".beswarm")
|
202
|
+
os.makedirs(cache_dir, exist_ok=True)
|
203
|
+
cache_file = os.path.join(cache_dir, "work_agent_conversation_history.json")
|
204
|
+
with open(cache_file, "w", encoding="utf-8") as f:
|
205
|
+
f.write(json.dumps(conversation_history, ensure_ascii=False, indent=4))
|
206
|
+
|
207
|
+
work_agent_system_prompt = conversation_history.pop(0)
|
208
|
+
if conversation_history:
|
209
|
+
# 获取原始内容
|
210
|
+
original_content = work_agent_system_prompt["content"]
|
211
|
+
|
212
|
+
# 定义正则表达式
|
213
|
+
regex = r"<latest_file_content>(.*?)</latest_file_content>"
|
214
|
+
|
215
|
+
# 进行匹配
|
216
|
+
match = re.search(regex, original_content, re.DOTALL)
|
217
|
+
|
218
|
+
# 提取内容或设置为空字符串
|
219
|
+
if match:
|
220
|
+
extracted_content = f"<latest_file_content>{match.group(1)}</latest_file_content>\n\n"
|
221
|
+
else:
|
222
|
+
extracted_content = ""
|
223
|
+
|
224
|
+
conversation_history[0]["content"] = extracted_content + conversation_history[0]["content"]
|
225
|
+
|
226
|
+
instruction_agent.conversation["default"][1:] = conversation_history
|
227
|
+
if "find_and_click_element" in str(tools_json):
|
228
|
+
instruction_prompt = await get_current_screen_image_message(instruction_prompt)
|
229
|
+
next_instruction = await instruction_agent.ask_async(instruction_prompt)
|
230
|
+
print("\n🤖 指令智能体生成的下一步指令:", next_instruction)
|
231
|
+
if "fetch_gpt_response_stream HTTP Error', 'status_code': 404" in next_instruction:
|
232
|
+
raise Exception(f"Model: {instruction_agent_config['engine']} not found!")
|
233
|
+
if "'status_code': 413" in next_instruction:
|
234
|
+
raise Exception(f"The request body is too long, please try again.")
|
235
|
+
next_instruction = extract_xml_content(next_instruction, "instructions")
|
236
|
+
if not next_instruction:
|
237
|
+
print("\n❌ 指令智能体生成的指令不符合要求,请重新生成。")
|
238
|
+
continue
|
239
|
+
else:
|
240
|
+
if conversation_history == []:
|
241
|
+
next_instruction = (
|
242
|
+
"任务描述:\n"
|
243
|
+
f"{goal}\n\n"
|
244
|
+
"现在开始执行第一步:\n"
|
245
|
+
f"{next_instruction}"
|
246
|
+
)
|
247
|
+
break
|
248
|
+
return next_instruction
|
249
|
+
|
250
|
+
need_instruction = True
|
251
|
+
while True:
|
252
|
+
next_instruction = ''
|
253
|
+
if need_instruction:
|
254
|
+
next_instruction = await instruction_agent_task()
|
255
|
+
|
256
|
+
yield {"user": next_instruction}
|
257
|
+
|
258
|
+
# 检查任务是否完成
|
259
|
+
if "任务已完成" in next_instruction:
|
260
|
+
print("\n✅ 任务已完成!")
|
261
|
+
break
|
262
|
+
if "find_and_click_element" in str(tools_json):
|
263
|
+
next_instruction = await get_current_screen_image_message(next_instruction)
|
264
|
+
result = await work_agent.ask_async(next_instruction)
|
265
|
+
if result.strip() == '' or result.strip() == '</content>\n</write_to_file>':
|
266
|
+
print("\n❌ 工作智能体回复为空,请重新生成指令。")
|
267
|
+
need_instruction = False
|
268
|
+
continue
|
269
|
+
yield {"assistant": result}
|
270
|
+
print("✅ 工作智能体回复:", result)
|
271
|
+
need_instruction = True
|
@@ -1,130 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import copy
|
3
|
-
import json
|
4
|
-
import platform
|
5
|
-
from datetime import datetime
|
6
|
-
|
7
|
-
from ..aient.src.aient.models import chatgpt
|
8
|
-
from ..aient.src.aient.plugins import register_tool, get_function_call_list
|
9
|
-
from ..aient.src.aient.prompt import system_prompt, instruction_system_prompt
|
10
|
-
from ..utils import extract_xml_content, get_current_screen_image_message
|
11
|
-
|
12
|
-
@register_tool()
|
13
|
-
async def worker(goal, tools, work_dir, cache_messages=None):
|
14
|
-
"""
|
15
|
-
启动一个 **工作智能体 (Worker Agent)** 来自动完成指定的任务目标 (`goal`)。
|
16
|
-
|
17
|
-
这个工作智能体接收一个清晰的任务描述、一组可供调用的工具 (`tools`),以及一个工作目录 (`work_dir`)。
|
18
|
-
它会利用语言模型的能力,结合可用的工具,自主规划并逐步执行必要的操作,直到最终完成指定的任务目标。
|
19
|
-
核心功能是根据输入的目标,驱动整个任务执行流程。
|
20
|
-
|
21
|
-
Args:
|
22
|
-
goal (str): 需要完成的具体任务目标描述。工作智能体将围绕此目标进行工作。必须清晰、具体。
|
23
|
-
tools (list[str]): 一个包含可用工具函数对象的列表。工作智能体在执行任务时可能会调用这些工具来与环境交互(例如读写文件、执行命令等)。
|
24
|
-
work_dir (str): 工作目录的绝对路径。工作智能体将在此目录上下文中执行操作。
|
25
|
-
|
26
|
-
Returns:
|
27
|
-
str: 当任务成功完成时,返回字符串 "任务已完成"。
|
28
|
-
"""
|
29
|
-
|
30
|
-
tools_json = [value for _, value in get_function_call_list(tools).items()]
|
31
|
-
work_agent_system_prompt = system_prompt.format(
|
32
|
-
os_version=platform.platform(),
|
33
|
-
workspace_path=work_dir,
|
34
|
-
shell=os.getenv('SHELL', 'Unknown'),
|
35
|
-
tools_list=tools_json
|
36
|
-
)
|
37
|
-
|
38
|
-
work_agent_config = {
|
39
|
-
"api_key": os.getenv("API_KEY"),
|
40
|
-
"api_url": os.getenv("BASE_URL"),
|
41
|
-
"engine": os.getenv("MODEL"),
|
42
|
-
"system_prompt": work_agent_system_prompt,
|
43
|
-
"print_log": True,
|
44
|
-
# "max_tokens": 8000,
|
45
|
-
"temperature": 0.5,
|
46
|
-
"function_call_max_loop": 100,
|
47
|
-
}
|
48
|
-
if cache_messages:
|
49
|
-
work_agent_config["cache_messages"] = cache_messages
|
50
|
-
|
51
|
-
instruction_agent_config = {
|
52
|
-
"api_key": os.getenv("API_KEY"),
|
53
|
-
"api_url": os.getenv("BASE_URL"),
|
54
|
-
"engine": os.getenv("MODEL"),
|
55
|
-
"system_prompt": instruction_system_prompt.format(os_version=platform.platform(), tools_list=tools_json, workspace_path=work_dir, current_time=datetime.now().strftime("%Y-%m-%d %H:%M:%S")),
|
56
|
-
"print_log": False,
|
57
|
-
# "max_tokens": 4000,
|
58
|
-
"temperature": 0.7,
|
59
|
-
"use_plugins": False,
|
60
|
-
}
|
61
|
-
|
62
|
-
# 工作agent初始化
|
63
|
-
work_agent = chatgpt(**work_agent_config)
|
64
|
-
async def instruction_agent_task():
|
65
|
-
while True:
|
66
|
-
|
67
|
-
instruction_prompt = f"""
|
68
|
-
</work_agent_conversation_end>
|
69
|
-
任务目标: {goal}
|
70
|
-
|
71
|
-
在 tag <work_agent_conversation_start>...</work_agent_conversation_end> 之前的对话历史都是工作智能体的对话历史。
|
72
|
-
|
73
|
-
根据以上对话历史和目标,请生成下一步指令。如果任务已完成,请回复"任务已完成"。
|
74
|
-
"""
|
75
|
-
# 让指令agent分析对话历史并生成新指令
|
76
|
-
instruction_agent = chatgpt(**instruction_agent_config)
|
77
|
-
conversation_history = copy.deepcopy(work_agent.conversation["default"])
|
78
|
-
|
79
|
-
cache_dir = os.path.join(work_dir, ".beswarm")
|
80
|
-
os.makedirs(cache_dir, exist_ok=True)
|
81
|
-
cache_file = os.path.join(cache_dir, "work_agent_conversation_history.json")
|
82
|
-
with open(cache_file, "w", encoding="utf-8") as f:
|
83
|
-
f.write(json.dumps(conversation_history, ensure_ascii=False, indent=4))
|
84
|
-
|
85
|
-
conversation_history.pop(0)
|
86
|
-
instruction_agent.conversation["default"][1:] = conversation_history
|
87
|
-
if "find_and_click_element" in str(tools_json):
|
88
|
-
instruction_prompt = await get_current_screen_image_message(instruction_prompt)
|
89
|
-
next_instruction = await instruction_agent.ask_async(instruction_prompt)
|
90
|
-
print("\n🤖 指令智能体生成的下一步指令:", next_instruction)
|
91
|
-
if "fetch_gpt_response_stream HTTP Error', 'status_code': 404" in next_instruction:
|
92
|
-
raise Exception(f"Model: {instruction_agent_config['engine']} not found!")
|
93
|
-
if "'status_code': 413" in next_instruction:
|
94
|
-
raise Exception(f"The request body is too long, please try again.")
|
95
|
-
next_instruction = extract_xml_content(next_instruction, "instructions")
|
96
|
-
if not next_instruction:
|
97
|
-
print("\n❌ 指令智能体生成的指令不符合要求,请重新生成。")
|
98
|
-
continue
|
99
|
-
else:
|
100
|
-
if conversation_history == []:
|
101
|
-
next_instruction = (
|
102
|
-
"任务描述:\n"
|
103
|
-
f"{goal}\n\n"
|
104
|
-
"现在开始执行第一步:\n"
|
105
|
-
f"{next_instruction}"
|
106
|
-
)
|
107
|
-
break
|
108
|
-
return next_instruction
|
109
|
-
|
110
|
-
need_instruction = True
|
111
|
-
while True:
|
112
|
-
next_instruction = ''
|
113
|
-
if need_instruction:
|
114
|
-
next_instruction = await instruction_agent_task()
|
115
|
-
|
116
|
-
# 检查任务是否完成
|
117
|
-
if "任务已完成" in next_instruction:
|
118
|
-
print("\n✅ 任务已完成!")
|
119
|
-
break
|
120
|
-
if "find_and_click_element" in str(tools_json):
|
121
|
-
next_instruction = await get_current_screen_image_message(next_instruction)
|
122
|
-
result = await work_agent.ask_async(next_instruction)
|
123
|
-
if result.strip() == '' or result.strip() == '</content>\n</write_to_file>':
|
124
|
-
print("\n❌ 工作智能体回复为空,请重新生成指令。")
|
125
|
-
need_instruction = False
|
126
|
-
continue
|
127
|
-
print("✅ 工作智能体回复:", result)
|
128
|
-
need_instruction = True
|
129
|
-
|
130
|
-
return "任务已完成"
|
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.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/arduino-tags.scm
RENAMED
File without changes
|
File without changes
|
{beswarm-0.1.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/chatito-tags.scm
RENAMED
File without changes
|
{beswarm-0.1.61 → beswarm-0.1.63}/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.61 → beswarm-0.1.63}/beswarm/queries/tree-sitter-language-pack/javascript-tags.scm
RENAMED
File without changes
|
File without changes
|
File without changes
|
{beswarm-0.1.61 → beswarm-0.1.63}/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.61 → beswarm-0.1.63}/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
|