agently 4.0.6.7__py3-none-any.whl → 4.0.6.10__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.
@@ -188,6 +188,7 @@ class ConfigurePromptExtension(BaseAgent):
188
188
  "Cannot execute YAML prompt configures, expect prompt configures as a dictionary data but got:"
189
189
  f"{ prompt }"
190
190
  )
191
+ return self
191
192
 
192
193
  def load_json_prompt(self, path_or_content: str, mappings: dict[str, Any] | None = None):
193
194
  path = Path(path_or_content)
@@ -209,3 +210,4 @@ class ConfigurePromptExtension(BaseAgent):
209
210
  "Cannot execute JSON prompt configures, expect prompt configures as a dictionary data but got:"
210
211
  f"{ prompt }"
211
212
  )
213
+ return self
@@ -17,6 +17,32 @@ from typing import TYPE_CHECKING
17
17
 
18
18
  from agently.types.plugins import EventHooker
19
19
 
20
+ COLORS = {
21
+ "black": 30,
22
+ "red": 31,
23
+ "green": 32,
24
+ "yellow": 33,
25
+ "blue": 34,
26
+ "magenta": 35,
27
+ "cyan": 36,
28
+ "white": 37,
29
+ "gray": 90,
30
+ }
31
+
32
+
33
+ def color_text(text: str, color: str | None = None, bold: bool = False, underline: bool = False) -> str:
34
+ codes = []
35
+ if bold:
36
+ codes.append("1")
37
+ if underline:
38
+ codes.append("4")
39
+ if color and color in COLORS:
40
+ codes.append(str(COLORS[color]))
41
+ if not codes:
42
+ return text
43
+ return f"\x1b[{';'.join(codes)}m{text}\x1b[0m"
44
+
45
+
20
46
  if TYPE_CHECKING:
21
47
  from agently.types.data import EventMessage, AgentlySystemEvent
22
48
 
@@ -72,12 +98,18 @@ class SystemMessageHooker(EventHooker):
72
98
  and SystemMessageHooker._current_meta["row_id"] == message_data["response_id"]
73
99
  and SystemMessageHooker._current_meta["stage"] == content["stage"]
74
100
  ):
75
- print(content["detail"], end="")
101
+ print(color_text(content["detail"], color="gray"), end="", flush=True)
76
102
  else:
77
- print(
78
- f"[Agent-{ message_data['agent_name'] }] - [Request-{ message_data['response_id'] }]\nStage: { content['stage'] }\nDetail:\n{ content['detail'] }",
79
- end="",
103
+ header = color_text(
104
+ f"[Agent-{ message_data['agent_name'] }] - [Request-{ message_data['response_id'] }]",
105
+ color="blue",
106
+ bold=True,
80
107
  )
108
+ stage_label = color_text("Stage:", color="cyan", bold=True)
109
+ stage_val = color_text(content["stage"], color="yellow", underline=True)
110
+ detail_label = color_text("Detail:\n", color="cyan", bold=True)
111
+ detail = color_text(content["detail"], color="green")
112
+ print(f"{header}\n{stage_label} {stage_val}\n{detail_label}{detail}", end="")
81
113
  SystemMessageHooker._current_meta["table_name"] = message_data["agent_name"]
82
114
  SystemMessageHooker._current_meta["row_id"] = message_data["response_id"]
83
115
  SystemMessageHooker._current_meta["stage"] = content["stage"]
@@ -99,28 +131,40 @@ class SystemMessageHooker(EventHooker):
99
131
  },
100
132
  )
101
133
  if settings["runtime.show_model_logs"]:
134
+ header = color_text(
135
+ f"[Agent-{ message_data['agent_name'] }] - [Response-{ message_data['response_id'] }]",
136
+ color="blue",
137
+ bold=True,
138
+ )
139
+ stage_label = color_text("Stage:", color="cyan", bold=True)
140
+ stage_val = color_text(content["stage"], color="yellow", underline=True)
141
+ detail_label = color_text("Detail:\n", color="cyan", bold=True)
142
+ detail = color_text(f"{content['detail']}", color="gray")
102
143
  await event_center.async_emit(
103
144
  "log",
104
145
  {
105
146
  "level": "INFO",
106
- "content": f"[Agent-{ message_data['agent_name'] }] - [Response-{ message_data['response_id'] }]\nStage: { content['stage'] }\nDetail:\n{ content['detail'] }",
147
+ "content": f"{header}\n{stage_label} {stage_val}\n{detail_label}{detail}",
107
148
  },
108
149
  )
109
150
  case "TOOL":
110
151
  if settings["runtime.show_tool_logs"]:
152
+ tool_title = color_text("[Tool Using Result]:", color="blue", bold=True)
153
+ tool_body = color_text(str(message.content["data"]), color="gray")
111
154
  await event_center.async_emit(
112
155
  "log",
113
156
  {
114
157
  "level": "INFO",
115
- "content": f"[Tool Using Result]:\n{ message.content['data'] }",
158
+ "content": f"{tool_title}\n{tool_body}",
116
159
  },
117
160
  )
118
161
  case "TRIGGER_FLOW":
119
162
  if settings["runtime.show_trigger_flow_logs"]:
163
+ trigger = color_text(f"[TriggerFlow] { message.content['data'] }", color="yellow", bold=True)
120
164
  await event_center.async_emit(
121
165
  "log",
122
166
  {
123
167
  "level": "INFO",
124
- "content": f"[TriggerFlow] { message.content['data'] }",
168
+ "content": trigger,
125
169
  },
126
170
  )
@@ -146,6 +146,10 @@ class OpenAICompatible(ModelRequester):
146
146
  self.model_type = cast(str, self.plugin_settings.get("model_type"))
147
147
  self._messenger = event_center.create_messenger(self.name)
148
148
 
149
+ # check if has attachment prompt
150
+ if self.prompt["attachment"]:
151
+ self.plugin_settings["rich_content"] = True
152
+
149
153
  @staticmethod
150
154
  def _on_register():
151
155
  pass
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ import json
15
16
  import yaml
16
17
 
17
18
  from typing import (
@@ -38,6 +39,7 @@ from agently.utils import SettingsNamespace, DataFormatter
38
39
 
39
40
  if TYPE_CHECKING:
40
41
  from pydantic import BaseModel
42
+ from agently.types.data import SerializableData
41
43
  from agently.core import Prompt
42
44
  from agently.utils import Settings
43
45
 
@@ -649,7 +651,12 @@ class AgentlyPromptGenerator(PromptGenerator):
649
651
  }
650
652
  )
651
653
 
652
- return create_model(name, **fields, **validators)
654
+ return create_model(
655
+ name,
656
+ __config__={'extra': 'allow'},
657
+ **fields,
658
+ **validators,
659
+ )
653
660
  else:
654
661
  item_type = Any
655
662
  if len(schema) > 0:
@@ -698,3 +705,59 @@ class AgentlyPromptGenerator(PromptGenerator):
698
705
  "AgentlyOutput",
699
706
  {"list": DataFormatter.sanitize(output_prompt, remain_type=True)},
700
707
  )
