aient 1.1.92__tar.gz → 1.1.93__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.1.92 → aient-1.1.93}/PKG-INFO +1 -1
- {aient-1.1.92 → aient-1.1.93}/aient/architext/architext/core.py +21 -6
- {aient-1.1.92 → aient-1.1.93}/aient/architext/test/test.py +53 -0
- {aient-1.1.92 → aient-1.1.93}/aient.egg-info/PKG-INFO +1 -1
- {aient-1.1.92 → aient-1.1.93}/pyproject.toml +1 -1
- {aient-1.1.92 → aient-1.1.93}/LICENSE +0 -0
- {aient-1.1.92 → aient-1.1.93}/README.md +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/__init__.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/architext/architext/__init__.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/architext/test/openai_client.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/architext/test/test_save_load.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/core/__init__.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/core/log_config.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/core/models.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/core/request.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/core/response.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/core/test/test_base_api.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/core/test/test_geminimask.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/core/test/test_image.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/core/test/test_payload.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/core/utils.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/models/__init__.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/models/audio.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/models/base.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/models/chatgpt.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/plugins/__init__.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/plugins/arXiv.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/plugins/config.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/plugins/excute_command.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/plugins/get_time.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/plugins/image.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/plugins/list_directory.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/plugins/read_file.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/plugins/read_image.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/plugins/readonly.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/plugins/registry.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/plugins/run_python.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/plugins/websearch.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/plugins/write_file.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/utils/__init__.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/utils/prompt.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient/utils/scripts.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient.egg-info/SOURCES.txt +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient.egg-info/dependency_links.txt +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient.egg-info/requires.txt +0 -0
- {aient-1.1.92 → aient-1.1.93}/aient.egg-info/top_level.txt +0 -0
- {aient-1.1.92 → aient-1.1.93}/setup.cfg +0 -0
- {aient-1.1.92 → aient-1.1.93}/test/test_Web_crawler.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/test/test_ddg_search.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/test/test_google_search.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/test/test_ollama.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/test/test_plugin.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/test/test_search.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/test/test_url.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/test/test_whisper.py +0 -0
- {aient-1.1.92 → aient-1.1.93}/test/test_yjh.py +0 -0
@@ -6,7 +6,7 @@ import hashlib
|
|
6
6
|
import mimetypes
|
7
7
|
from dataclasses import dataclass
|
8
8
|
from abc import ABC, abstractmethod
|
9
|
-
from typing import List, Dict, Any, Optional, Union
|
9
|
+
from typing import List, Dict, Any, Optional, Union, Callable
|
10
10
|
|
11
11
|
# 1. 核心数据结构: ContentBlock
|
12
12
|
@dataclass
|
@@ -32,20 +32,35 @@ class ContextProvider(ABC):
|
|
32
32
|
return None
|
33
33
|
|
34
34
|
class Texts(ContextProvider):
|
35
|
-
def __init__(self, text: str, name: Optional[str] = None):
|
35
|
+
def __init__(self, text: Union[str, Callable[[], str]], name: Optional[str] = None):
|
36
36
|
self._text = text
|
37
|
+
self._is_dynamic = callable(self._text)
|
38
|
+
|
37
39
|
if name is None:
|
38
|
-
|
39
|
-
|
40
|
+
if self._is_dynamic:
|
41
|
+
import uuid
|
42
|
+
_name = f"dynamic_text_{uuid.uuid4().hex[:8]}"
|
43
|
+
else:
|
44
|
+
h = hashlib.sha1(self._text.encode()).hexdigest()
|
45
|
+
_name = f"text_{h[:8]}"
|
40
46
|
else:
|
41
47
|
_name = name
|
42
48
|
super().__init__(_name)
|
43
49
|
|
44
|
-
def
|
50
|
+
async def refresh(self):
|
51
|
+
if self._is_dynamic:
|
52
|
+
self._is_stale = True
|
53
|
+
await super().refresh()
|
54
|
+
|
55
|
+
def update(self, text: Union[str, Callable[[], str]]):
|
45
56
|
self._text = text
|
57
|
+
self._is_dynamic = callable(self._text)
|
46
58
|
self.mark_stale()
|
47
59
|
|
48
|
-
async def render(self) -> str:
|
60
|
+
async def render(self) -> str:
|
61
|
+
if self._is_dynamic:
|
62
|
+
return self._text()
|
63
|
+
return self._text
|
49
64
|
|
50
65
|
class Tools(ContextProvider):
|
51
66
|
def __init__(self, tools_json: List[Dict]): super().__init__("tools"); self._tools_json = tools_json
|
@@ -819,6 +819,59 @@ class TestContextManagement(unittest.IsolatedAsyncioTestCase):
|
|
819
819
|
if os.path.exists(test_file):
|
820
820
|
os.remove(test_file)
|
821
821
|
|
822
|
+
async def test_z_dynamic_texts_provider(self):
|
823
|
+
"""测试 Texts provider 是否支持可调用对象以实现动态内容"""
|
824
|
+
import time
|
825
|
+
from datetime import datetime
|
826
|
+
|
827
|
+
# 1. 使用 lambda 函数创建一个动态的 Texts provider
|
828
|
+
# 每次调用 render 时,它都应该返回当前时间
|
829
|
+
dynamic_text_provider = Texts(lambda: datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
|
830
|
+
messages = Messages(UserMessage(dynamic_text_provider))
|
831
|
+
|
832
|
+
# 2. 第一次渲染
|
833
|
+
rendered1 = await messages.render_latest()
|
834
|
+
time1_str = rendered1[0]['content']
|
835
|
+
self.assertIsNotNone(time1_str)
|
836
|
+
|
837
|
+
# 3. 等待一秒钟
|
838
|
+
time.sleep(1)
|
839
|
+
|
840
|
+
# 4. 第二次渲染,并期望内容已更新
|
841
|
+
rendered2 = await messages.render_latest()
|
842
|
+
time2_str = rendered2[0]['content']
|
843
|
+
self.assertIsNotNone(time2_str)
|
844
|
+
|
845
|
+
# 5. 验证两次渲染的时间戳不同
|
846
|
+
self.assertNotEqual(time1_str, time2_str, "动态 Texts provider 的内容在两次渲染之间应该更新")
|
847
|
+
|
848
|
+
async def test_z2_dynamic_texts_with_prefix(self):
|
849
|
+
"""测试动态 Texts provider 包含静态前缀时也能正确更新"""
|
850
|
+
import time
|
851
|
+
from datetime import datetime
|
852
|
+
import platform
|
853
|
+
|
854
|
+
# 1. 创建一个包含静态前缀和动态内容的 provider
|
855
|
+
# 正确的用法是将整个表达式放入 lambda
|
856
|
+
dynamic_provider = Texts(lambda: f"平台信息:{platform.platform()}, 时间:{datetime.now().isoformat()}")
|
857
|
+
messages = Messages(UserMessage(dynamic_provider))
|
858
|
+
|
859
|
+
# 2. 第一次渲染
|
860
|
+
rendered1 = await messages.render_latest()
|
861
|
+
content1 = rendered1[0]['content']
|
862
|
+
self.assertIn("平台信息:", content1)
|
863
|
+
|
864
|
+
# 3. 等待一秒
|
865
|
+
time.sleep(1)
|
866
|
+
|
867
|
+
# 4. 第二次渲染
|
868
|
+
rendered2 = await messages.render_latest()
|
869
|
+
content2 = rendered2[0]['content']
|
870
|
+
self.assertIn("平台信息:", content2)
|
871
|
+
|
872
|
+
# 5. 验证两次内容不同(因为时间戳变了)
|
873
|
+
self.assertNotEqual(content1, content2, "包含静态前缀的动态 provider 内容应该更新")
|
874
|
+
|
822
875
|
|
823
876
|
# ==============================================================================
|
824
877
|
# 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
|