agently 4.0.7__tar.gz → 4.0.7.1__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.
Files changed (77) hide show
  1. {agently-4.0.7 → agently-4.0.7.1}/PKG-INFO +1 -1
  2. {agently-4.0.7 → agently-4.0.7.1}/agently/_default_settings.yaml +2 -1
  3. {agently-4.0.7 → agently-4.0.7.1}/agently/base.py +17 -1
  4. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/plugins/PromptGenerator/AgentlyPromptGenerator.py +21 -5
  5. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/tools/Search.py +1 -1
  6. {agently-4.0.7 → agently-4.0.7.1}/agently/core/ModelRequest.py +6 -1
  7. {agently-4.0.7 → agently-4.0.7.1}/agently/core/TriggerFlow/TriggerFlow.py +1 -1
  8. {agently-4.0.7 → agently-4.0.7.1}/agently/core/TriggerFlow/process/BaseProcess.py +8 -4
  9. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/DataFormatter.py +8 -2
  10. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/DataLocator.py +108 -31
  11. {agently-4.0.7 → agently-4.0.7.1}/pyproject.toml +1 -1
  12. {agently-4.0.7 → agently-4.0.7.1}/LICENSE +0 -0
  13. {agently-4.0.7 → agently-4.0.7.1}/README.md +0 -0
  14. {agently-4.0.7 → agently-4.0.7.1}/agently/__init__.py +0 -0
  15. {agently-4.0.7 → agently-4.0.7.1}/agently/_default_init.py +0 -0
  16. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/agent_extensions/AutoFuncExtension.py +0 -0
  17. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/agent_extensions/ChatSessionExtension.py +0 -0
  18. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/agent_extensions/ConfigurePromptExtension.py +0 -0
  19. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/agent_extensions/KeyWaiterExtension.py +0 -0
  20. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/agent_extensions/ToolExtension.py +0 -0
  21. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/agent_extensions/__init__.py +0 -0
  22. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/hookers/ConsoleHooker.py +0 -0
  23. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/hookers/PureLoggerHooker.py +0 -0
  24. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/hookers/SystemMessageHooker.py +0 -0
  25. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/plugins/ModelRequester/OpenAICompatible.py +0 -0
  26. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/plugins/ResponseParser/AgentlyResponseParser.py +0 -0
  27. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/plugins/ToolManager/AgentlyToolManager.py +0 -0
  28. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/plugins/__init__.py +0 -0
  29. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/tools/Browse.py +0 -0
  30. {agently-4.0.7 → agently-4.0.7.1}/agently/builtins/tools/__init__.py +0 -0
  31. {agently-4.0.7 → agently-4.0.7.1}/agently/core/Agent.py +0 -0
  32. {agently-4.0.7 → agently-4.0.7.1}/agently/core/EventCenter.py +0 -0
  33. {agently-4.0.7 → agently-4.0.7.1}/agently/core/ExtensionHandlers.py +0 -0
  34. {agently-4.0.7 → agently-4.0.7.1}/agently/core/PluginManager.py +0 -0
  35. {agently-4.0.7 → agently-4.0.7.1}/agently/core/Prompt.py +0 -0
  36. {agently-4.0.7 → agently-4.0.7.1}/agently/core/Tool.py +0 -0
  37. {agently-4.0.7 → agently-4.0.7.1}/agently/core/TriggerFlow/BluePrint.py +0 -0
  38. {agently-4.0.7 → agently-4.0.7.1}/agently/core/TriggerFlow/Chunk.py +0 -0
  39. {agently-4.0.7 → agently-4.0.7.1}/agently/core/TriggerFlow/Execution.py +0 -0
  40. {agently-4.0.7 → agently-4.0.7.1}/agently/core/TriggerFlow/Process.py +0 -0
  41. {agently-4.0.7 → agently-4.0.7.1}/agently/core/TriggerFlow/__init__.py +0 -0
  42. {agently-4.0.7 → agently-4.0.7.1}/agently/core/TriggerFlow/process/ForEachProcess.py +0 -0
  43. {agently-4.0.7 → agently-4.0.7.1}/agently/core/TriggerFlow/process/MatchCaseProcess.py +0 -0
  44. {agently-4.0.7 → agently-4.0.7.1}/agently/core/TriggerFlow/process/__init__.py +0 -0
  45. {agently-4.0.7 → agently-4.0.7.1}/agently/core/__init__.py +0 -0
  46. {agently-4.0.7 → agently-4.0.7.1}/agently/integrations/chromadb.py +0 -0
  47. {agently-4.0.7 → agently-4.0.7.1}/agently/types/__init__.py +0 -0
  48. {agently-4.0.7 → agently-4.0.7.1}/agently/types/data/__init__.py +0 -0
  49. {agently-4.0.7 → agently-4.0.7.1}/agently/types/data/event.py +0 -0
  50. {agently-4.0.7 → agently-4.0.7.1}/agently/types/data/prompt.py +0 -0
  51. {agently-4.0.7 → agently-4.0.7.1}/agently/types/data/request.py +0 -0
  52. {agently-4.0.7 → agently-4.0.7.1}/agently/types/data/response.py +0 -0
  53. {agently-4.0.7 → agently-4.0.7.1}/agently/types/data/serializable.py +0 -0
  54. {agently-4.0.7 → agently-4.0.7.1}/agently/types/data/tool.py +0 -0
  55. {agently-4.0.7 → agently-4.0.7.1}/agently/types/plugins/EventHooker.py +0 -0
  56. {agently-4.0.7 → agently-4.0.7.1}/agently/types/plugins/ModelRequester.py +0 -0
  57. {agently-4.0.7 → agently-4.0.7.1}/agently/types/plugins/PromptGenerator.py +0 -0
  58. {agently-4.0.7 → agently-4.0.7.1}/agently/types/plugins/ResponseParser.py +0 -0
  59. {agently-4.0.7 → agently-4.0.7.1}/agently/types/plugins/ToolManager.py +0 -0
  60. {agently-4.0.7 → agently-4.0.7.1}/agently/types/plugins/__init__.py +0 -0
  61. {agently-4.0.7 → agently-4.0.7.1}/agently/types/plugins/base.py +0 -0
  62. {agently-4.0.7 → agently-4.0.7.1}/agently/types/trigger_flow/__init__.py +0 -0
  63. {agently-4.0.7 → agently-4.0.7.1}/agently/types/trigger_flow/trigger_flow.py +0 -0
  64. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/DataPathBuilder.py +0 -0
  65. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/FunctionShifter.py +0 -0
  66. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/GeneratorConsumer.py +0 -0
  67. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/LazyImport.py +0 -0
  68. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/Logger.py +0 -0
  69. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/Messenger.py +0 -0
  70. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/PythonSandbox.py +0 -0
  71. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/RuntimeData.py +0 -0
  72. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/SerializableRuntimeData.py +0 -0
  73. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/Settings.py +0 -0
  74. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/Storage.py +0 -0
  75. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/StreamingJSONCompleter.py +0 -0
  76. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/StreamingJSONParser.py +0 -0
  77. {agently-4.0.7 → agently-4.0.7.1}/agently/utils/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agently
