aient 1.2.13__py3-none-any.whl → 1.2.15__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.
@@ -58,11 +58,11 @@ class ContentBlock:
58
58
 
59
59
  # 2. 上下文提供者 (带缓存)
60
60
  class ContextProvider(ABC):
61
- def __init__(self, name: str):
61
+ def __init__(self, name: str, visible: bool = True):
62
62
  self.name = name
63
63
  self._cached_content: Optional[str] = None
64
64
  self._is_stale: bool = True
65
- self._visible: bool = True
65
+ self._visible: bool = visible
66
66
 
67
67
  def __str__(self):
68
68
  # This allows the object to be captured when used inside an f-string.
@@ -97,7 +97,7 @@ class ContextProvider(ABC):
97
97
  return None
98
98
 
99
99
  class Texts(ContextProvider):
100
- def __init__(self, text: Optional[Union[str, Callable[[], str]]] = None, name: Optional[str] = None):
100
+ def __init__(self, text: Optional[Union[str, Callable[[], str]]] = None, name: Optional[str] = None, visible: bool = True):
101
101
  if text is None and name is None:
102
102
  raise ValueError("Either 'text' or 'name' must be provided.")
103
103
 
@@ -119,7 +119,7 @@ class Texts(ContextProvider):
119
119
  _name = f"text_{h[:8]}"
120
120
  else:
121
121
  _name = name
122
- super().__init__(_name)
122
+ super().__init__(_name, visible=visible)
123
123
 
124
124
  async def refresh(self):
125
125
  if self._is_dynamic:
@@ -180,8 +180,8 @@ class Texts(ContextProvider):
180
180
  return self.content == other.content
181
181
 
182
182
  class Tools(ContextProvider):
183
- def __init__(self, tools_json: Optional[List[Dict]] = None, name: str = "tools"):
184
- super().__init__(name)
183
+ def __init__(self, tools_json: Optional[List[Dict]] = None, name: str = "tools", visible: bool = True):
184
+ super().__init__(name, visible=visible)
185
185
  self._tools_json = tools_json or []
186
186
  def update(self, tools_json: List[Dict]):
187
187
  self._tools_json = tools_json
@@ -197,8 +197,8 @@ class Tools(ContextProvider):
197
197
  return self._tools_json == other._tools_json
198
198
 
199
199
  class Files(ContextProvider):
200
- def __init__(self, *paths: Union[str, List[str]], name: str = "files"):
201
- super().__init__(name)
200
+ def __init__(self, *paths: Union[str, List[str]], name: str = "files", visible: bool = True):
201
+ super().__init__(name, visible=visible)
202
202
  self._files: Dict[str, str] = {}
203
203
 
204
204
  file_paths: List[str] = []
@@ -278,8 +278,8 @@ class Files(ContextProvider):
278
278
  return self._files == other._files
279
279
 
280
280
  class Images(ContextProvider):
281
- def __init__(self, url: str, name: Optional[str] = None):
282
- super().__init__(name or url)
281
+ def __init__(self, url: str, name: Optional[str] = None, visible: bool = True):
282
+ super().__init__(name or url, visible=visible)
283
283
  self.url = url
284
284
  def update(self, url: str):
285
285
  self.url = url
@@ -654,7 +654,7 @@ class Messages:
654
654
  with open(file_path, 'rb') as f:
655
655
  return pickle.load(f)
656
656
  except FileNotFoundError:
657
- logging.warning(f"File not found at {file_path}, returning empty Messages.")
657
+ # logging.warning(f"File not found at {file_path}, returning empty Messages.")
658
658
  return cls()
659
659
  except (pickle.UnpicklingError, EOFError) as e:
660
660
  logging.error(f"Could not deserialize file {file_path}: {e}")
@@ -1158,7 +1158,46 @@ Current time: {Texts(lambda: datetime.now().strftime("%Y-%m-%d %H:%M:%S"))}
1158
1158
  with self.assertRaises(IndexError):
1159
1159
  _ = mess[2]
1160
1160
 
1161
- async def test_zb_message_provider_by_name(self):
1161
+ async def test_zb_fstring_provider_invisible_on_init(self):
1162
+ """测试在f-string中初始化的provider可以被设置为不可见"""
1163
+
1164
+ # 1. 在 f-string 中初始化一个 provider 并设置 visible=False
1165
+ # 在修改前,这会因为 __init__ 不接受 'visible' 参数而失败
1166
+ message_with_invisible_provider = f"""
1167
+ Tools: {Tools(tools_json=[{"name": "should_not_appear"}], visible=False)}
1168
+ Files: {Files(visible=True, name="files")}
1169
+ """
1170
+
1171
+ messages = Messages(UserMessage(message_with_invisible_provider))
1172
+
1173
+ # 2. 准备 Files provider 的内容
1174
+ test_file = "test_invisible_fstring.txt"
1175
+ with open(test_file, "w") as f:
1176
+ f.write("visible content")
1177
+
1178
+ try:
1179
+ files_provider = messages.provider("files")
1180
+ self.assertIsNotNone(files_provider)
1181
+ files_provider.update(test_file)
1182
+
1183
+ # 3. 渲染并验证
1184
+ rendered = await messages.render_latest()
1185
+ self.assertEqual(len(rendered), 1)
1186
+ content = rendered[0]['content']
1187
+
1188
+ # 4. 验证不可见的 provider 的内容没有出现
1189
+ self.assertNotIn("<tools>", content)
1190
+ self.assertNotIn("should_not_appear", content)
1191
+
1192
+ # 5. 验证可见的 provider 的内容正常出现
1193
+ self.assertIn("<latest_file_content>", content)
1194
+ self.assertIn("visible content", content)
1195
+
1196
+ finally:
1197
+ if os.path.exists(test_file):
1198
+ os.remove(test_file)
1199
+
1200
+ async def test_zc_message_provider_by_name(self):
1162
1201
  """测试是否可以通过名称从 Message 对象中获取 provider"""