708
+
709
+ def _to_serializable_output_prompt(self, output_prompt_part: Any):
710
+ if not isinstance(output_prompt_part, (Mapping, Sequence)) or isinstance(output_prompt_part, str):
711
+ return output_prompt_part
712
+
713
+ if isinstance(output_prompt_part, Mapping):
714
+ result = {}
715
+ for key, value in output_prompt_part.items():
716
+ result[key] = self._to_serializable_output_prompt(value)
717
+ return result
718
+ else:
719
+ if isinstance(output_prompt_part, tuple):
720
+ match len(output_prompt_part):
721
+ case 0:
722
+ return []
723
+ case 1:
724
+ return {
725
+ "$type": output_prompt_part[0],
726
+ }
727
+ case _:
728
+ desc_text = ";".join([item for item in output_prompt_part[1:] if item])
729
+ if desc_text:
730
+ return {
731
+ "$type": output_prompt_part[0],
732
+ "$desc": desc_text,
733
+ }
734
+ else:
735
+ return {
736
+ "$type": output_prompt_part[0],
737
+ }
738
+ else:
739
+ return list(output_prompt_part)
740
+
741
+ def to_serializable_prompt_data(self, inherit: bool = False) -> "SerializableData":
742
+ prompt_data = self.prompt.get(
743
+ default={},
744
+ inherit=inherit,
745
+ )
746
+ if "output" in prompt_data:
747
+ prompt_data["output"] = self._to_serializable_output_prompt(prompt_data["output"])
748
+ return DataFormatter.sanitize(prompt_data)
749
+
750
+ def to_json_prompt(self, inherit: bool = False):
751
+ return json.dumps(
752
+ self.to_serializable_prompt_data(inherit),
753
+ indent=2,
754
+ ensure_ascii=False,
755
+ )
756
+
757
+ def to_yaml_prompt(self, inherit: bool = False):
758
+ return yaml.safe_dump(
759
+ self.to_serializable_prompt_data(inherit),
760
+ indent=2,
761
+ allow_unicode=True,
762
+ sort_keys=False,
763
+ )
agently/core/Agent.py CHANGED
@@ -13,6 +13,8 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import uuid
16
+ import yaml
17
+ import json
16
18
 
17
19
  from typing import Any, TYPE_CHECKING
18
20
 
@@ -91,7 +93,7 @@ class BaseAgent:
91
93
  value: Any,
92
94
  mappings: dict[str, Any] | None = None,
93
95
  ):
94
- self.prompt.set(key, value, mappings)
96
+ self.agent_prompt.set(key, value, mappings)
95
97
  return self
96
98
 
97
99
  def set_request_prompt(
@@ -104,7 +106,7 @@ class BaseAgent:
104
106
  return self
105
107
 
106
108
  def remove_agent_prompt(self, key: "PromptStandardSlot | str"):
107
- self.prompt.set(key, None)
109
+ self.agent_prompt.set(key, None)
108
110
  return self
109
111
 
110
112
  def remove_request_prompt(self, key: "PromptStandardSlot | str"):
@@ -112,34 +114,34 @@ class BaseAgent:
112
114
  return self
113
115
 
114
116
  def reset_chat_history(self):
115
- if "chat_history" in self.prompt:
116
- self.prompt.set("chat_history", [])
117
+ if "chat_history" in self.agent_prompt:
118
+ self.agent_prompt.set("chat_history", [])
117
119
  return self
118
120
 
119
121
  def set_chat_history(self, chat_history: "list[dict[str, Any] | ChatMessage]"):
120
122
  self.reset_chat_history()
121
123
  if not isinstance(chat_history, list):
122
124
  chat_history = [chat_history]
123
- self.prompt.set("chat_history", chat_history)
125
+ self.agent_prompt.set("chat_history", chat_history)
124
126
  return self
125
127
 
126
128
  def add_chat_history(self, chat_history: "list[dict[str, Any] | ChatMessage] | dict[str, Any] | ChatMessage"):
127
129
  if not isinstance(chat_history, list):
128
130
  chat_history = [chat_history]
129
- self.prompt.set("chat_history", chat_history)
131
+ self.agent_prompt.set("chat_history", chat_history)
130
132
  return self
131
133
 
132
134
  def reset_action_results(self):
133
- if "action_results" in self.prompt:
134
- del self.prompt["action_results"]
135
+ if "action_results" in self.agent_prompt:
136
+ del self.agent_prompt["action_results"]
135
137
  return self
136
138
 
137
139
  def set_action_results(self, action_results: list[dict[str, Any]]):
138
- self.prompt.set("action_results", action_results)
140
+ self.agent_prompt.set("action_results", action_results)
139
141
  return self
140
142
 
141
143
  def add_action_results(self, action: str, result: Any):
142
- self.prompt.append("action_results", {action: result})
144
+ self.agent_prompt.append("action_results", {action: result})
143
145
  return self
144
146
 
145
147
  # Quick Prompt
@@ -151,7 +153,7 @@ class BaseAgent:
151
153
  always: bool = False,
152
154
  ):
153
155
  if always:
154
- self.prompt.set("input", prompt, mappings)
156
+ self.agent_prompt.set("input", prompt, mappings)
155
157
  else:
156
158
  self.request.prompt.set("input", prompt, mappings)
157
159
  return self
@@ -164,8 +166,8 @@ class BaseAgent:
164
166
  always: bool = False,
165
167
  ):
166
168
  if always:
167
- self.prompt.set("instruct", ["{system.rule} ARE IMPORTANT RULES YOU SHALL FOLLOW!"])
168
- self.prompt.set("system.rule", prompt, mappings)
169
+ self.agent_prompt.set("instruct", ["{system.rule} ARE IMPORTANT RULES YOU SHALL FOLLOW!"])
170
+ self.agent_prompt.set("system.rule", prompt, mappings)
169
171
  else:
170
172
  self.request.prompt.set("instruct", ["{system.rule} ARE IMPORTANT RULES YOU SHALL FOLLOW!"])
171
173
  self.request.prompt.set("system.rule", prompt, mappings)
@@ -179,8 +181,8 @@ class BaseAgent:
179
181
  always: bool = False,
180
182
  ):
181
183
  if always:
182
- self.prompt.set("instruct", ["YOU MUST REACT AND RESPOND AS {system.role}!"])
183
- self.prompt.set("system.your_role", prompt, mappings)
184
+ self.agent_prompt.set("instruct", ["YOU MUST REACT AND RESPOND AS {system.role}!"])
185
+ self.agent_prompt.set("system.your_role", prompt, mappings)
184
186
  else:
185
187
  self.request.prompt.set("instruct", ["YOU MUST REACT AND RESPOND AS {system.role}!"])
186
188
  self.request.prompt.set("system.your_role", prompt, mappings)
@@ -194,8 +196,8 @@ class BaseAgent:
194
196
  always: bool = False,
195
197
  ):
196
198
  if always:
197
- self.prompt.set("instruct", ["{system.user_info} IS IMPORTANT INFORMATION ABOUT USER!"])
198
- self.prompt.set("system.user_info", prompt, mappings)
199
+ self.agent_prompt.set("instruct", ["{system.user_info} IS IMPORTANT INFORMATION ABOUT USER!"])
200
+ self.agent_prompt.set("system.user_info", prompt, mappings)
199
201
  else:
200
202
  self.request.prompt.set("instruct", ["{system.user_info} IS IMPORTANT INFORMATION ABOUT USER!"])
201
203
  self.request.prompt.set("system.user_info", prompt, mappings)
@@ -209,7 +211,7 @@ class BaseAgent:
209
211
  always: bool = False,
210
212
  ):
211
213
  if always:
212
- self.prompt.set("input", prompt, mappings)
214
+ self.agent_prompt.set("input", prompt, mappings)
213
215
  else:
214
216
  self.request.prompt.set("input", prompt, mappings)
215
217
  return self
@@ -222,7 +224,7 @@ class BaseAgent:
222
224
  always: bool = False,
223
225
  ):
224
226
  if always:
225
- self.prompt.set("info", prompt, mappings)
227
+ self.agent_prompt.set("info", prompt, mappings)
226
228
  else:
227
229
  self.request.prompt.set("info", prompt, mappings)
228
230
  return self
@@ -235,7 +237,7 @@ class BaseAgent:
235
237
  always: bool = False,
236
238
  ):
237
239
  if always:
238
- self.prompt.set("instruct", prompt, mappings)
240
+ self.agent_prompt.set("instruct", prompt, mappings)
239
241
  else:
240
242
  self.request.prompt.set("instruct", prompt, mappings)
241
243
  return self
@@ -248,7 +250,7 @@ class BaseAgent:
248
250
  always: bool = False,
249
251
  ):
250
252
  if always:
251
- self.prompt.set("examples", prompt, mappings)
253
+ self.agent_prompt.set("examples", prompt, mappings)
252
254
  else:
253
255
  self.request.prompt.set("examples", prompt, mappings)
254
256
  return self
@@ -266,11 +268,24 @@ class BaseAgent:
266
268
  always: bool = False,
267
269
  ):
268
270
  if always:
269
- self.prompt.set("output", prompt, mappings)
271
+ self.agent_prompt.set("output", prompt, mappings)
270
272
  else:
271
273
  self.request.prompt.set("output", prompt, mappings)
272
274
  return self
273
275
 
276
+ def attachment(
277
+ self,
278
+ prompt: list[dict[str, Any]],
279
+ mappings: dict[str, Any] | None = None,
280
+ *,
281
+ always: bool = False,
282
+ ):
283
+ if always:
284
+ self.agent_prompt.set("attachment", prompt, mappings)
285
+ else:
286
+ self.request_prompt.set("attachment", prompt, mappings)
287
+ return self
288
+
274
289
  def options(
275
290
  self,
276
291
  options: dict[str, Any],
@@ -278,7 +293,34 @@ class BaseAgent:
278
293
  always: bool = False,
279
294
  ):
280
295
  if always:
281
- self.prompt.set("options", options)
296
+ self.agent_prompt.set("options", options)
282
297
  else:
283
298
  self.request.prompt.set("options", options)
284
299
  return self
300
+
301
+ # Prompt
302
+ def get_prompt_text(self):
303
+ return self.request_prompt.to_text()[6:][:-11]
304
+
305
+ def get_json_prompt(self):
306
+ prompt_data = {
307
+ ".agent": self.agent_prompt.to_serializable_prompt_data(),
308
+ ".request": self.request_prompt.to_serializable_prompt_data(),
309
+ }
310
+ return json.dumps(
311
+ prompt_data,
312
+ indent=2,
313
+ ensure_ascii=False,
314
+ )
315
+
316
+ def get_yaml_prompt(self):
317
+ prompt_data = {
318
+ ".agent": self.agent_prompt.to_serializable_prompt_data(),
319
+ ".request": self.request_prompt.to_serializable_prompt_data(),
320
+ }
321
+ return yaml.safe_dump(
322
+ prompt_data,
323
+ indent=2,
324
+ allow_unicode=True,
325
+ sort_keys=False,
326
+ )
@@ -22,12 +22,13 @@ ContentKindTuple: TypeAlias = Literal["all", "delta", "original"]
22
22
  ContentKindStreaming: TypeAlias = Literal["instant", "streaming_parse"]
23
23
 
24
24
  from agently.core import Prompt, ExtensionHandlers
25
- from agently.utils import Settings, FunctionShifter, DataFormatter
25
+ from agently.utils import Settings, FunctionShifter, DataFormatter, DataLocator
26
26
 
27
27
  if TYPE_CHECKING:
28
28
  from agently.core import PluginManager
29
29
  from agently.types.data import AgentlyModelResponseMessage, PromptStandardSlot, StreamingData, SerializableValue
30
30
  from agently.types.plugins import ModelRequester, ResponseParser
31
+ from pydantic import BaseModel
31
32
 
32
33
 
33
34
  class ModelResponseResult:
@@ -39,6 +40,7 @@ class ModelResponseResult:
39
40
  response_generator: AsyncGenerator["AgentlyModelResponseMessage", None],
40
41
  plugin_manager: "PluginManager",
41
42
  settings: Settings,
43
+ extension_handlers: ExtensionHandlers,
42
44
  ):
43
45
  self.agent_name = agent_name
44
46
  self.plugin_manager = plugin_manager
@@ -50,19 +52,145 @@ class ModelResponseResult:
50
52
  str(self.settings["plugins.ResponseParser.activate"]),
51
53
  ),
52
54
  )
53
- _response_parser = ResponseParser(agent_name, response_id, prompt, response_generator, self.settings)
55
+ self._response_id = response_id
56
+ self._extension_handlers = extension_handlers
57
+ self._response_parser = ResponseParser(agent_name, response_id, prompt, response_generator, self.settings)
54
58
  self.prompt = prompt