3
- Version: 4.0.7
3
+ Version: 4.0.7.1
4
4
  Summary:
5
5
  License: Apache-2.0
6
6
  License-File: LICENSE
@@ -43,6 +43,7 @@ runtime:
43
43
  show_model_logs: False
44
44
  show_tool_logs: False
45
45
  show_trigger_flow_logs: False
46
+ httpx_log_level: "WARNING"
46
47
  plugins:
47
48
  ToolManager:
48
- activate: AgentlyToolManager
49
+ activate: AgentlyToolManager
@@ -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 logging
15
16
  from typing import Any, Literal, Type, TYPE_CHECKING, TypeVar, Generic, cast
16
17
 
17
18
  from agently.utils import Settings, create_logger, FunctionShifter, DataFormatter
@@ -37,6 +38,10 @@ _hook_default_event_handlers(event_center)
37
38
  async_system_message = event_center.async_system_message
38
39
  system_message = event_center.system_message
39
40
  logger = create_logger()
41
+ httpx_level_name = settings.get("runtime.httpx_log_level", "WARNING")
42
+ httpx_level = getattr(logging, str(httpx_level_name).upper(), logging.WARNING)
43
+ logging.getLogger("httpx").setLevel(httpx_level)
44
+ logging.getLogger("httpcore").setLevel(httpx_level)
40
45
  tool = Tool(plugin_manager, settings)