1163
1202
  # 1. 创建一个包含命名 provider 的 Message
1164
1203
  message = UserMessage(
@@ -1182,7 +1221,7 @@ Current time: {Texts(lambda: datetime.now().strftime("%Y-%m-%d %H:%M:%S"))}
1182
1221
  non_existent_provider = message.provider("non_existent")
1183
1222
  self.assertIsNone(non_existent_provider)
1184
1223
 
1185
- async def test_zc_slicing_support(self):
1224
+ async def test_zd_slicing_support(self):
1186
1225
  """测试 Messages 对象是否支持切片操作"""
1187
1226
  m1 = SystemMessage("1")
1188
1227
  m2 = UserMessage("2")
@@ -1217,7 +1256,7 @@ Current time: {Texts(lambda: datetime.now().strftime("%Y-%m-%d %H:%M:%S"))}
1217
1256
  self.assertEqual(len(sliced_single), 1)
1218
1257
  self.assertIs(sliced_single[0], m3)
1219
1258
 
1220
- async def test_zd_slice_assignment(self):
1259
+ async def test_ze_slice_assignment(self):
1221
1260
  """测试 Messages 对象的切片赋值功能"""
1222
1261
  # 1. Setup initial Messages objects
1223
1262
  m1 = SystemMessage("1")
@@ -1258,7 +1297,7 @@ Current time: {Texts(lambda: datetime.now().strftime("%Y-%m-%d %H:%M:%S"))}
1258
1297
  self.assertEqual(messages3[2].content, "C")
1259
1298
  self.assertIsInstance(messages3[1], AssistantMessage)
1260
1299
 
1261
- async def test_ze_fstring_lambda_serialization(self):
1300
+ async def test_zf_fstring_lambda_serialization(self):
1262
1301
  """测试包含 lambda 的 f-string 消息是否可以被序列化和反序列化"""
1263
1302
  import platform
1264
1303
  import os
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aient
3
- Version: 1.2.13
3
+ Version: 1.2.15
4
4
  Summary: Aient: The Awakening of Agent.
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -1,8 +1,8 @@
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=v5Phz5qwON2SBhpDXVxvJX_ZO2c_dPWDekq-jKkOvdI,28431
3
+ aient/architext/architext/core.py,sha256=UvvIAW6GhNvUnRyVl5OWL2FNFtxlVNBDT2Ain0ytwaQ,28614
4
4
  aient/architext/test/openai_client.py,sha256=Dqtbmubv6vwF8uBqcayG0kbsiO65of7sgU2-DRBi-UM,4590
5
- aient/architext/test/test.py,sha256=XOSbDD-hlBnZiu5-500T-sy0m61zsq2SqQgFIoK6TJ0,61137
5
+ aient/architext/test/test.py,sha256=cYhrM_UdUZPI1Flfca_1zRX99mh44gg1hizJY5KQcsc,62659
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
@@ -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.13.dist-info/licenses/LICENSE,sha256=XNdbcWldt0yaNXXWB_Bakoqnxb3OVhUft4MgMA_71ds,1051
39
- aient-1.2.13.dist-info/METADATA,sha256=XRa2hTD04qTwEsOcHYyPT2fxadw31nxFNwL6A4y2Q5I,4842
40
- aient-1.2.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
41
- aient-1.2.13.dist-info/top_level.txt,sha256=3oXzrP5sAVvyyqabpeq8A2_vfMtY554r4bVE-OHBrZk,6
42
- aient-1.2.13.dist-info/RECORD,,
38
+ aient-1.2.15.dist-info/licenses/LICENSE,sha256=XNdbcWldt0yaNXXWB_Bakoqnxb3OVhUft4MgMA_71ds,1051
39
+ aient-1.2.15.dist-info/METADATA,sha256=AAn4cRpbzlffWKPJKsyvhgbAMMMP6g7HyPNb1Ov6GYY,4842
40
+ aient-1.2.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
41
+ aient-1.2.15.dist-info/top_level.txt,sha256=3oXzrP5sAVvyyqabpeq8A2_vfMtY554r4bVE-OHBrZk,6
42
+ aient-1.2.15.dist-info/RECORD,,
File without changes