55
- self.full_result_data = _response_parser.full_result_data
56
- self.get_meta = _response_parser.get_meta
57
- self.async_get_meta = _response_parser.async_get_meta
58
- self.get_text = _response_parser.get_text
59
- self.async_get_text = _response_parser.async_get_text
60
- self.get_data = _response_parser.get_data
61
- self.async_get_data = _response_parser.async_get_data
62
- self.get_data_object = _response_parser.get_data_object
63
- self.async_get_data_object = _response_parser.async_get_data_object
64
- self.get_generator = _response_parser.get_generator
65
- self.get_async_generator = _response_parser.get_async_generator
59
+ self.full_result_data = self._response_parser.full_result_data
60
+ self.get_meta = self._response_parser.get_meta
61
+ self.async_get_meta = self._response_parser.async_get_meta
62
+ self.get_text = self._response_parser.get_text
63
+ self.async_get_text = self._response_parser.async_get_text
64
+ # self.get_data = self._response_parser.get_data
65
+ # self.async_get_data = self._response_parser.async_get_data
66
+ # self.get_data_object = self._response_parser.get_data_object
67
+ # self.async_get_data_object = self._response_parser.async_get_data_object
68
+ self.get_data = FunctionShifter.syncify(self.async_get_data)
69
+ self.get_data_object = FunctionShifter.syncify(self.async_get_data_object)
70
+ self.get_generator = self._response_parser.get_generator
71
+ self.get_async_generator = self._response_parser.get_async_generator
72
+
73
+ @overload
74
+ async def async_get_data(
75
+ self,
76
+ *,
77
+ type: Literal['parsed'],
78
+ ensure_keys: list[str],
79
+ key_style: Literal["dot", "slash"] = "dot",
80
+ max_retries: int = 3,
81
+ raise_ensure_failure: bool = True,
82
+ _retry_count: int = 0,
83
+ ) -> dict[str, Any]: ...
84
+
85
+ @overload
86
+ async def async_get_data(
87
+ self,
88
+ *,
89
+ type: Literal['original', 'parsed', 'all'] = "parsed",
90
+ ensure_keys: list[str] | None = None,
91
+ key_style: Literal["dot", "slash"] = "dot",
92
+ max_retries: int = 3,
93
+ raise_ensure_failure: bool = True,
94
+ _retry_count: int = 0,
95
+ ) -> Any: ...
96
+
97
+ async def async_get_data(
98
+ self,
99
+ *,
100
+ type: Literal['original', 'parsed', 'all'] = "parsed",
101
+ ensure_keys: list[str] | None = None,
102
+ key_style: Literal["dot", "slash"] = "dot",
103
+ max_retries: int = 3,
104
+ raise_ensure_failure: bool = True,
105
+ _retry_count: int = 0,
106
+ ) -> Any:
107
+ if type == "parsed" and ensure_keys:
108
+ try:
109
+ data = await self._response_parser.async_get_data(type=type)
110
+ for ensure_key in ensure_keys:
111
+ EMPTY = object()
112
+ if DataLocator.locate_path_in_dict(data, ensure_key, key_style, default=EMPTY) is EMPTY:
113
+ raise
114
+ return data
115
+ except:
116
+ from agently.base import async_system_message
117
+
118
+ await async_system_message(
119
+ "MODEL_REQUEST",
120
+ {
121
+ "agent_name": self.agent_name,
122
+ "response_id": self._response_id,
123
+ "content": {
124
+ "stage": "No Target Data in Response, Preparing Retry",
125
+ "detail": f"\n[Response]: { await self.async_get_text() }\n"
126
+ f"[Retried Times]: { _retry_count }",
127
+ },
128
+ },
129
+ self.settings,
130
+ )
131
+
132
+ if _retry_count < max_retries:
133
+ return await ModelResponse(
134
+ self.agent_name,
135
+ self.plugin_manager,
136
+ self.settings,
137
+ self.prompt,
138
+ self._extension_handlers,
139
+ ).result.async_get_data(
140
+ type=type,
141
+ ensure_keys=ensure_keys,
142
+ key_style=key_style,
143
+ max_retries=max_retries,
144
+ raise_ensure_failure=raise_ensure_failure,
145
+ _retry_count=_retry_count + 1,
146
+ )
147
+ else:
148
+ if raise_ensure_failure:
149
+ raise ValueError(
150
+ f"Can not generate ensure keys { ensure_keys } within { max_retries } retires."
151
+ )
152
+ else:
153
+ return await self._response_parser.async_get_data(type=type)
154
+ return await self._response_parser.async_get_data(type=type)
155
+
156
+ @overload
157
+ async def async_get_data_object(
158
+ self,
159
+ *,
160
+ ensure_keys: list[str],
161
+ key_style: Literal["dot", "slash"] = "dot",
162
+ max_retries: int = 3,
163
+ raise_ensure_failure: bool = True,
164
+ ) -> "BaseModel": ...
165
+
166
+ @overload
167
+ async def async_get_data_object(
168
+ self,
169
+ *,
170
+ ensure_keys: None,
171
+ key_style: Literal["dot", "slash"] = "dot",
172
+ max_retries: int = 3,
173
+ raise_ensure_failure: bool = True,
174
+ ) -> "BaseModel | None": ...
175
+
176
+ async def async_get_data_object(
177
+ self,
178
+ *,
179
+ ensure_keys: list[str] | None = None,
180
+ key_style: Literal["dot", "slash"] = "dot",
181
+ max_retries: int = 3,
182
+ raise_ensure_failure: bool = True,
183
+ ):
184
+ if ensure_keys:
185
+ await self.async_get_data(
186
+ ensure_keys=ensure_keys,
187
+ key_style=key_style,
188
+ max_retries=max_retries,
189
+ _retry_count=0,
190
+ raise_ensure_failure=raise_ensure_failure,
191
+ )
192
+ return await self._response_parser.async_get_data_object()
193
+ return await self._response_parser.async_get_data_object()
66
194
 
67
195
 
68
196
  class ModelResponse:
@@ -98,6 +226,7 @@ class ModelResponse:
98
226
  self._get_response_generator(),
99
227
  self.plugin_manager,
100
228
  self.settings,
229
+ self.extension_handlers,
101
230
  )
102
231
  self.get_meta = self.result.get_meta
103
232
  self.async_get_meta = self.result.async_get_meta
@@ -394,6 +523,15 @@ class ModelRequest:
394
523
  self.prompt.set("output", prompt, mappings)
395
524
  return self
396
525
 
526
+ def attachment(
527
+ self,
528
+ prompt: list[dict[str, Any]],
529
+ mappings: dict[str, Any] | None = None,
530
+ ):
531
+ self.prompt.set("attachment", prompt, mappings)
532
+ return self
533
+
534
+ # Response & Result
397
535
  def get_response(self):
398
536
  response = ModelResponse(
399
537
  self.agent_name,
@@ -418,11 +556,35 @@ class ModelRequest:
418
556
  self,
419
557
  *,
420
558
  type: Literal['original', 'parsed', 'all'] = "parsed",
559
+ ensure_keys: list[str] | None = None,
560
+ key_style: Literal["dot", "slash"] = "dot",
561
+ max_retries: int = 3,
562
+ raise_ensure_failure: bool = True,
421
563
  ):
422
- return await self.get_response().async_get_data(type=type)
564
+ response = self.get_response()
565
+ return await response.async_get_data(
566
+ type=type,
567
+ ensure_keys=ensure_keys,
568
+ key_style=key_style,
569
+ max_retries=max_retries,
570
+ raise_ensure_failure=raise_ensure_failure,
571
+ )
423
572
 
424
- async def async_get_data_object(self):
425
- return await self.get_response().async_get_data_object()
573
+ async def async_get_data_object(
574
+ self,
575
+ *,
576
+ ensure_keys: list[str] | None = None,
577
+ key_style: Literal["dot", "slash"] = "dot",
578
+ max_retries: int = 3,
579
+ raise_ensure_failure: bool = True,
580
+ ):
581
+ response = self.get_response()
582
+ return await response.async_get_data_object(
583
+ ensure_keys=ensure_keys,
584
+ key_style=key_style,
585
+ max_retries=max_retries,
586
+ raise_ensure_failure=raise_ensure_failure,
587
+ )
426
588
 
427
589
  @overload