41
46
  _agently_messenger = event_center.create_messenger("Agently")
42
47
 
@@ -70,11 +75,13 @@ settings.update_mappings(
70
75
  "runtime.show_model_logs": True,
71
76
  "runtime.show_tool_logs": True,
72
77
  "runtime.show_trigger_flow_logs": True,
78
+ "runtime.httpx_log_level": "INFO",
73
79
  },
74
80
  False: {
75
81
  "runtime.show_model_logs": False,
76
82
  "runtime.show_tool_logs": False,
77
83
  "runtime.show_trigger_flow_logs": False,
84
+ "runtime.httpx_log_level": "WARNING",
78
85
  },
79
86
  }
80
87
  }
@@ -117,7 +124,16 @@ class AgentlyMain(Generic[A]):
117
124
  self.tool = tool
118
125
  self.AgentType = AgentType
119
126
 
120
- self.set_settings = self.settings.set_settings
127
+ def set_settings(key: str, value: "SerializableValue", *, auto_load_env: bool = False):
128
+ self.settings.set_settings(key, value, auto_load_env=auto_load_env)
129
+ if key in ("runtime.httpx_log_level", "debug"):
130
+ level_name = self.settings.get("runtime.httpx_log_level", "WARNING")
131
+ level = getattr(logging, str(level_name).upper(), logging.WARNING)
132
+ logging.getLogger("httpx").setLevel(level)
133
+ logging.getLogger("httpcore").setLevel(level)
134
+ return self
135
+
136
+ self.set_settings = set_settings
121
137
 
122
138
  def set_debug_console(self, debug_console_status: Literal["ON", "OFF"]):
123
139
  match debug_console_status:
@@ -589,13 +589,29 @@ class AgentlyPromptGenerator(PromptGenerator):
589
589
  fields = {}
590
590
  validators = {}
591
591
 
592
- def ensure_list_and_cast(v: Any, target_type: type):
592
+ def ensure_list_and_cast(v: Any, target_type: Any):
593
593
  if not isinstance(v, list):
594
594
  v = [v]
595
- return [
596
- (target_type(item) if target_type is not Any and not isinstance(item, target_type) else item)
597
- for item in v
598
- ]
595
+ casted = []
596
+ for item in v:
597
+ if target_type is Any or not isinstance(target_type, type):
598
+ casted.append(item)
599
+ continue
600
+ target_type = cast(type, target_type)
601
+ if isinstance(item, target_type):
602
+ casted.append(item)
603
+ continue
604
+ if isinstance(item, Mapping):
605
+ model_validate = getattr(target_type, "model_validate", None)
606
+ if callable(model_validate):
607
+ casted.append(model_validate(item))
608
+ continue
609
+ parse_obj = getattr(target_type, "parse_obj", None)
610
+ if callable(parse_obj):
611
+ casted.append(parse_obj(item))
612
+ continue
613
+ casted.append(target_type(item))
614
+ return casted
599
615
 
600
616
  if isinstance(schema, Mapping):
601
617
  for field_name, field_type_schema in schema.items():
@@ -103,7 +103,7 @@ class Search:
103
103
  ] = "us-en",
104
104
  options: dict[str, Any] | None = None,
105
105
  ):
106
- LazyImport.import_package("ddgs")
106
+ LazyImport.import_package("ddgs", version_constraint=">=9.10.0")
107
107
  from ddgs import DDGS
108
108
 
109
109
  self.proxy = proxy
@@ -153,6 +153,11 @@ class ModelResponseResult:
153
153
  return await self._response_parser.async_get_data(type=type)
154
154
  return await self._response_parser.async_get_data(type=type)
155
155
 
