aient 1.2.15__tar.gz → 1.2.17__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.
- {aient-1.2.15 → aient-1.2.17}/PKG-INFO +1 -1
- {aient-1.2.15 → aient-1.2.17}/aient/architext/architext/core.py +44 -19
- {aient-1.2.15 → aient-1.2.17}/aient/architext/test/test.py +68 -0
- {aient-1.2.15 → aient-1.2.17}/aient.egg-info/PKG-INFO +1 -1
- {aient-1.2.15 → aient-1.2.17}/pyproject.toml +1 -1
- {aient-1.2.15 → aient-1.2.17}/LICENSE +0 -0
- {aient-1.2.15 → aient-1.2.17}/README.md +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/__init__.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/architext/architext/__init__.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/architext/test/openai_client.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/architext/test/test_save_load.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/core/__init__.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/core/log_config.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/core/models.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/core/request.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/core/response.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/core/test/test_base_api.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/core/test/test_geminimask.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/core/test/test_image.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/core/test/test_payload.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/core/utils.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/models/__init__.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/models/audio.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/models/base.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/models/chatgpt.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/plugins/__init__.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/plugins/arXiv.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/plugins/config.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/plugins/excute_command.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/plugins/get_time.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/plugins/image.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/plugins/list_directory.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/plugins/read_file.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/plugins/read_image.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/plugins/readonly.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/plugins/registry.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/plugins/run_python.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/plugins/websearch.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/plugins/write_file.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/utils/__init__.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/utils/prompt.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient/utils/scripts.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient.egg-info/SOURCES.txt +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient.egg-info/dependency_links.txt +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient.egg-info/requires.txt +0 -0
- {aient-1.2.15 → aient-1.2.17}/aient.egg-info/top_level.txt +0 -0
- {aient-1.2.15 → aient-1.2.17}/setup.cfg +0 -0
- {aient-1.2.15 → aient-1.2.17}/test/test_Web_crawler.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/test/test_ddg_search.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/test/test_google_search.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/test/test_ollama.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/test/test_plugin.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/test/test_search.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/test/test_url.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/test/test_whisper.py +0 -0
- {aient-1.2.15 → aient-1.2.17}/test/test_yjh.py +0 -0
@@ -96,6 +96,13 @@ class ContextProvider(ABC):
|
|
96
96
|
return ContentBlock(self.name, self._cached_content)
|
97
97
|
return None
|
98
98
|
|
99
|
+
def __add__(self, other):
|
100
|
+
if isinstance(other, Message):
|
101
|
+
# Create a new message of the same type as `other`, with `self` prepended.
|
102
|
+
new_items = [self] + other.provider()
|
103
|
+
return type(other)(*new_items)
|
104
|
+
return NotImplemented
|
105
|
+
|
99
106
|
class Texts(ContextProvider):
|
100
107
|
def __init__(self, text: Optional[Union[str, Callable[[], str]]] = None, name: Optional[str] = None, visible: bool = True):
|
101
108
|
if text is None and name is None:
|
@@ -665,30 +672,48 @@ class Messages:
|
|
665
672
|
return Messages(*self._messages[index])
|
666
673
|
return self._messages[index]
|
667
674
|
|
668
|
-
def __setitem__(self, index: slice, value: 'Messages'):
|
669
|
-
if
|
670
|
-
|
671
|
-
|
672
|
-
# Basic slice assignment logic.
|
673
|
-
# A more robust implementation would handle step and negative indices.
|
674
|
-
start, stop, step = index.indices(len(self._messages))
|
675
|
+
def __setitem__(self, index: Union[int, slice], value: Union[Message, 'Messages']):
|
676
|
+
if isinstance(index, int):
|
677
|
+
if not isinstance(value, Message):
|
678
|
+
raise TypeError("When assigning to an index, the value must be a Message.")
|
675
679
|
|
676
|
-
|
677
|
-
|
680
|
+
if not (-len(self._messages) <= index < len(self._messages)):
|
681
|
+
raise IndexError("Messages assignment index out of range")
|
678
682
|
|
679
|
-
|
680
|
-
|
681
|
-
for provider in
|
683
|
+
# Get old message to remove its providers
|
684
|
+
old_message = self._messages[index]
|
685
|
+
for provider in old_message.provider():
|
682
686
|
self._notify_provider_removed(provider)
|
683
687
|
|
684
|
-
|
685
|
-
|
688
|
+
# Assign new message
|
689
|
+
self._messages[index] = value
|
690
|
+
value._parent_messages = self
|
691
|
+
for provider in value.provider():
|
692
|
+
self._notify_provider_added(provider, value)
|
693
|
+
|
694
|
+
elif isinstance(index, slice):
|
695
|
+
if not isinstance(value, Messages):
|
696
|
+
raise TypeError("When assigning to a slice, the value must be a Messages object.")
|
686
697
|
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
698
|
+
start, stop, step = index.indices(len(self._messages))
|
699
|
+
if step != 1:
|
700
|
+
raise ValueError("Slice assignment with step is not supported.")
|
701
|
+
|
702
|
+
# Remove old providers from the index
|
703
|
+
for i in range(start, stop):
|
704
|
+
for provider in self._messages[i].provider():
|
705
|
+
self._notify_provider_removed(provider)
|
706
|
+
|
707
|
+
# Replace the slice in the list
|
708
|
+
self._messages[start:stop] = value._messages
|
709
|
+
|
710
|
+
# Add new providers to the index and set parent
|
711
|
+
for msg in value:
|
712
|
+
msg._parent_messages = self
|
713
|
+
for provider in msg.provider():
|
714
|
+
self._notify_provider_added(provider, msg)
|
715
|
+
else:
|
716
|
+
raise TypeError("Unsupported operand type(s) for assignment")
|
692
717
|
|
693
718
|
def __len__(self) -> int: return len(self._messages)
|
694
719
|
def __iter__(self): return iter(self._messages)
|
@@ -1341,6 +1341,74 @@ Files: {Files(visible=True, name="files")}
|
|
1341
1341
|
if os.path.exists(test_file_path):
|
1342
1342
|
os.remove(test_file_path)
|
1343
1343
|
|
1344
|
+
async def test_zg_provider_plus_message_addition(self):
|
1345
|
+
"""测试所有 ContextProvider 子类与 Message 子类相加的功能"""
|
1346
|
+
# 1. 准备 providers
|
1347
|
+
text_provider = Texts("Some text.")
|
1348
|
+
tools_provider = Tools([{"name": "a_tool"}])
|
1349
|
+
|
1350
|
+
test_file = "test_provider_addition.txt"
|
1351
|
+
with open(test_file, "w") as f: f.write("File content.")
|
1352
|
+
files_provider = Files(test_file)
|
1353
|
+
|
1354
|
+
providers_to_test = [text_provider, tools_provider, files_provider]
|
1355
|
+
|
1356
|
+
# 2. 准备 message aclsdd
|
1357
|
+
messages_to_test = [
|
1358
|
+
UserMessage(Texts("Initial user message.")),
|
1359
|
+
SystemMessage(Texts("Initial system message.")),
|
1360
|
+
AssistantMessage(Texts("Initial assistant message."))
|
1361
|
+
]
|
1362
|
+
|
1363
|
+
try:
|
1364
|
+
for provider in providers_to_test:
|
1365
|
+
for message in messages_to_test:
|
1366
|
+
with self.subTest(provider=type(provider).__name__, message=type(message).__name__):
|
1367
|
+
# 执行加法操作
|
1368
|
+
result_message = provider + message
|
1369
|
+
|
1370
|
+
# 验证结果类型是否与原始 message 相同
|
1371
|
+
self.assertIsInstance(result_message, type(message), f"结果应为 {type(message).__name__} 类型")
|
1372
|
+
|
1373
|
+
# 验证 provider 数量
|
1374
|
+
self.assertEqual(len(result_message), 2, "结果消息应包含两个 provider")
|
1375
|
+
|
1376
|
+
# 验证 provider 的类型和顺序
|
1377
|
+
result_providers = result_message.provider()
|
1378
|
+
self.assertIsInstance(result_providers[0], type(provider), f"第一个 provider 应为 {type(provider).__name__} 类型")
|
1379
|
+
self.assertIsInstance(result_providers[1], Texts, "第二个 provider 应为 Texts 类型")
|
1380
|
+
|
1381
|
+
# 验证原始消息没有被修改
|
1382
|
+
self.assertEqual(len(message), 1)
|
1383
|
+
|
1384
|
+
finally:
|
1385
|
+
# 3. 清理文件
|
1386
|
+
if os.path.exists(test_file):
|
1387
|
+
os.remove(test_file)
|
1388
|
+
|
1389
|
+
async def test_zh_provider_plus_message_assignment(self):
|
1390
|
+
"""测试 ContextProvider + Message 的结果可以赋值回 Messages 列表"""
|
1391
|
+
# 1. 准备 provider 和 messages
|
1392
|
+
text_provider = Texts("Prefix text.")
|
1393
|
+
messages = Messages(
|
1394
|
+
UserMessage("Initial user message.")
|
1395
|
+
)
|
1396
|
+
|
1397
|
+
# 2. 执行操作
|
1398
|
+
# 这行代码在修改 __setitem__ 之前应该会失败
|
1399
|
+
messages[0] = text_provider + messages[0]
|
1400
|
+
|
1401
|
+
# 3. 验证结果
|
1402
|
+
self.assertEqual(len(messages), 1)
|
1403
|
+
self.assertEqual(len(messages[0]), 2) # Now UserMessage has two providers
|
1404
|
+
|
1405
|
+
# 4. 验证内容
|
1406
|
+
rendered = await messages.render_latest()
|
1407
|
+
self.assertEqual(rendered[0]['content'], "Prefix text.Initial user message.")
|
1408
|
+
|
1409
|
+
# 5. 验证 provider 索引
|
1410
|
+
self.assertIsNotNone(messages.provider(text_provider.name))
|
1411
|
+
|
1344
1412
|
|
1345
1413
|
# ==============================================================================
|
1346
1414
|
# 6. 演示
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|