428
590
  def get_generator(
agently/core/Prompt.py CHANGED
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import re
16
+ from textwrap import dedent
16
17
  from typing import Any, Literal, Mapping, Sequence, TYPE_CHECKING, cast, overload, TypeVar
17
18
 
18
19
  from agently.utils import RuntimeData, Settings
@@ -98,6 +99,9 @@ class Prompt(RuntimeData):
98
99
  self.to_messages = self.prompt_generator.to_messages
99
100
  self.to_prompt_object = self.prompt_generator.to_prompt_object
100
101
  self.to_output_model = self.prompt_generator.to_output_model
102
+ self.to_serializable_prompt_data = self.prompt_generator.to_serializable_prompt_data
103
+ self.to_json_prompt = self.prompt_generator.to_json_prompt
104
+ self.to_yaml_prompt = self.prompt_generator.to_yaml_prompt
101
105
 
102
106
  def _substitute_placeholder(self, obj: T, variable_mappings: dict[str, Any]) -> T | Any:
103
107
  if not isinstance(variable_mappings, dict):
@@ -157,6 +161,8 @@ class Prompt(RuntimeData):
157
161
  value: Any,
158
162
  mappings: dict[str, Any] | None = None,
159
163
  ):
164
+ if isinstance(value, str):
165
+ value = dedent(value.strip())
160
166
  if mappings is not None:
161
167
  super().set(
162
168
  self._substitute_placeholder(key, mappings),
@@ -183,6 +189,8 @@ class Prompt(RuntimeData):
183
189
  value: Any,
184
190
  mappings: dict[str, Any] | None = None,
185
191
  ):
192
+ if isinstance(value, str):
193
+ value = dedent(value.strip())
186
194
  if mappings is not None:
187
195
  super().append(
188
196
  self._substitute_placeholder(key, mappings),
@@ -36,10 +36,10 @@ class TriggerFlowChunk:
36
36
 
37
37
  async def async_call(self, data: "TriggerFlowEventData"):
38
38
  result = await FunctionShifter.asyncify(self._handler)(data)
39
- await data.async_emit(self.trigger, result, layer_marks=data.layer_marks.copy())
39
+ await data.async_emit(self.trigger, result, _layer_marks=data._layer_marks.copy())
40
40
  return result
41
41
 
42
42
  def call(self, data: "TriggerFlowEventData"):
43
43
  result = FunctionShifter.syncify(self._handler)(data)
44
- data.emit(self.trigger, result, layer_marks=data.layer_marks.copy())
44
+ data.emit(self.trigger, result, _layer_marks=data._layer_marks.copy())
45
45
  return result
@@ -97,7 +97,7 @@ class TriggerFlowExecution:
97
97
  self,
98
98
  trigger_event: str,
99
99
  value: Any = None,
100
- layer_marks: list[str] | None = None,
100
+ _layer_marks: list[str] | None = None,
101
101
  *,
102
102
  trigger_type: Literal["event", "runtime_data", "flow_data"] = "event",
103
103
  ):
@@ -134,7 +134,7 @@ class TriggerFlowExecution:
134
134
  trigger_type=trigger_type,
135
135
  value=value,
136
136
  execution=self,
137
- layer_marks=layer_marks,
137
+ _layer_marks=_layer_marks,
138
138
  )
139
139
  )
140
140
  )
@@ -178,7 +178,7 @@ class TriggerFlowBaseProcess:
178
178
  if mode == "simple_or"
179
179
  else (data.trigger_type, data.trigger_event, data.value)
180
180
  ),
181
- layer_marks=data.layer_marks.copy(),
181
+ _layer_marks=data._layer_marks.copy(),
182
182
  )
183
183
  case "and":
184
184
  if data.trigger_type in values and data.trigger_event in values[trigger_type]: # type: ignore
@@ -191,7 +191,7 @@ class TriggerFlowBaseProcess:
191
191
  await data.async_emit(
192
192
  when_trigger,
193
193
  values,
194
- layer_marks=data.layer_marks.copy(),
194
+ _layer_marks=data._layer_marks.copy(),
195
195
  )
196
196
 
197
197
  for trigger_type, trigger_event_dict in values.items():
@@ -213,15 +213,21 @@ class TriggerFlowBaseProcess:
213
213
 
214
214
  def to(
215
215
  self,
216
- chunk: "TriggerFlowChunk | TriggerFlowHandler | str",
216
+ chunk: "TriggerFlowChunk | TriggerFlowHandler | str | tuple[str, TriggerFlowHandler]",
217
217
  side_branch: bool = False,
218
+ name: str | None = None,
218
219
  ):
219
220
  if isinstance(chunk, str):
220
221
  if chunk in self._blue_print.chunks:
221
222
  chunk = self._blue_print.chunks[chunk]
222
223
  else:
223
224
  raise NotImplementedError(f"Cannot find chunk named '{ chunk }'")
224
- chunk = TriggerFlowChunk(chunk) if callable(chunk) else chunk
225
+ elif isinstance(chunk, tuple):
226
+ chunk_name = chunk[0]
227
+ chunk_func = chunk[1]
228
+ chunk = TriggerFlowChunk(chunk_func, name=chunk_name)
229
+ else:
230
+ chunk = TriggerFlowChunk(chunk, name=name) if callable(chunk) else chunk
225
231
  self._blue_print.add_handler(
226
232
  self.trigger_type,
227
233
  self.trigger_event,
@@ -235,34 +241,51 @@ class TriggerFlowBaseProcess:
235
241
  **self._options,
236
242
  )
237
243
 
238
- def side_branch(self, chunk: "TriggerFlowChunk | TriggerFlowHandler"):
239
- return self.to(chunk, side_branch=True)
244
+ def side_branch(
245
+ self,
246
+ chunk: "TriggerFlowChunk | TriggerFlowHandler",
247
+ *,
248
+ name: str | None = None,
249
+ ):
250
+ return self.to(
251
+ chunk,
252
+ side_branch=True,
253
+ name=name,
254
+ )
240
255
 
241
256
  def batch(
242
257
  self,
243
- *chunks: "TriggerFlowChunk | TriggerFlowHandler",
258
+ *chunks: "TriggerFlowChunk | TriggerFlowHandler | tuple[str, TriggerFlowHandler]",
244
259
  side_branch: bool = False,
245
260
  ):
246
261
  batch_trigger = f"Batch-{ uuid.uuid4().hex }"
247
262
  results = {}
248
- chunks_to_wait = {}
263
+ triggers_to_wait = {}
264
+ trigger_to_chunk_name = {}
249
265
 
250
266
  async def wait_all_chunks(data: "TriggerFlowEventData"):
251
- if data.event in chunks_to_wait:
252
- results[data.event] = data.value
253
- chunks_to_wait[data.event] = True
254
- for done in chunks_to_wait.values():
267
+ if data.event in triggers_to_wait:
268
+ results[trigger_to_chunk_name[data.event]] = data.value
269
+ triggers_to_wait[data.event] = True
270
+ for done in triggers_to_wait.values():
255
271
  if done is False:
256
272
  return
257
273
  await data.async_emit(
258
274
  batch_trigger,
259
275
  results,
260
- layer_marks=data.layer_marks.copy(),
276
+ _layer_marks=data._layer_marks.copy(),
261
277
  )
262
278
 
263
279
  for chunk in chunks:
