aient 1.2.26__py3-none-any.whl → 1.2.28__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.
- aient/architext/architext/core.py +9 -0
- aient/architext/test/test.py +20 -0
- aient/core/response.py +3 -2
- aient/core/utils.py +38 -0
- {aient-1.2.26.dist-info → aient-1.2.28.dist-info}/METADATA +1 -1
- {aient-1.2.26.dist-info → aient-1.2.28.dist-info}/RECORD +9 -9
- {aient-1.2.26.dist-info → aient-1.2.28.dist-info}/WHEEL +0 -0
- {aient-1.2.26.dist-info → aient-1.2.28.dist-info}/licenses/LICENSE +0 -0
- {aient-1.2.26.dist-info → aient-1.2.28.dist-info}/top_level.txt +0 -0
@@ -315,6 +315,8 @@ class Message(ABC):
|
|
315
315
|
self.role = role
|
316
316
|
processed_items = []
|
317
317
|
for item in initial_items:
|
318
|
+
if item is None:
|
319
|
+
continue
|
318
320
|
if isinstance(item, str):
|
319
321
|
# Check if the string contains placeholders from f-string rendering
|
320
322
|
import re
|
@@ -471,6 +473,13 @@ class Message(ABC):
|
|
471
473
|
def get(self, key: str, default: Any = None) -> Any:
|
472
474
|
"""提供类似字典的 .get() 方法来访问属性。"""
|
473
475
|
return getattr(self, key, default)
|
476
|
+
|
477
|
+
async def render_latest(self) -> Optional[Dict[str, Any]]:
|
478
|
+
"""Refreshes all providers in the message and returns the rendered dictionary."""
|
479
|
+
tasks = [provider.refresh() for provider in self._items]
|
480
|
+
await asyncio.gather(*tasks)
|
481
|
+
return self.to_dict()
|
482
|
+
|
474
483
|
def to_dict(self) -> Optional[Dict[str, Any]]:
|
475
484
|
is_multimodal = any(isinstance(p, Images) for p in self._items)
|
476
485
|
|
aient/architext/test/test.py
CHANGED
@@ -1434,6 +1434,26 @@ Files: {Files(visible=True, name="files")}
|
|
1434
1434
|
self.assertTrue(message in messages_collection)
|
1435
1435
|
self.assertFalse(UserMessage("not in collection") in messages_collection)
|
1436
1436
|
|
1437
|
+
async def test_zz_none_input_ignored(self):
|
1438
|
+
"""测试在Message初始化时,None值是否被自动忽略"""
|
1439
|
+
# 1. 在初始化列表中包含 None
|
1440
|
+
message = UserMessage("Hello", None, "World")
|
1441
|
+
self.assertEqual(len(message.provider()), 2)
|
1442
|
+
self.assertIsInstance(message.provider()[0], Texts)
|
1443
|
+
self.assertIsInstance(message.provider()[1], Texts)
|
1444
|
+
rendered = await message.render_latest()
|
1445
|
+
self.assertEqual(rendered['content'], "HelloWorld")
|
1446
|
+
|
1447
|
+
# 2. 测试只有 None
|
1448
|
+
message_none = SystemMessage(None)
|
1449
|
+
self.assertEqual(len(message_none.provider()), 0)
|
1450
|
+
self.assertFalse(message_none)
|
1451
|
+
|
1452
|
+
# 3. 测试混合 provider 和 None
|
1453
|
+
message_mixed = SystemMessage(Texts("hi"), None)
|
1454
|
+
self.assertEqual(len(message_mixed.provider()), 1)
|
1455
|
+
self.assertIsInstance(message_mixed.provider()[0], Texts)
|
1456
|
+
|
1437
1457
|
|
1438
1458
|
# ==============================================================================
|
1439
1459
|
# 6. 演示
|
aient/core/response.py
CHANGED
@@ -8,7 +8,7 @@ from datetime import datetime
|
|
8
8
|
|
9
9
|
from .log_config import logger
|
10
10
|
|
11
|
-
from .utils import safe_get, generate_sse_response, generate_no_stream_response, end_of_line, parse_json_safely
|
11
|
+
from .utils import safe_get, generate_sse_response, generate_no_stream_response, end_of_line, parse_json_safely, upload_image_to_0x0st
|
12
12
|
|
13
13
|
async def check_response(response, error_log):
|
14
14
|
if response and not (200 <= response.status_code < 300):
|
@@ -277,7 +277,8 @@ async def fetch_gpt_response_stream(client, url, headers, payload, timeout):
|
|
277
277
|
openrouter_reasoning = safe_get(line, "choices", 0, "delta", "reasoning", default="")
|
278
278
|
openrouter_base64_image = safe_get(line, "choices", 0, "delta", "images", 0, "image_url", "url", default="")
|
279
279
|
if openrouter_base64_image:
|
280
|
-
|
280
|
+
image_url = await upload_image_to_0x0st(openrouter_base64_image)
|
281
|
+
sse_string = await generate_sse_response(timestamp, payload["model"], content=f"\n\n")
|
281
282
|
yield sse_string
|
282
283
|
continue
|
283
284
|
azure_databricks_claude_summary_content = safe_get(line, "choices", 0, "delta", "content", 0, "summary", 0, "text", default="")
|
aient/core/utils.py
CHANGED
@@ -797,6 +797,44 @@ def parse_json_safely(json_str):
|
|
797
797
|
# 两种方法都失败,抛出异常
|
798
798
|
raise Exception(f"无法解析JSON字符串: {e}, {json_str}")
|
799
799
|
|
800
|
+
async def upload_image_to_0x0st(base64_image: str):
|
801
|
+
"""
|
802
|
+
Uploads a base64 encoded image to 0x0.st.
|
803
|
+
|
804
|
+
Args:
|
805
|
+
base64_image: The base64 encoded image string.
|
806
|
+
|
807
|
+
Returns:
|
808
|
+
The URL of the uploaded image.
|
809
|
+
"""
|
810
|
+
if "," in base64_image:
|
811
|
+
base64_image_split = base64_image.split(",")[1]
|
812
|
+
|
813
|
+
image_data = base64.b64decode(base64_image_split)
|
814
|
+
|
815
|
+
img_format = get_image_format(image_data)
|
816
|
+
if not img_format:
|
817
|
+
img_format = 'png' # 如果无法检测到格式,则默认为 png
|
818
|
+
|
819
|
+
content_type = f'image/{img_format}'
|
820
|
+
file_name = f'image.{img_format}'
|
821
|
+
|
822
|
+
files = {'file': (file_name, image_data, content_type)}
|
823
|
+
data = {'expires': '24', 'secret': '123456'}
|
824
|
+
|
825
|
+
async with httpx.AsyncClient() as client:
|
826
|
+
try:
|
827
|
+
response = await client.post("https://0x0.st", files=files, data=data)
|
828
|
+
response.raise_for_status()
|
829
|
+
return response.text.strip()
|
830
|
+
except httpx.RequestError as e:
|
831
|
+
logger.error(f"请求 0x0.st 时出错: {e}")
|
832
|
+
# raise HTTPException(status_code=500, detail="上传图片到 0x0.st 失败")
|
833
|
+
except httpx.HTTPStatusError as e:
|
834
|
+
logger.error(f"上传图片到 0x0.st 时发生 HTTP 错误: {e.response.status_code}")
|
835
|
+
# raise HTTPException(status_code=e.response.status_code, detail=f"上传图片到 0x0.st 失败: {e.response.text}")
|
836
|
+
return base64_image
|
837
|
+
|
800
838
|
if __name__ == "__main__":
|
801
839
|
provider = {
|
802
840
|
"base_url": "https://gateway.ai.cloudflare.com/v1/%7Baccount_id%7D/%7Bgateway_id%7D/google-vertex-ai",
|
@@ -1,15 +1,15 @@
|
|
1
1
|
aient/__init__.py,sha256=SRfF7oDVlOOAi6nGKiJIUK6B_arqYLO9iSMp-2IZZps,21
|
2
2
|
aient/architext/architext/__init__.py,sha256=79Ih1151rfcqZdr7F8HSZSTs_iT2SKd1xCkehMsXeXs,19
|
3
|
-
aient/architext/architext/core.py,sha256=
|
3
|
+
aient/architext/architext/core.py,sha256=tfaAwdVN0Q1LK9Dz91Yyc83UJeVba-9LYgQ8cyp6xHQ,30887
|
4
4
|
aient/architext/test/openai_client.py,sha256=Dqtbmubv6vwF8uBqcayG0kbsiO65of7sgU2-DRBi-UM,4590
|
5
|
-
aient/architext/test/test.py,sha256=
|
5
|
+
aient/architext/test/test.py,sha256=uo1hSFnzV-8DeuPE0K3R0-K-cotitLEMidFj7SQn3UQ,67633
|
6
6
|
aient/architext/test/test_save_load.py,sha256=o8DqH6gDYZkFkQy-a7blqLtJTRj5e4a-Lil48pJ0V3g,3260
|
7
7
|
aient/core/__init__.py,sha256=NxjebTlku35S4Dzr16rdSqSTWUvvwEeACe8KvHJnjPg,34
|
8
8
|
aient/core/log_config.py,sha256=kz2_yJv1p-o3lUQOwA3qh-LSc3wMHv13iCQclw44W9c,274
|
9
9
|
aient/core/models.py,sha256=KMlCRLjtq1wQHZTJGqnbWhPS2cHq6eLdnk7peKDrzR8,7490
|
10
10
|
aient/core/request.py,sha256=QnDhyrjzcJOEQU2oauMQi_HHMRR5NxdkrX7nn5JMwTc,76675
|
11
|
-
aient/core/response.py,sha256=
|
12
|
-
aient/core/utils.py,sha256=
|
11
|
+
aient/core/response.py,sha256=Z9geTfh2LkGHKAqjelgeleQtfOAYIyM82t9AVB4xsgE,36407
|
12
|
+
aient/core/utils.py,sha256=gxgp5gMO-HQ9ItPNGBRAp8mskc31cXSRpZX9c2AWzEw,31437
|
13
13
|
aient/core/test/test_base_api.py,sha256=pWnycRJbuPSXKKU9AQjWrMAX1wiLC_014Qc9hh5C2Pw,524
|
14
14
|
aient/core/test/test_geminimask.py,sha256=HFX8jDbNg_FjjgPNxfYaR-0-roUrOO-ND-FVsuxSoiw,13254
|
15
15
|
aient/core/test/test_image.py,sha256=_T4peNGdXKBHHxyQNx12u-NTyFE8TlYI6NvvagsG2LE,319
|
@@ -35,8 +35,8 @@ aient/plugins/write_file.py,sha256=Jt8fOEwqhYiSWpCbwfAr1xoi_BmFnx3076GMhuL06uI,3
|
|
35
35
|
aient/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
36
|
aient/utils/prompt.py,sha256=UcSzKkFE4-h_1b6NofI6xgk3GoleqALRKY8VBaXLjmI,11311
|
37
37
|
aient/utils/scripts.py,sha256=VqtK4RFEx7KxkmcqG3lFDS1DxoNlFFGErEjopVcc8IE,40974
|
38
|
-
aient-1.2.
|
39
|
-
aient-1.2.
|
40
|
-
aient-1.2.
|
41
|
-
aient-1.2.
|
42
|
-
aient-1.2.
|
38
|
+
aient-1.2.28.dist-info/licenses/LICENSE,sha256=XNdbcWldt0yaNXXWB_Bakoqnxb3OVhUft4MgMA_71ds,1051
|
39
|
+
aient-1.2.28.dist-info/METADATA,sha256=lbCvTrGjtvhxkJRu5vWI4rgAIE1d7s-dVeaHIehVPdE,4842
|
40
|
+
aient-1.2.28.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
41
|
+
aient-1.2.28.dist-info/top_level.txt,sha256=3oXzrP5sAVvyyqabpeq8A2_vfMtY554r4bVE-OHBrZk,6
|
42
|
+
aient-1.2.28.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|