156
+ @overload
157
+ async def async_get_data_object(
158
+ self,
159
+ ) -> "BaseModel | None": ...
160
+
156
161
  @overload
157
162
  async def async_get_data_object(
158
163
  self,
@@ -467,7 +472,7 @@ class ModelRequest:
467
472
  prompt: Any,
468
473
  mappings: dict[str, Any] | None = None,
469
474
  ):
470
- self.prompt.set("system", ["YOU MUST REACT AND RESPOND AS {system.role}!"])
475
+ self.prompt.set("system", ["YOU MUST REACT AND RESPOND AS {system.your_role}!"])
471
476
  self.prompt.set("system.your_role", prompt, mappings)
472
477
  return self
473
478
 
@@ -227,7 +227,7 @@ class TriggerFlow:
227
227
  self,
228
228
  initial_value: Any = None,
229
229
  *,
230
- timeout: int | None = 10,
230
+ timeout: float | None = 10.0,
231
231
  concurrency: int | None = None,
232
232
  ):
233
233
  execution = self.create_execution(concurrency=concurrency)
@@ -294,16 +294,20 @@ class TriggerFlowBaseProcess:
294
294
  chunk = self._flow_chunk(chunk_name)(chunk_func)
295
295
  else:
296
296
  chunk = self._flow_chunk(chunk.__name__)(chunk) if callable(chunk) else chunk
297
+ typed_chunk = cast(TriggerFlowChunk, chunk)
297
298
  triggers_to_wait[chunk.trigger] = False
298
299
  trigger_to_chunk_name[chunk.trigger] = chunk.name
299
300
  results[chunk.name] = None
300
301
 
301
302
  if semaphore is None:
302
- handler = chunk.async_call
303
+ handler = typed_chunk.async_call
303
304
  else:
304
- async def handler(data: "TriggerFlowEventData", _chunk=chunk):
305
- async with semaphore:
306
- return await _chunk.async_call(data)
305
+ def make_handler(bound_chunk: TriggerFlowChunk):
306
+ async def handler(data: "TriggerFlowEventData"):
307
+ async with semaphore:
308
+ return await bound_chunk.async_call(data)
309
+ return handler
310
+ handler = make_handler(typed_chunk)
307
311
 