264
- chunk = TriggerFlowChunk(chunk) if callable(chunk) else chunk
265
- chunks_to_wait[chunk.name] = False
280
+ if isinstance(chunk, tuple):
281
+ chunk_name = chunk[0]
282
+ chunk_func = chunk[1]
283
+ chunk = TriggerFlowChunk(chunk_func, name=chunk_name)
284
+ else:
285
+ chunk = TriggerFlowChunk(chunk) if callable(chunk) else chunk
286
+ triggers_to_wait[chunk.trigger] = False
287
+ trigger_to_chunk_name[chunk.trigger] = chunk.name
288
+ results[chunk.name] = None
266
289
  self._blue_print.add_handler(
267
290
  self.trigger_type,
268
291
  self.trigger_event,
@@ -299,13 +322,13 @@ class TriggerFlowBaseProcess:
299
322
  await data.async_emit(
300
323
  collect_trigger,
301
324
  self._block_data.global_data.get(f"collections.{ collection_name}"),
302
- layer_marks=data.layer_marks.copy(),
325
+ _layer_marks=data._layer_marks.copy(),
303
326
  )
304
327
  elif mode == "filled_then_empty":
305
328
  await data.async_emit(
306
329
  collect_trigger,
307
330
  self._block_data.global_data.get(f"collections.{ collection_name}"),
308
- layer_marks=data.layer_marks.copy(),
331
+ _layer_marks=data._layer_marks.copy(),
309
332
  )
310
333
  del self._block_data.global_data[f"collections.{ collection_name}"]
311
334
 
@@ -49,7 +49,7 @@ class TriggerFlowForEachProcess(TriggerFlowBaseProcess):
49
49
  data.async_emit(
50
50
  send_item_trigger,
51
51
  item,
52
- data.layer_marks.copy(),
52
+ data._layer_marks.copy(),
53
53
  )
54
54
  )
55
55
  data.layer_out()
@@ -62,7 +62,7 @@ class TriggerFlowForEachProcess(TriggerFlowBaseProcess):
62
62
  await data.async_emit(
63
63
  send_item_trigger,
64
64
  data.value,
65
- data.layer_marks.copy(),
65
+ data._layer_marks.copy(),
66
66
  )
67
67
  data.layer_out()
68
68
 
@@ -103,7 +103,7 @@ class TriggerFlowForEachProcess(TriggerFlowBaseProcess):
103
103
  await data.async_emit(
104
104
  end_for_each_trigger,
105
105
  list(for_each_results[for_each_instance_id].values()),
106
- data.layer_marks.copy(),
106
+ data._layer_marks.copy(),
107
107
  )
108
108
  for_each_results.delete(for_each_instance_id)
109
109
 
@@ -58,7 +58,7 @@ class TriggerFlowMatchCaseProcess(TriggerFlowBaseProcess):
58
58
  await data.async_emit(
59
59
  f"Match-{ match_id }-Case-{ case_id }",
60
60
  data.value,
61
- layer_marks=data.layer_marks.copy(),
61
+ _layer_marks=data._layer_marks.copy(),
62
62
  )
63
63
  return
64
64
  elif mode == "hit_all":
@@ -71,7 +71,7 @@ class TriggerFlowMatchCaseProcess(TriggerFlowBaseProcess):
71
71
  data.async_emit(
72
72
  f"Match-{ match_id }-Case-{ case_id }",
73
73
  data.value,
74
- layer_marks=data.layer_marks.copy(),
74
+ _layer_marks=data._layer_marks.copy(),
75
75
  )
76
76
  )
77
77
  data.layer_out()
@@ -81,13 +81,13 @@ class TriggerFlowMatchCaseProcess(TriggerFlowBaseProcess):
81
81
  await data.async_emit(
82
82
  f"Match-{ match_id }-Else",
83
83
  data.value,
84
- layer_marks=data.layer_marks.copy(),
84
+ _layer_marks=data._layer_marks.copy(),
85
85
  )
86
86
  else:
87
87
  await data.async_emit(
88
88
  f"Match-{ match_id }-Result",
89
89
  data.value,
90
- layer_marks=data.layer_marks.copy(),
90
+ _layer_marks=data._layer_marks.copy(),
91
91
  )
92
92
 
93
93
  self.to(match_case)
@@ -164,7 +164,7 @@ class TriggerFlowMatchCaseProcess(TriggerFlowBaseProcess):
164
164
  await data.async_emit(
165
165
  f"Match-{ match_id }-Result",
166
166
  list(match_results.values()),
167
- layer_marks=data.layer_marks.copy(),
167
+ _layer_marks=data._layer_marks.copy(),
168
168
  )
169
169
  del data._system_runtime_data[f"match_results.{ data.upper_layer_mark }"]
170
170
  else:
@@ -172,7 +172,7 @@ class TriggerFlowMatchCaseProcess(TriggerFlowBaseProcess):
172
172
  await data.async_emit(
173
173
  f"Match-{ match_id }-Result",
174
174
  data.value,
175
- layer_marks=data.layer_marks.copy(),
175
+ _layer_marks=data._layer_marks.copy(),
176
176
  )
177
177
 
178
178
  for trigger in branch_ends:
@@ -16,7 +16,7 @@ from typing import Any, Protocol, TYPE_CHECKING
16
16
  from .base import AgentlyPlugin
17
17
 
18
18
  if TYPE_CHECKING:
19
- from agently.types.data import PromptModel
19
+ from agently.types.data import PromptModel, SerializableData
20
20
  from agently.core import Prompt
21
21
  from agently.utils import Settings
22
22
  from pydantic import BaseModel
@@ -130,3 +130,7 @@ class PromptGenerator(AgentlyPlugin, Protocol):
130
130
  - For list outputs: use `BaseModel(list=output_result)` to validate.
