agno 2.1.8__py3-none-any.whl → 2.1.9__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.
@@ -122,6 +122,7 @@ class Knowledge:
122
122
  exclude=exclude,
123
123
  upsert=upsert,
124
124
  skip_if_exists=skip_if_exists,
125
+ reader=reader,
125
126
  )
126
127
  for url in urls:
127
128
  await self.add_content_async(
@@ -133,6 +134,7 @@ class Knowledge:
133
134
  exclude=exclude,
134
135
  upsert=upsert,
135
136
  skip_if_exists=skip_if_exists,
137
+ reader=reader,
136
138
  )
137
139
  for i, text_content in enumerate(text_contents):
138
140
  content_name = f"{name}_{i}" if name else f"text_content_{i}"
@@ -146,6 +148,7 @@ class Knowledge:
146
148
  exclude=exclude,
147
149
  upsert=upsert,
148
150
  skip_if_exists=skip_if_exists,
151
+ reader=reader,
149
152
  )
150
153
  if topics:
151
154
  await self.add_content_async(
@@ -168,6 +171,7 @@ class Knowledge:
168
171
  remote_content=remote_content,
169
172
  upsert=upsert,
170
173
  skip_if_exists=skip_if_exists,
174
+ reader=reader,
171
175
  )
172
176
 
173
177
  else:
agno/models/message.py CHANGED
@@ -2,6 +2,8 @@ import json
2
2
  from time import time
3
3
  from typing import Any, Dict, List, Optional, Sequence, Union
4
4
 
5
+ from uuid import uuid4
6
+
5
7
  from pydantic import BaseModel, ConfigDict, Field
6
8
 
7
9
  from agno.media import Audio, File, Image, Video
@@ -51,6 +53,8 @@ class Citations(BaseModel):
51
53
  class Message(BaseModel):
52
54
  """Message sent to the Model"""
53
55
 
56
+ id: str = Field(default_factory=lambda: str(uuid4()))
57
+
54
58
  # The role of the message author.
55
59
  # One of system, user, assistant, or tool.
56
60
  role: str
@@ -259,6 +263,7 @@ class Message(BaseModel):
259
263
  def to_dict(self) -> Dict[str, Any]:
260
264
  """Returns the message as a dictionary."""
261
265
  message_dict = {
266
+ "id": self.id,
262
267
  "content": self.content,
263
268
  "reasoning_content": self.reasoning_content,
264
269
  "from_history": self.from_history,
agno/team/team.py CHANGED
@@ -1674,11 +1674,11 @@ class Team:
1674
1674
  )
1675
1675
  self.model = cast(Model, self.model)
1676
1676
 
1677
- if metadata is not None:
1678
- if self.metadata is not None:
1679
- merge_dictionaries(metadata, self.metadata)
1680
- else:
1677
+ if self.metadata is not None:
1678
+ if metadata is None:
1681
1679
  metadata = self.metadata
1680
+ else:
1681
+ merge_dictionaries(metadata, self.metadata)
1682
1682
 
1683
1683
  # Create a new run_response for this attempt
