beswarm 0.3.13__py3-none-any.whl → 0.3.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- beswarm/aient/aient/architext/architext/core.py +9 -1
- beswarm/aient/aient/architext/test/test.py +26 -0
- beswarm/aient/aient/core/request.py +10 -7
- beswarm/aient/aient/core/utils.py +1 -1
- beswarm/aient/aient/models/chatgpt.py +17 -0
- {beswarm-0.3.13.dist-info → beswarm-0.3.14.dist-info}/METADATA +1 -1
- {beswarm-0.3.13.dist-info → beswarm-0.3.14.dist-info}/RECORD +10 -10
- {beswarm-0.3.13.dist-info → beswarm-0.3.14.dist-info}/WHEEL +0 -0
- {beswarm-0.3.13.dist-info → beswarm-0.3.14.dist-info}/entry_points.txt +0 -0
- {beswarm-0.3.13.dist-info → beswarm-0.3.14.dist-info}/top_level.txt +0 -0
@@ -423,8 +423,16 @@ class Message(ABC):
|
|
423
423
|
processed_items.append(Images(url=image_url))
|
424
424
|
else:
|
425
425
|
raise ValueError(f"Unsupported item type in list: {item_type}")
|
426
|
+
elif isinstance(item, dict):
|
427
|
+
item_type = item.get('type')
|
428
|
+
if item_type == 'image_url':
|
429
|
+
image_url = item.get('image_url', {}).get('url')
|
430
|
+
if image_url:
|
431
|
+
processed_items.append(Images(url=image_url))
|
432
|
+
else:
|
433
|
+
raise ValueError(f"Unsupported dict item type: {item_type}")
|
426
434
|
else:
|
427
|
-
raise TypeError(f"Unsupported item type: {type(item)}. Must be str, ContextProvider, or
|
435
|
+
raise TypeError(f"Unsupported item type: {type(item)}. Must be str, ContextProvider, list, or dict.")
|
428
436
|
self._items: List[ContextProvider] = processed_items
|
429
437
|
self._parent_messages: Optional['Messages'] = None
|
430
438
|
|
@@ -1884,6 +1884,32 @@ Files: {Files(visible=True, name="files")}
|
|
1884
1884
|
if os.path.exists(non_existent_file):
|
1885
1885
|
os.remove(non_existent_file)
|
1886
1886
|
|
1887
|
+
async def test_auto_convert_image_dict_to_image_provider(self):
|
1888
|
+
"""测试 UserMessage 是否能自动转换 image_url 字典为 Images provider"""
|
1889
|
+
base64_image_data = "/9j/4AAQSkZJRgABAQEAYABgAAD/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAEAAAAAAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAABAAEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKAP/2Q=="
|
1890
|
+
image_dict = {
|
1891
|
+
'type': 'image_url',
|
1892
|
+
'image_url': {
|
1893
|
+
'url': f'data:image/jpeg;base64,{base64_image_data}'
|
1894
|
+
}
|
1895
|
+
}
|
1896
|
+
|
1897
|
+
# This is the functionality we are testing.
|
1898
|
+
# The UserMessage should be able to take this dictionary directly.
|
1899
|
+
message = UserMessage(image_dict)
|
1900
|
+
|
1901
|
+
# 1. Verify that the message contains exactly one provider.
|
1902
|
+
self.assertEqual(len(message.provider()), 1)
|
1903
|
+
|
1904
|
+
# 2. Verify that the provider is an instance of the Images class.
|
1905
|
+
image_provider = message.provider()[0]
|
1906
|
+
self.assertIsInstance(image_provider, Images)
|
1907
|
+
|
1908
|
+
# 3. Verify that the content of the Images provider is correct.
|
1909
|
+
rendered = await message.render_latest()
|
1910
|
+
self.assertEqual(rendered['content'][0]['image_url']['url'], image_dict['image_url']['url'])
|
1911
|
+
|
1912
|
+
|
1887
1913
|
# ==============================================================================
|
1888
1914
|
# 6. 演示
|
1889
1915
|
# ==============================================================================
|
@@ -295,7 +295,7 @@ async def get_gemini_payload(request, engine, provider, api_key=None):
|
|
295
295
|
if key == request.model:
|
296
296
|
for k, v in value.items():
|
297
297
|
payload[k] = v
|
298
|
-
elif all(_model not in request.model.lower() for _model in model_dict.keys()) and "-" not in key:
|
298
|
+
elif all(_model not in request.model.lower() for _model in model_dict.keys()) and "-" not in key and " " not in key:
|
299
299
|
payload[key] = value
|
300
300
|
|
301
301
|
return url, headers, payload
|
@@ -591,7 +591,7 @@ async def get_vertex_gemini_payload(request, engine, provider, api_key=None):
|
|
591
591
|
if key == request.model:
|
592
592
|
for k, v in value.items():
|
593
593
|
payload[k] = v
|
594
|
-
elif all(_model not in request.model.lower() for _model in model_dict.keys()) and "-" not in key:
|
594
|
+
elif all(_model not in request.model.lower() for _model in model_dict.keys()) and "-" not in key and " " not in key:
|
595
595
|
payload[key] = value
|
596
596
|
|
597
597
|
return url, headers, payload
|
@@ -1116,6 +1116,9 @@ async def get_gpt_payload(request, engine, provider, api_key=None):
|
|
1116
1116
|
if "temperature" in payload:
|
1117
1117
|
payload.pop("temperature")
|
1118
1118
|
|
1119
|
+
if "v1/responses" in url:
|
1120
|
+
payload.pop("stream_options", None)
|
1121
|
+
|
1119
1122
|
# 代码生成/数学解题 0.0
|
1120
1123
|
# 数据抽取/分析 1.0
|
1121
1124
|
# 通用对话 1.3
|
@@ -1149,7 +1152,7 @@ async def get_gpt_payload(request, engine, provider, api_key=None):
|
|
1149
1152
|
if key == request.model:
|
1150
1153
|
for k, v in value.items():
|
1151
1154
|
payload[k] = v
|
1152
|
-
elif all(_model not in request.model.lower() for _model in model_dict.keys()) and "-" not in key:
|
1155
|
+
elif all(_model not in request.model.lower() for _model in model_dict.keys()) and "-" not in key and " " not in key:
|
1153
1156
|
payload[key] = value
|
1154
1157
|
|
1155
1158
|
return url, headers, payload
|
@@ -1247,7 +1250,7 @@ async def get_azure_payload(request, engine, provider, api_key=None):
|
|
1247
1250
|
if key == request.model:
|
1248
1251
|
for k, v in value.items():
|
1249
1252
|
payload[k] = v
|
1250
|
-
elif all(_model not in request.model.lower() for _model in model_dict.keys()) and "-" not in key:
|
1253
|
+
elif all(_model not in request.model.lower() for _model in model_dict.keys()) and "-" not in key and " " not in key:
|
1251
1254
|
payload[key] = value
|
1252
1255
|
|
1253
1256
|
return url, headers, payload
|
@@ -1367,7 +1370,7 @@ async def get_azure_databricks_payload(request, engine, provider, api_key=None):
|
|
1367
1370
|
if key == request.model:
|
1368
1371
|
for k, v in value.items():
|
1369
1372
|
payload[k] = v
|
1370
|
-
elif all(_model not in request.model.lower() for _model in model_dict.keys()) and "-" not in key:
|
1373
|
+
elif all(_model not in request.model.lower() for _model in model_dict.keys()) and "-" not in key and " " not in key:
|
1371
1374
|
payload[key] = value
|
1372
1375
|
|
1373
1376
|
return url, headers, payload
|
@@ -1454,7 +1457,7 @@ async def get_openrouter_payload(request, engine, provider, api_key=None):
|
|
1454
1457
|
if key == request.model:
|
1455
1458
|
for k, v in value.items():
|
1456
1459
|
payload[k] = v
|
1457
|
-
elif all(_model not in request.model.lower() for _model in model_dict.keys()) and "-" not in key:
|
1460
|
+
elif all(_model not in request.model.lower() for _model in model_dict.keys()) and "-" not in key and " " not in key:
|
1458
1461
|
payload[key] = value
|
1459
1462
|
|
1460
1463
|
return url, headers, payload
|
@@ -1820,7 +1823,7 @@ async def get_claude_payload(request, engine, provider, api_key=None):
|
|
1820
1823
|
if key == request.model:
|
1821
1824
|
for k, v in value.items():
|
1822
1825
|
payload[k] = v
|
1823
|
-
elif all(_model not in request.model.lower() for _model in model_dict.keys()) and "-" not in key:
|
1826
|
+
elif all(_model not in request.model.lower() for _model in model_dict.keys()) and "-" not in key and " " not in key:
|
1824
1827
|
payload[key] = value
|
1825
1828
|
|
1826
1829
|
return url, headers, payload
|
@@ -52,7 +52,7 @@ class BaseAPI:
|
|
52
52
|
self.v1_models: str = urlunparse(parsed_url[:2] + (before_v1 + "models",) + ("",) * 3)
|
53
53
|
|
54
54
|
if "v1/responses" in parsed_url.path:
|
55
|
-
self.chat_url: str =
|
55
|
+
self.chat_url: str = api_url
|
56
56
|
else:
|
57
57
|
self.chat_url: str = urlunparse(parsed_url[:2] + (before_v1 + "chat/completions",) + ("",) * 3)
|
58
58
|
self.image_url: str = urlunparse(parsed_url[:2] + (before_v1 + "images/generations",) + ("",) * 3)
|
@@ -89,6 +89,13 @@ class RepetitiveResponseError(Exception):
|
|
89
89
|
self.count = count
|
90
90
|
|
91
91
|
|
92
|
+
class AllToolsMissingParametersError(Exception):
|
93
|
+
"""Custom exception for when all tools are missing required parameters."""
|
94
|
+
def __init__(self, message, response_text):
|
95
|
+
super().__init__(message)
|
96
|
+
self.response_text = response_text
|
97
|
+
|
98
|
+
|
92
99
|
class chatgpt(BaseLLM):
|
93
100
|
"""
|
94
101
|
Official ChatGPT API
|
@@ -500,6 +507,9 @@ class chatgpt(BaseLLM):
|
|
500
507
|
missing_required_params.append(f"Error: {tool_name} missing required parameters: {missing_required_params}")
|
501
508
|
function_parameter = valid_function_parameters
|
502
509
|
|
510
|
+
if not function_parameter and missing_required_params:
|
511
|
+
raise AllToolsMissingParametersError("\n\n".join(missing_required_params), response_text=full_response)
|
512
|
+
|
503
513
|
# 删除 task_complete 跟其他工具一起调用的情况,因为 task_complete 必须单独调用
|
504
514
|
if len(function_parameter) > 1:
|
505
515
|
function_parameter = [tool_dict for tool_dict in function_parameter if tool_dict.get("function_name", "") != "task_complete"]
|
@@ -810,6 +820,13 @@ class chatgpt(BaseLLM):
|
|
810
820
|
{"role": "user", "content": "你的消息没有以[done]结尾,请重新输出"}
|
811
821
|
]
|
812
822
|
continue
|
823
|
+
except AllToolsMissingParametersError as e:
|
824
|
+
self.logger.warning(f"All tools are missing required parameters: {e}. Retrying with corrective prompt.")
|
825
|
+
need_done_prompt = [
|
826
|
+
{"role": "assistant", "content": e.response_text},
|
827
|
+
{"role": "user", "content": f"{e.message},请重新输出"}
|
828
|
+
]
|
829
|
+
continue
|
813
830
|
except EmptyResponseError as e:
|
814
831
|
self.logger.warning(f"{e}, retrying...")
|
815
832
|
continue
|
@@ -10,16 +10,16 @@ beswarm/agents/chatgroup.py,sha256=PzrmRcDKAbB7cxL16nMod_CzPosDV6bfTmXxQVuv-AQ,1
|
|
10
10
|
beswarm/agents/planact.py,sha256=dhPkMUaZLc1dO0TrI1Orr_i60iLzJHQIYBI_QjjSJwI,18723
|
11
11
|
beswarm/aient/aient/__init__.py,sha256=SRfF7oDVlOOAi6nGKiJIUK6B_arqYLO9iSMp-2IZZps,21
|
12
12
|
beswarm/aient/aient/architext/architext/__init__.py,sha256=79Ih1151rfcqZdr7F8HSZSTs_iT2SKd1xCkehMsXeXs,19
|
13
|
-
beswarm/aient/aient/architext/architext/core.py,sha256=
|
13
|
+
beswarm/aient/aient/architext/architext/core.py,sha256=E5QTM0NNoHPxRawH_Lmb01azAAlmLlm0bPy5c78zG38,37972
|
14
14
|
beswarm/aient/aient/architext/test/openai_client.py,sha256=Dqtbmubv6vwF8uBqcayG0kbsiO65of7sgU2-DRBi-UM,4590
|
15
|
-
beswarm/aient/aient/architext/test/test.py,sha256=
|
15
|
+
beswarm/aient/aient/architext/test/test.py,sha256=c6wHwo8DQL5yeEQ3T1lqMleHJ9M5Sifnk4Qqk64Vv7w,90970
|
16
16
|
beswarm/aient/aient/architext/test/test_save_load.py,sha256=o8DqH6gDYZkFkQy-a7blqLtJTRj5e4a-Lil48pJ0V3g,3260
|
17
17
|
beswarm/aient/aient/core/__init__.py,sha256=NxjebTlku35S4Dzr16rdSqSTWUvvwEeACe8KvHJnjPg,34
|
18
18
|
beswarm/aient/aient/core/log_config.py,sha256=kz2_yJv1p-o3lUQOwA3qh-LSc3wMHv13iCQclw44W9c,274
|
19
19
|
beswarm/aient/aient/core/models.py,sha256=KMlCRLjtq1wQHZTJGqnbWhPS2cHq6eLdnk7peKDrzR8,7490
|
20
|
-
beswarm/aient/aient/core/request.py,sha256=
|
20
|
+
beswarm/aient/aient/core/request.py,sha256=s9cRpSLmuujuPxqKfmT8X1_eRby4z3NREjlSEG5Bwzg,78052
|
21
21
|
beswarm/aient/aient/core/response.py,sha256=VYpXfF6RO3Y-fTZMGV2p-bcrd73BPAKlz33gQkOcqjE,38462
|
22
|
-
beswarm/aient/aient/core/utils.py,sha256=
|
22
|
+
beswarm/aient/aient/core/utils.py,sha256=jlEjtsCnnUxp-z9NLCiDbLBxEd9AE0zEWxnpjq7_5ao,31700
|
23
23
|
beswarm/aient/aient/core/test/test_base_api.py,sha256=pWnycRJbuPSXKKU9AQjWrMAX1wiLC_014Qc9hh5C2Pw,524
|
24
24
|
beswarm/aient/aient/core/test/test_geminimask.py,sha256=HFX8jDbNg_FjjgPNxfYaR-0-roUrOO-ND-FVsuxSoiw,13254
|
25
25
|
beswarm/aient/aient/core/test/test_image.py,sha256=_T4peNGdXKBHHxyQNx12u-NTyFE8TlYI6NvvagsG2LE,319
|
@@ -27,7 +27,7 @@ beswarm/aient/aient/core/test/test_payload.py,sha256=8jBiJY1uidm1jzL-EiK0s6UGmW9
|
|
27
27
|
beswarm/aient/aient/models/__init__.py,sha256=ZTiZgbfBPTjIPSKURE7t6hlFBVLRS9lluGbmqc1WjxQ,43
|
28
28
|
beswarm/aient/aient/models/audio.py,sha256=FNW4lxG1IhxOU7L8mvcbaeC1nXk_lpUZQlg9ijQ0h_Q,1937
|
29
29
|
beswarm/aient/aient/models/base.py,sha256=HWIGfa2A7OTccvHK0wG1-UlHB-yaWRC7hbi4oR1Mu1Y,7228
|
30
|
-
beswarm/aient/aient/models/chatgpt.py,sha256=
|
30
|
+
beswarm/aient/aient/models/chatgpt.py,sha256=lhn2Q2iSIB_edXgEv8bP7t4JZK1e3pZiImXjSMJR54Y,44736
|
31
31
|
beswarm/aient/aient/plugins/__init__.py,sha256=p3KO6Aa3Lupos4i2SjzLQw1hzQTigOAfEHngsldrsyk,986
|
32
32
|
beswarm/aient/aient/plugins/arXiv.py,sha256=yHjb6PS3GUWazpOYRMKMzghKJlxnZ5TX8z9F6UtUVow,1461
|
33
33
|
beswarm/aient/aient/plugins/config.py,sha256=TGgZ5SnNKZ8MmdznrZ-TEq7s2ulhAAwTSKH89bci3dA,7079
|
@@ -121,8 +121,8 @@ beswarm/tools/subtasks.py,sha256=Fsf_542CkECcwFwxD-F38_IUsmk06xe1P7e6pBPTy4Y,128
|
|
121
121
|
beswarm/tools/worker.py,sha256=mQ1qdrQ8MgL99byAbTvxfEByFFGN9mty3UHqHjARMQ8,2331
|
122
122
|
beswarm/tools/write_csv.py,sha256=u0Hq18Ksfheb52MVtyLNCnSDHibITpsYBPs2ub7USYA,1466
|
123
123
|
beswarm/tools/write_file.py,sha256=L2coBqz-aRFxPBvJBrbWbUJhu7p3oKAAGb9R144bFtk,4926
|
124
|
-
beswarm-0.3.
|
125
|
-
beswarm-0.3.
|
126
|
-
beswarm-0.3.
|
127
|
-
beswarm-0.3.
|
128
|
-
beswarm-0.3.
|
124
|
+
beswarm-0.3.14.dist-info/METADATA,sha256=7EF549W5qhomzsWEHBSdg4ZJwQttF1VC72muLl2F9Jo,3878
|
125
|
+
beswarm-0.3.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
126
|
+
beswarm-0.3.14.dist-info/entry_points.txt,sha256=URK7Y4PDzBgxIecQnxsWTu4O-eaFa1CoAcNTWh5R7LM,45
|
127
|
+
beswarm-0.3.14.dist-info/top_level.txt,sha256=pJw4O87wvt5882smuSO6DfByJz7FJ8SxxT8h9fHCmpo,8
|
128
|
+
beswarm-0.3.14.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|