131
131
  """
132
132
  ...
133
+
134
+ def to_serializable_prompt_data(self, *args, **kwargs) -> "SerializableData": ...
135
+ def to_json_prompt(self, *args, **kwargs) -> str: ...
136
+ def to_yaml_prompt(self, *args, **kwargs) -> str: ...
@@ -43,7 +43,7 @@ class TriggerFlowEventData:
43
43
  trigger_type: Literal["event", "runtime_data", "flow_data"],
44
44
  value: Any,
45
45
  execution: "TriggerFlowExecution",
46
- layer_marks: list[str] | None = None,
46
+ _layer_marks: list[str] | None = None,
47
47
  ):
48
48
  self.trigger_event = trigger_event
49
49
  self.trigger_type = trigger_type
@@ -51,7 +51,7 @@ class TriggerFlowEventData:
51
51
  self.type = trigger_type
52
52
  self.value = value
53
53
  self.execution_id = execution.id
54
- self.layer_marks = layer_marks if layer_marks is not None else []
54
+ self._layer_marks = _layer_marks if _layer_marks is not None else []
55
55
  self.settings = execution.settings
56
56
 
57
57
  self.get_flow_data = execution.get_flow_data
@@ -84,17 +84,17 @@ class TriggerFlowEventData:
84
84
 
85
85
  @property
86
86
  def upper_layer_mark(self):
87
- return self.layer_marks[-2] if len(self.layer_marks) > 1 else None
87
+ return self._layer_marks[-2] if len(self._layer_marks) > 1 else None
88
88
 
89
89
  @property
90
90
  def layer_mark(self):
91
- return self.layer_marks[-1] if len(self.layer_marks) > 0 else None
91
+ return self._layer_marks[-1] if len(self._layer_marks) > 0 else None
92
92
 
93
93
  def layer_in(self):
94
- self.layer_marks.append(uuid.uuid4().hex)
94
+ self._layer_marks.append(uuid.uuid4().hex)
95
95
 
96
96
  def layer_out(self):
97
- self.layer_marks = self.layer_marks[:-1] if len(self.layer_marks) > 0 else []
97
+ self._layer_marks = self._layer_marks[:-1] if len(self._layer_marks) > 0 else []
98
98
 
99
99
 
100
100
  TriggerFlowHandler = Callable[[TriggerFlowEventData], Any]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agently
3
- Version: 4.0.6.7
3
+ Version: 4.0.6.10
4
4
  Summary:
5
5
  License: Apache-2.0
6
6
  License-File: LICENSE
@@ -4,37 +4,37 @@ agently/_default_settings.yaml,sha256=6woqJ2tjg_jl6kwSOwmTMETfVraHidort2smf0Is_q
4
4
  agently/base.py,sha256=PY-HgIQesv3_oBsU25Fwe96C35C4GgpaFdxLBUwh-AA,4692
5
5
  agently/builtins/agent_extensions/AutoFuncExtension.py,sha256=TmwMazwPzb5WXfDqfedY5yZOOMTFIHqaB9Bte29adUc,2433
6
6
  agently/builtins/agent_extensions/ChatSessionExtension.py,sha256=Y6mvnsfAY0rykKtfp-tApwJy5O4SS-YEt2-jaWr83uc,12034
7
- agently/builtins/agent_extensions/ConfigurePromptExtension.py,sha256=A5rYGTa0oSh1N0CdtHQSypFJqcQJm5v5CcCWRnI7iP0,10190
7
+ agently/builtins/agent_extensions/ConfigurePromptExtension.py,sha256=vURsWcy5UnKppBNOAy0ZnY03yMY3QqH7j3ZeixS8VOo,10230
8
8
  agently/builtins/agent_extensions/KeyWaiterExtension.py,sha256=Rf8dB8Yt3_9IJifpiE-Rn6lLIXqZjaNp94lnX6Betgw,5555
9
9
  agently/builtins/agent_extensions/ToolExtension.py,sha256=S3jjumHiauEQ-m46Zkh-1I9ih02kKoj8sBEU82woz1E,6886
10
10
  agently/builtins/agent_extensions/__init__.py,sha256=IxWRQogF8PCVNXeY7D4qhGukEx3JFvfLlUW2x0FbyfA,852
11
11
  agently/builtins/hookers/ConsoleHooker.py,sha256=aJdDj_nG8CiwyelA505zvtpzBSwD52nFIkBRDJGgq3Y,8099
12
12
  agently/builtins/hookers/PureLoggerHooker.py,sha256=fzN0OfhQzgns4KeCNH-qcdm-BdQT0W2kqEmt3Zp2pYI,1906
13
- agently/builtins/hookers/SystemMessageHooker.py,sha256=nU5rOzcuXKdaTXWix3jhZ-4QoD4cMQJZo02wNTpZpjI,5396
14
- agently/builtins/plugins/ModelRequester/OpenAICompatible.py,sha256=xX-iy3qgToD8jIrPsL1NufMb6dlf0SVmX0rPjAkPSQ0,25261
15
- agently/builtins/plugins/PromptGenerator/AgentlyPromptGenerator.py,sha256=KMlXKH44MExTaGnu5cmLtvYT3aXOQiXOZN-F4JeVnJE,28514
13
+ agently/builtins/hookers/SystemMessageHooker.py,sha256=1nh1FY70PYyZOAQGfQiGnwIvo4ZF3NSAjeghI3sInn4,7207
14
+ agently/builtins/plugins/ModelRequester/OpenAICompatible.py,sha256=Druzptw_aKtCAI-a3wqFO4KgtzAP0L6HZZ_2I7t2u80,25397
15
+ agently/builtins/plugins/PromptGenerator/AgentlyPromptGenerator.py,sha256=GRRR9uxgyCXHKgt_r2BinWnhKy8rYUN8CG9ld2P8n4E,30841
16
16
  agently/builtins/plugins/ResponseParser/AgentlyResponseParser.py,sha256=FEhfsiHB4Bx7HfghnObklLj08j8IVwGh0WEVD6U-G3U,17445
17
17
  agently/builtins/plugins/ToolManager/AgentlyToolManager.py,sha256=oaqte5LAryZQMD6vuEbKhe6kOLUyZTRZswC1MDFiYxw,9138
18
18
  agently/builtins/plugins/__init__.py,sha256=wj4_U9TTekc2CmjppbXKUREDFRXFX1y0ySOW-CxQuok,801
19
19
  agently/builtins/tools/Browse.py,sha256=gIePs-gtsqOI_ZTReGqEcoKvhs4FkBzTxow--QS5_ek,3469
20
20
  agently/builtins/tools/Search.py,sha256=tUynNiW_ZMAGaB2ua3HRcY_trIbLEoASFE-p2QMQ0Zg,7362
21
21
  agently/builtins/tools/__init__.py,sha256=pFOWgH2C3xRvgQo3UVdkj4yHjF9nNtmoVHmOZfoGsyU,647
22
- agently/core/Agent.py,sha256=HbUqlCWFgtziavN8r-2RFQyrbHMMxKA6y-io-0CY8TA,9022
22
+ agently/core/Agent.py,sha256=hxRR3ca71XAabViIZGL31EYF4CAxmQS2KJrktCUs39k,10329
23
23
  agently/core/EventCenter.py,sha256=sknU5w9MpGDQgMOF9c5k4PfM4SNT5X_LrpYte2HaFNM,10861
24
24
  agently/core/ExtensionHandlers.py,sha256=88iSAW50bgMshB56cTgKg30eOjZQyXiJY1en4w7afWY,2076
25
- agently/core/ModelRequest.py,sha256=rB8LQ2_7TJlOHZQ6jIKSfXDDQar7dv_bi8g7xpIoUN4,17355
25
+ agently/core/ModelRequest.py,sha256=Sagd7HQozPPM41gbhYU9Lzj68IKPgR_xa00PA7lzpF4,23171
26
26
  agently/core/PluginManager.py,sha256=oUnXbe1ilQTOWwnENxtGtV6wG-yZriCxniqfuxuTFO0,4354
27
- agently/core/Prompt.py,sha256=8SlqytnAIM_FIWbY2Jx-T7yOs_jqmkz9cux8-2iOCjA,8023
27
+ agently/core/Prompt.py,sha256=oAxRZ7kG07mM6G7p6gP_zX41TgGb8vA-IilcnCb_Gc4,8432
28
28
  agently/core/Tool.py,sha256=PNYf_BwVefr8IOqf5asLaVq2fU7hQaFJwJVj3S4fq84,1871
29
29
  agently/core/TriggerFlow/BluePrint.py,sha256=Lz-wbA0f79t7VjvX0knH-9AC_Qz9wts0QFemL97R3jo,4810
30
- agently/core/TriggerFlow/Chunk.py,sha256=i5oTT9-dI-mXI6vbWwnQZ5e1ryGgZDYsyE9ALqbS2tQ,1555
31
- agently/core/TriggerFlow/Execution.py,sha256=9up20Jim7KyHsRJUMckvPa8G68Q5ipMKn34wIxx5OKA,11637
30
+ agently/core/TriggerFlow/Chunk.py,sha256=d5cdK8fL-Ayg4-6qJom0J3wDIZFevoCw_kHGYMXBKOU,1559
31
+ agently/core/TriggerFlow/Execution.py,sha256=sXxDt5l9m2ZWMG6JZjnt50akyDFEu4I-YB2yhW-UP5E,11640
32
32
  agently/core/TriggerFlow/Process.py,sha256=doIDUa7x0j1TVuOhp-hraC0hHLwpistF-Dksf76NJvQ,837
33
33
  agently/core/TriggerFlow/TriggerFlow.py,sha256=03xC1EdWiNfnRbAocH-97JcxyzfCnChivI1KmvPt6-E,7671
34
34
  agently/core/TriggerFlow/__init__.py,sha256=eHc6ldUIS0kka_1fZXkdaHFnSDoXaGSvXggwVszMAJQ,911
35
- agently/core/TriggerFlow/process/BaseProcess.py,sha256=FOYfpQGdWrCe0cd-qbWK_bpNCQCHOULnZvzH36C8Kls,13650
36
- agently/core/TriggerFlow/process/ForEachProcess.py,sha256=oBI7KIpnj2tbczt_cTJCNvS793Xjif9_31ytkrEzQlE,4546
37
- agently/core/TriggerFlow/process/MatchCaseProcess.py,sha256=-NpbAlXq054juNkFCsDdWsIBMoHHKV1-cEsgndcd9KY,7888
35
+ agently/core/TriggerFlow/process/BaseProcess.py,sha256=oUlsj0AgK39e24kGWCZY6pXDlpbSVJ-mh-UPhJrqgRI,14467
36
+ agently/core/TriggerFlow/process/ForEachProcess.py,sha256=rjUVouZENnuGFp7GXGTgWJT7uMEhczHamWr9cFugsh0,4549
37
+ agently/core/TriggerFlow/process/MatchCaseProcess.py,sha256=MKY5Yh66JiMABhCzamRl8UZOBjbD75TFp84Jw6o_t68,7900
38
38
  agently/core/TriggerFlow/process/__init__.py,sha256=BP5bAr9LRVVD83KFqXeprgTmXA1iCSOSsD509BtoX_E,753
39
39
  agently/core/__init__.py,sha256=CPglSpW5oEEmWpCpdvv9wK4myXmVipjuZm5HtMq6Vxo,1214
40
40
  agently/integrations/chromadb.py,sha256=hLrjwsU_d4SOGRX0bf-55uiA73YarIzRa8ORFnwu3W8,9797
@@ -48,13 +48,13 @@ agently/types/data/serializable.py,sha256=v2KlyKNOKp4L6J_Ueupb-gCyrnngvBskFUwNPS
48
48
  agently/types/data/tool.py,sha256=wE8Dda2JtY5cojpHUuQrw7PNeVZ6Zma968bn-pUmS7I,1529
49
49
  agently/types/plugins/EventHooker.py,sha256=kb80-baVc3fVlrddW5syv9uSD8a2Mcw8Fd3I2HQhY_Y,1030
50
50
  agently/types/plugins/ModelRequester.py,sha256=urG1zFX0b4U6ZKSO50IbW5IHK3ydmRgUom7O7Niqk8s,3875
51
- agently/types/plugins/PromptGenerator.py,sha256=45jmVzAkyl1Yj2M8RVfQM_zFAJZP4zrPuQkHbWIQSRQ,4531
51
+ agently/types/plugins/PromptGenerator.py,sha256=V8kqT0Eeq09AQqfGA-SZ5mNKeit1UrmqlDQCquSMzUU,4752
52
52
  agently/types/plugins/ResponseParser.py,sha256=_IRbQhT-G1ZNg2zkJgCYNF5qRaIzrDfbxLC7kO-tdK4,3984
53
53
  agently/types/plugins/ToolManager.py,sha256=q1Y3G_tzh1AU3s13H-zTDZIkR4W1mjh9E6AKudFOvyg,2421
54
54
  agently/types/plugins/__init__.py,sha256=gz_EpgBQGndIQHY5vJB2YRzAN5yIb3FZZG7pC8lB1lM,848
55
55
  agently/types/plugins/base.py,sha256=AoNLwsH5IZBQt7_NZfxMWMhAk6PJSOFHR0IYOXp1imI,1167
56
56
  agently/types/trigger_flow/__init__.py,sha256=Gj31SmWBC4qtrOqQedyGsnCfeSkUf3XvZNFrJ2QbMNw,777
57
- agently/types/trigger_flow/trigger_flow.py,sha256=uDUZiila_4Rr41zUlzR4QqaRaraC43XTFfj-jnnG2G0,3787
57
+ agently/types/trigger_flow/trigger_flow.py,sha256=6lvhDwizIV5p3h61l1GsmJU_9Tw8v3u-SnHuygkSJdo,3799
58
58
  agently/utils/DataFormatter.py,sha256=0P92t81vnp-rJSJvlbTF3yM-PRiteB19BNEQ8cmvmns,9444
59
59
  agently/utils/DataLocator.py,sha256=ss8OLet9HN0U1PZb-OCHS6KL54kv7vFZph6G0-GBidk,6015
60
60
  agently/utils/DataPathBuilder.py,sha256=sEzE1i2EWn7NMkCCXDT50gR6_qMzcZ0y0YGkYbXdB3s,10007
@@ -70,7 +70,7 @@ agently/utils/Storage.py,sha256=E7QyNJ9T0yOUafPgdP90La698hgLMSGjhJ7qCEHzxxw,9438
70
70
  agently/utils/StreamingJSONCompleter.py,sha256=aZ9zuGUTQlP-QKbXHUZCf6EtVuG49MKn8xdhw0VhDEA,4292
71
71
  agently/utils/StreamingJSONParser.py,sha256=sPPJOtj5OYvsrukRErcoxRl4yuV1zDuf7pQ_pvw_Zow,21116
72
72
  agently/utils/__init__.py,sha256=7MDln5OVkqFEdhhuG8VTdr2q02UWwCj-udndwzWV_iQ,1280
73
- agently-4.0.6.7.dist-info/METADATA,sha256=LZiqVCSE6wlDUhct8N33KtNf1M8Qs8aWFQHCCB3oAmo,7112
74
- agently-4.0.6.7.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
75
- agently-4.0.6.7.dist-info/licenses/LICENSE,sha256=Y5ZgAdYgMFigPT8dhN18dTLRtBshOSfWhTDRO1t0Cq4,11360
76
- agently-4.0.6.7.dist-info/RECORD,,
73
+ agently-4.0.6.10.dist-info/METADATA,sha256=FfpitXk1hlaWpkToJ08XHQhbkpC_zijeCMN2UaZI0Xs,7113
74
+ agently-4.0.6.10.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
75
+ agently-4.0.6.10.dist-info/licenses/LICENSE,sha256=Y5ZgAdYgMFigPT8dhN18dTLRtBshOSfWhTDRO1t0Cq4,11360
76
+ agently-4.0.6.10.dist-info/RECORD,,