308
312
  self._blue_print.add_handler(
309
313
  self.trigger_type,
@@ -56,15 +56,21 @@ class DataFormatter:
56
56
  if issubclass(value, BaseModel):
57
57
  extracted_value = {}
58
58
  for name, field in value.model_fields.items():
59
+ annotation = field.annotation
60
+ if hasattr(field, "rebuild_annotation"):
61
+ try:
62
+ annotation = field.rebuild_annotation()
63
+ except Exception:
64
+ annotation = field.annotation
59
65
  extracted_value.update(
60
66
  {
61
67
  name: (
62
68
  (
63
- DataFormatter.sanitize(field.annotation, remain_type=remain_type),
69
+ DataFormatter.sanitize(annotation, remain_type=remain_type),
64
70
  field.description,
65
71
  )
66
72
  if field.description
67
- else (DataFormatter.sanitize(field.annotation, remain_type=remain_type),)
73
+ else (DataFormatter.sanitize(annotation, remain_type=remain_type),)
68
74
  )
69
75
  }
70
76
  )
@@ -21,6 +21,101 @@ if TYPE_CHECKING:
21
21
 
22
22
 
23
23
  class DataLocator:
24
+ @staticmethod
25
+ def _locate_path_parts(
26
+ result: Any,
27
+ path_parts: list[str],
28
+ *,
29
+ style: Literal["dot", "slash"],
30
+ default: Any,
31
+ ):
32
+ if not path_parts:
33
+ return result
34
+ path_part = path_parts[0]
35
+ remaining = path_parts[1:]
36
+ if style == "dot":
37
+ if "[" in path_part:
38
+ path_key_and_index = path_part.split("[")
39
+ path_key = path_key_and_index[0]
40
+ path_index = path_key_and_index[1][:-1]
41
+ if isinstance(result, Mapping):
42
+ result = result.get(path_key, default)
43
+ else:
44
+ return default
45
+ if path_index in ("*", ""):
46
+ if not isinstance(result, str) and isinstance(result, Sequence):
47
+ values = []
48
+ for item in result:
49
+ value = DataLocator._locate_path_parts(
50
+ item,
51
+ remaining,
52
+ style=style,
53
+ default=default,
54
+ )
55
+ if value is default:
56
+ return default
57
+ values.append(value)
58
+ return values
59
+ return default
60
+ try:
61
+ index = int(path_index)
62
+ except Exception:
63
+ return default
64
+ if not isinstance(result, str) and isinstance(result, Sequence):
65
+ try:
66
+ return DataLocator._locate_path_parts(
67
+ result[index],
68
+ remaining,
69
+ style=style,
70
+ default=default,
71
+ )
72
+ except Exception:
73
+ return default
74
+ return default
75
+ else:
76
+ if isinstance(result, Mapping):
77
+ return DataLocator._locate_path_parts(
78
+ result.get(path_part, default),
79
+ remaining,
80
+ style=style,
81
+ default=default,
82
+ )
83
+ return default
84
+ else:
85
+ if path_part == "*":
86
+ if not isinstance(result, str) and isinstance(result, Sequence):
87
+ values = []
88
+ for item in result:
89
+ value = DataLocator._locate_path_parts(
90
+ item,
91
+ remaining,
92
+ style=style,
93
+ default=default,
94
+ )
95
+ if value is default:
96
+ return default
97
+ values.append(value)
98
+ return values
99
+ return default
100
+ if isinstance(result, Mapping):
101
+ return DataLocator._locate_path_parts(
102
+ result.get(path_part, default),
103
+ remaining,
104
+ style=style,
105
+ default=default,
106
+ )
107
+ if not isinstance(result, str) and isinstance(result, Sequence):
108
+ try:
109
+ return DataLocator._locate_path_parts(
110
+ result[int(path_part)],
111
+ remaining,
112
+ style=style,
113
+ default=default,
114
+ )
115
+ except Exception:
116
+ return default
117
+ return default
118
+
24
119
  @staticmethod
25
120
  def locate_path_in_dict(
26
121
  original_dict: dict,
@@ -34,42 +129,24 @@ class DataLocator:
34
129
  match style:
35
130
  case "dot":
36
131
  try:
37
- result = original_dict
38
132
  path_parts = path.split(".")
39
- for path_part in path_parts:
40
- if "[" in path_part:
41
- path_key_and_index = path_part.split("[")
42
- path_key = path_key_and_index[0]
43
- path_index = int(path_key_and_index[1][:-1])
44
- if isinstance(result, Mapping):
45
- result = result[path_key]
46
- else:
47
- return default
48
- if not isinstance(result, str) and isinstance(result, Sequence):
49
- result = result[path_index]
50
- else:
51
- return default
52
- else:
53
- if isinstance(result, Mapping):
54
- result = result[path_part]
55
- else:
56
- return default
57
- return result
133
+ return DataLocator._locate_path_parts(
134
+ original_dict,
135
+ path_parts,
136
+ style="dot",
137
+ default=default,
138
+ )
58
139
  except Exception:
59
140
  return default
60
141
  case "slash":
61
- result = original_dict
62
- path_parts = path.split("/")
63
142
  try:
64
- for path_part in path_parts:
65
- if path_part:
66
- if isinstance(result, Mapping):
67
- result = result[path_part]
68
- elif not isinstance(result, str) and isinstance(result, Sequence):
69
- result = result[int(path_part)]
70
- else:
71
- return default
72
- return result
143
+ path_parts = [part for part in path.split("/") if part]
144
+ return DataLocator._locate_path_parts(
145
+ original_dict,
146
+ path_parts,
147
+ style="slash",
148
+ default=default,
149
+ )
73
150
  except Exception:
74
151
  return default
75
152
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agently"
3
- version = "4.0.7"
3
+ version = "4.0.7.1"
4
4
  description = ""
5
5
  authors = [
6
6
  {name = "Agently Team",email = "developer@agently.tech"},
File without changes
File without changes
File without changes
File without changes
File without changes