1684
1684
  run_response = TeamRunOutput(
@@ -2201,7 +2201,7 @@ class Team:
2201
2201
 
2202
2202
  # Execute post-hooks after output is generated but before response is returned
2203
2203
  if self.post_hooks is not None:
2204
- self._execute_post_hooks(
2204
+ await self._aexecute_post_hooks(
2205
2205
  hooks=self.post_hooks, # type: ignore
2206
2206
  run_output=run_response,
2207
2207
  session_state=session_state,
@@ -2427,12 +2427,12 @@ class Team:
2427
2427
  )
2428
2428
 
2429
2429
  self.model = cast(Model, self.model)
2430
-
2431
- if metadata is not None:
2432
- if self.metadata is not None:
2433
- merge_dictionaries(metadata, self.metadata)
2434
- else:
2430
+
2431
+ if self.metadata is not None:
2432
+ if metadata is None:
2435
2433
  metadata = self.metadata
2434
+ else:
2435
+ merge_dictionaries(metadata, self.metadata)
2436
2436
 
2437
2437
  # Get knowledge filters
2438
2438
  effective_filters = knowledge_filters
@@ -165,7 +165,7 @@ class GoogleCalendarTools(Toolkit):
165
165
 
166
166
  try:
167
167
  service = cast(Resource, self.service)
168
-
168
+
169
169
  events_result = (
170
170
  service.events()
171
171
  .list(
@@ -247,9 +247,9 @@ class GoogleCalendarTools(Toolkit):
247
247
 
248
248
  # Determine sendUpdates value based on notify_attendees parameter
249
249
  send_updates = "all" if notify_attendees and attendees else "none"
250
-
250
+
251
251
  service = cast(Resource, self.service)
252
-
252
+
253
253
  event_result = (
254
254
  service.events()
255
255
  .insert(
@@ -298,7 +298,7 @@ class GoogleCalendarTools(Toolkit):
298
298
  """
299
299
  try:
300
300
  service = cast(Resource, self.service)
301
-
301
+
302
302
  # First get the existing event to preserve its structure
303
303
  event = service.events().get(calendarId=self.calendar_id, eventId=event_id).execute()
304
304
 
@@ -333,16 +333,13 @@ class GoogleCalendarTools(Toolkit):
333
333
 
334
334
  # Determine sendUpdates value based on notify_attendees parameter
335
335
  send_updates = "all" if notify_attendees and attendees else "none"
336
-
336
+
337
337
  # Update the event
338
-
338
+
339
339
  updated_event = (
340
- service.events().update(
341
- calendarId=self.calendar_id,
342
- eventId=event_id,
343
- body=event,
344
- sendUpdates=send_updates
345
- ).execute()
340
+ service.events()
341
+ .update(calendarId=self.calendar_id, eventId=event_id, body=event, sendUpdates=send_updates)
342
+ .execute()
346
343
  )
347
344
 
348
345
  log_debug(f"Event {event_id} updated successfully.")
@@ -366,14 +363,10 @@ class GoogleCalendarTools(Toolkit):
366
363
  try:
367
364
  # Determine sendUpdates value based on notify_attendees parameter
368
365
  send_updates = "all" if notify_attendees else "none"
369
-
366
+
370
367
  service = cast(Resource, self.service)
371
-
372
- service.events().delete(
373
- calendarId=self.calendar_id,
374
- eventId=event_id,
375
- sendUpdates=send_updates
376
- ).execute()
368
+
369
+ service.events().delete(calendarId=self.calendar_id, eventId=event_id, sendUpdates=send_updates).execute()
377
370
 
378
371
  log_debug(f"Event {event_id} deleted successfully.")
379
372
  return json.dumps({"success": True, "message": f"Event {event_id} deleted successfully."})
@@ -400,7 +393,7 @@ class GoogleCalendarTools(Toolkit):
400
393
  """
401
394
  try:
402
395
  service = cast(Resource, self.service)
403
-
396
+
404
397
  params = {
405
398
  "calendarId": self.calendar_id,
406
399
  "maxResults": min(max_results, 100),
@@ -111,13 +111,16 @@ class Condition:
111
111
  audio=current_audio + all_audio,
112
112
  )
113
113
 
114
- def _evaluate_condition(self, step_input: StepInput) -> bool:
114
+ def _evaluate_condition(self, step_input: StepInput, session_state: Optional[Dict[str, Any]] = None) -> bool:
115
115
  """Evaluate the condition and return boolean result"""
116
116
  if isinstance(self.evaluator, bool):
117
117
  return self.evaluator
118
118
 
119
119
  if callable(self.evaluator):
120
- result = self.evaluator(step_input)
120
+ if session_state is not None and self._evaluator_has_session_state_param():
121
+ result = self.evaluator(step_input, session_state=session_state) # type: ignore[call-arg]
122
+ else:
123
+ result = self.evaluator(step_input)
121
124
 
122
125
  if isinstance(result, bool):
123
126
  return result
@@ -127,16 +130,24 @@ class Condition:
127
130
 
128
131
  return False
129
132
 
130
- async def _aevaluate_condition(self, step_input: StepInput) -> bool:
133
+ async def _aevaluate_condition(self, step_input: StepInput, session_state: Optional[Dict[str, Any]] = None) -> bool:
131
134
  """Async version of condition evaluation"""
132
135
  if isinstance(self.evaluator, bool):
133
136
  return self.evaluator
134
137
 
135
138
  if callable(self.evaluator):
139
+ has_session_state = session_state is not None and self._evaluator_has_session_state_param()
140
+
136
141
  if inspect.iscoroutinefunction(self.evaluator):
137
- result = await self.evaluator(step_input)
142
+ if has_session_state:
143
+ result = await self.evaluator(step_input, session_state=session_state) # type: ignore[call-arg]
144
+ else:
145
+ result = await self.evaluator(step_input)
138
146
  else:
139
- result = self.evaluator(step_input)
147
+ if has_session_state:
148
+ result = self.evaluator(step_input, session_state=session_state) # type: ignore[call-arg]
149
+ else:
150
+ result = self.evaluator(step_input)
140
151
 
141
152
  if isinstance(result, bool):
142
153
  return result
@@ -146,6 +157,17 @@ class Condition:
146
157
 
147
158
  return False
148
159
 
160
+ def _evaluator_has_session_state_param(self) -> bool:
161
+ """Check if the evaluator function has a session_state parameter"""
162
+ if not callable(self.evaluator):
163
+ return False
164
+
165
+ try:
166
+ sig = inspect.signature(self.evaluator)
167
+ return "session_state" in sig.parameters
168
+ except Exception:
169
+ return False
170
+
149
171
  def execute(
150
172
  self,
151
173
  step_input: StepInput,
@@ -166,7 +188,7 @@ class Condition:
166
188
  self._prepare_steps()
167
189
 
168
190
  # Evaluate the condition
169
- condition_result = self._evaluate_condition(step_input)
191
+ condition_result = self._evaluate_condition(step_input, session_state)
170
192
  log_debug(f"Condition {self.name} evaluated to: {condition_result}")
171
193
 
172
194
  if not condition_result:
@@ -275,7 +297,7 @@ class Condition:
275
297
  self._prepare_steps()
276
298
 
277
299
  # Evaluate the condition
278
- condition_result = self._evaluate_condition(step_input)
300
+ condition_result = self._evaluate_condition(step_input, session_state)
279
301
  log_debug(f"Condition {self.name} evaluated to: {condition_result}")
280
302
 
281
303
  if stream_intermediate_steps and workflow_run_response:
@@ -434,7 +456,7 @@ class Condition:
434
456
  self._prepare_steps()
435
457
 
436
458
  # Evaluate the condition
437
- condition_result = await self._aevaluate_condition(step_input)
459
+ condition_result = await self._aevaluate_condition(step_input, session_state)
438
460
  log_debug(f"Condition {self.name} evaluated to: {condition_result}")
439
461
 
440
462
  if not condition_result:
@@ -543,7 +565,7 @@ class Condition:
543
565
  self._prepare_steps()
544
566
 
545
567
  # Evaluate the condition
546
- condition_result = await self._aevaluate_condition(step_input)
568
+ condition_result = await self._aevaluate_condition(step_input, session_state)
547
569
  log_debug(f"Condition {self.name} evaluated to: {condition_result}")
548
570
 
549
571
  if stream_intermediate_steps and workflow_run_response:
agno/workflow/router.py CHANGED
@@ -108,10 +108,13 @@ class Router:
108
108
  audio=current_audio + all_audio,
109
109
  )
110
110
 
111
- def _route_steps(self, step_input: StepInput) -> List[Step]: # type: ignore[return-value]
111
+ def _route_steps(self, step_input: StepInput, session_state: Optional[Dict[str, Any]] = None) -> List[Step]: # type: ignore[return-value]
112
112
  """Route to the appropriate steps based on input"""
113
113
  if callable(self.selector):
114
- result = self.selector(step_input)
114
+ if session_state is not None and self._selector_has_session_state_param():
115
+ result = self.selector(step_input, session_state) # type: ignore[call-arg]
116
+ else:
117
+ result = self.selector(step_input)
115
118
 
116
119
  # Handle the result based on its type
117
120
  if isinstance(result, Step):
@@ -124,13 +127,21 @@ class Router:
124
127
 
125
128
  return []
126
129
 
127
- async def _aroute_steps(self, step_input: StepInput) -> List[Step]: # type: ignore[return-value]
130
+ async def _aroute_steps(self, step_input: StepInput, session_state: Optional[Dict[str, Any]] = None) -> List[Step]: # type: ignore[return-value]
128
131
  """Async version of step routing"""
129
132
  if callable(self.selector):
133
+ has_session_state = session_state is not None and self._selector_has_session_state_param()
134
+
130
135
  if inspect.iscoroutinefunction(self.selector):
131
- result = await self.selector(step_input)
136
+ if has_session_state:
137
+ result = await self.selector(step_input, session_state) # type: ignore[call-arg]
138
+ else:
139
+ result = await self.selector(step_input)
132
140
  else:
133
- result = self.selector(step_input)
141
+ if has_session_state:
142
+ result = self.selector(step_input, session_state) # type: ignore[call-arg]
143
+ else:
144
+ result = self.selector(step_input)
134
145
 
135
146
  # Handle the result based on its type
136
147
  if isinstance(result, Step):
@@ -143,6 +154,17 @@ class Router:
143
154
 
144
155
  return []
145
156
 
157
+ def _selector_has_session_state_param(self) -> bool:
158
+ """Check if the selector function has a session_state parameter"""
159
+ if not callable(self.selector):
160
+ return False
161
+
162
+ try:
163
+ sig = inspect.signature(self.selector)
164
+ return "session_state" in sig.parameters
165
+ except Exception:
166
+ return False
167
+
146
168
  def execute(
147
169
  self,
148
170
  step_input: StepInput,
@@ -163,7 +185,7 @@ class Router:
163
185
  self._prepare_steps()
164
186
 
165
187
  # Route to appropriate steps
166
- steps_to_execute = self._route_steps(step_input)
188
+ steps_to_execute = self._route_steps(step_input, session_state)
167
189
  log_debug(f"Router {self.name}: Selected {len(steps_to_execute)} steps to execute")
168
190
 
169
191
  if not steps_to_execute:
@@ -263,7 +285,7 @@ class Router:
263
285
  router_step_id = str(uuid4())
264
286
 
265
287
  # Route to appropriate steps
266
- steps_to_execute = self._route_steps(step_input)
288
+ steps_to_execute = self._route_steps(step_input, session_state)
267
289
  log_debug(f"Router {self.name}: Selected {len(steps_to_execute)} steps to execute")
268
290
 
269
291
  if stream_intermediate_steps and workflow_run_response:
@@ -413,7 +435,7 @@ class Router:
413
435
  self._prepare_steps()
414
436
 
415
437
  # Route to appropriate steps
416
- steps_to_execute = await self._aroute_steps(step_input)
438
+ steps_to_execute = await self._aroute_steps(step_input, session_state)
417
439
  log_debug(f"Router {self.name} selected: {len(steps_to_execute)} steps to execute")
418
440
 
419
441
  if not steps_to_execute:
@@ -516,7 +538,7 @@ class Router:
516
538
  router_step_id = str(uuid4())
517
539
 
518
540
  # Route to appropriate steps
519
- steps_to_execute = await self._aroute_steps(step_input)
541
+ steps_to_execute = await self._aroute_steps(step_input, session_state)
520
542
  log_debug(f"Router {self.name} selected: {len(steps_to_execute)} steps to execute")
521
543
 
522
544
  if stream_intermediate_steps and workflow_run_response:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agno
3
- Version: 2.1.8
3
+ Version: 2.1.9
4
4
  Summary: Agno: a lightweight library for building Multi-Agent Systems
5
5
  Author-email: Ashpreet Bedi <ashpreet@agno.com>
6
6
  Project-URL: homepage, https://agno.com
@@ -103,7 +103,7 @@ agno/integrations/discord/__init__.py,sha256=MS08QSnegGgpDZd9LyLjK4pWIk9dXlbzgD7
103
103
  agno/integrations/discord/client.py,sha256=2IWkA-kCDsDXByKOGq2QJG6MtFsbouzNN105rsXn95A,8375
104
104
  agno/knowledge/__init__.py,sha256=PJCt-AGKGFztzR--Ok2TNKW5QEqllZzqiI_7f8-1u80,79
105
105
  agno/knowledge/content.py,sha256=q2bjcjDhfge_UrQAcygrv5R9ZTk7vozzKnQpatDQWRo,2295
106
- agno/knowledge/knowledge.py,sha256=LnBQ-feIaaHwusgBMGWvXzj4_hiZBCg-ZglfkBYE6nA,77963
106
+ agno/knowledge/knowledge.py,sha256=P3-aEys4nYbLWs-vCoMQ1vf5A3s6wiKNp4yqscH-wGg,78103
107
107
  agno/knowledge/types.py,sha256=ciwDLK9MXwi_W_g4nUChEmK6meDQyqTqGK2Ad-wM1os,754
108
108
  agno/knowledge/utils.py,sha256=_uhEFtz4p7-cIKffdj5UZ__c-u96rs2UWP6dv5HpOMk,6490
109
109
  agno/knowledge/chunking/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -164,7 +164,7 @@ agno/memory/manager.py,sha256=qQYnrCWCA2P_z_sKR1_sJ5kGgtCL2WnpLRSyAL5unfU,51717
164
164
  agno/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
165
165
  agno/models/base.py,sha256=bjP0Xt5-Jlk1I_7wHmuv8lhUPE75WzZ_iF3U-d81TUI,85214
166
166
  agno/models/defaults.py,sha256=1_fe4-ZbNriE8BgqxVRVi4KGzEYxYKYsz4hn6CZNEEM,40
167
- agno/models/message.py,sha256=yHiNMsgadNEjAYAvtSJgktwsXqlRYC8N_DRShCzjYtc,18914
167
+ agno/models/message.py,sha256=iA9JSlm0KVEX6mCLOfsspoOIdbxREL3qlnN2RycaqZM,19024
168
168
  agno/models/metrics.py,sha256=81IILXZwGmOTiWK003bi5mg4bM1f4LCWbwyamjFzp18,4500
169
169
  agno/models/response.py,sha256=UIuqTBVfXOpxlpf8wOzc6wIrb0vR0FFO6JIkASaPfOQ,4213
170
170
  agno/models/utils.py,sha256=PprNlVI8d8loHayjRsrc4TL38sfkFMS3EVZcF5cLXoA,669
@@ -323,7 +323,7 @@ agno/session/summary.py,sha256=THBbzE48V81p4dKUX2W8OvbpsNO5dI6BdtqDyjfcVqw,8433
323
323
  agno/session/team.py,sha256=0lS-9ljtG17iyC0n8sq_7aEy9MZsdfMf8VgObqJ_3tg,10384
324
324
  agno/session/workflow.py,sha256=tluE_3ERMBYJtffpwlrhdETWlzJk6Xw2x06FZ1Y3fXg,7397
325
325
  agno/team/__init__.py,sha256=toHidBOo5M3n_TIVtIKHgcDbLL9HR-_U-YQYuIt_XtE,847
326
- agno/team/team.py,sha256=TinwhqZQLf-ouVIlfemIEd11h4efSjQUdDBijSoLT2U,377665
326
+ agno/team/team.py,sha256=rKDA0R5EfIk1BSe8BX9mkxJ4ck4RDT7gfju2DQQeVzU,377672
327
327
  agno/tools/__init__.py,sha256=jNll2sELhPPbqm5nPeT4_uyzRO2_KRTW-8Or60kioS0,210
328
328
  agno/tools/agentql.py,sha256=S82Z9aTNr-E5wnA4fbFs76COljJtiQIjf2grjz3CkHU,4104
329
329
  agno/tools/airflow.py,sha256=uf2rOzZpSU64l_qRJ5Raku-R3Gky-uewmYkh6W0-oxg,2610
@@ -370,7 +370,7 @@ agno/tools/gmail.py,sha256=MlLlEvxHly_2oKAZaKxXDmoHLTbWDSXcjOASGt7RpY8,28067
370
370
  agno/tools/google_bigquery.py,sha256=j0c14CgGK8KvD7eEirsdAx7RSwcfMheugn84ySq6miU,4483
371
371
  agno/tools/google_drive.py,sha256=dxGr_NhMsqFsr_tR3w4MgLXm7_nlCTI43sCmKw60N_4,11159
372
372
  agno/tools/google_maps.py,sha256=AqPEIt4u6B2kQtzOnL5PH3RXoefCfjT_Uvm3coAqzaY,9513
373
- agno/tools/googlecalendar.py,sha256=A6UeelPYOpo-51q6YwYjkGGR9HH4Gw025jUAP5Vm1XI,28919
373
+ agno/tools/googlecalendar.py,sha256=4WxmPIaxxsxAYP56XT7ehnmKEwicn9w_KOe8LMy5KB0,28670
374
374
  agno/tools/googlesearch.py,sha256=xRuaEqn7N6JIQC6z9jFuA0Kdtoe5MafGqRMtZ8jW2AQ,3566
375
375
  agno/tools/googlesheets.py,sha256=m8K0A8I5d68HG19OajDLCgGJzXnsnh33OQQOc6K5Qbg,15704
376
376
  agno/tools/hackernews.py,sha256=h5w-L5FkGGMAHr6Jjez6164-UYZ_2r2qFAzwMrKLdRM,2776
@@ -544,16 +544,16 @@ agno/vectordb/weaviate/__init__.py,sha256=FIoFJgqSmGuFgpvmsg8EjAn8FDAhuqAXed7fja
544
544
  agno/vectordb/weaviate/index.py,sha256=y4XYPRZFksMfrrF85B4hn5AtmXM4SH--4CyLo27EHgM,253
545
545
  agno/vectordb/weaviate/weaviate.py,sha256=8KNa5a-RuksE6w9poD4vi_ixUBeoB96PkzCL9DHSs5o,39406
546
546
  agno/workflow/__init__.py,sha256=lwavZXIkgqajbSf1jMqzE7kbXBIFmk5niI_NgpVI-gA,542
547
- agno/workflow/condition.py,sha256=MgJnHRPEJ2qCjUkcHKyZfOuAn-C38ZTgVcYjY8iTgrI,30122
547
+ agno/workflow/condition.py,sha256=9nnwzaf4SiaMKgSIbZ_mekP6ndx3daAas3vNyyUyclE,31327
548
548
  agno/workflow/loop.py,sha256=q2XssC179htRC7KPiebUcvr0lKexfZUB9aUO4D3tOrk,32305
549
549
  agno/workflow/parallel.py,sha256=Gb6XZbwDJgmBBbuiZTFHvphQqrsMVgM-HTOMoiIHweg,34843
550
- agno/workflow/router.py,sha256=-gPT43a1mP0tnE6wQa4tEAuGWNppel8DbmCg0ajo-L0,28295
550
+ agno/workflow/router.py,sha256=Z1hzzbLL7ZgJD2UuIP7p2Ubt0QWYMF2rX6pOapVIw7c,29461
551
551
  agno/workflow/step.py,sha256=2vBv97QoDLtFJnWAueDLLbzWvB3dxPd5Cl_dwqdl5Ew,60251
552
552
  agno/workflow/steps.py,sha256=1qOcH0SuPTPE0Ac3sRyRLjFoMcKyTo44hlJXdbOBNnM,25389
553
553
  agno/workflow/types.py,sha256=DutB4UkEppJoWRiNaGEnPk6xFNpg0oCBwOb7VJ8T_xE,18646
554
554
  agno/workflow/workflow.py,sha256=AD2mKXap840IwPb2WMnVJM30lQLAFUfWxd7nqQJ52hU,137906
555
- agno-2.1.8.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
556
- agno-2.1.8.dist-info/METADATA,sha256=v-MZ_AVGcZZ6oE5_GEsZR8kzP4MBxC38IZ9CFKhBhZo,24504
557
- agno-2.1.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
558
- agno-2.1.8.dist-info/top_level.txt,sha256=MKyeuVesTyOKIXUhc-d_tPa2Hrh0oTA4LM0izowpx70,5
559
- agno-2.1.8.dist-info/RECORD,,
555
+ agno-2.1.9.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
556
+ agno-2.1.9.dist-info/METADATA,sha256=wLm7Y7A7d_h_hzSZJPY0qPFjvjelASmRCwl7moipnb0,24504
557
+ agno-2.1.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
558
+ agno-2.1.9.dist-info/top_level.txt,sha256=MKyeuVesTyOKIXUhc-d_tPa2Hrh0oTA4LM0izowpx70,5
559
+ agno-2.1.9.dist-info/RECORD,,
File without changes