agno 1.8.1__py3-none-any.whl → 1.8.2__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.
agno/__init__.py CHANGED
@@ -0,0 +1,8 @@
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ try:
4
+ __version__ = version("agno")
5
+ except PackageNotFoundError:
6
+ __version__ = "0.0.0"
7
+
8
+ __all__ = ["__version__"]
agno/agent/agent.py CHANGED
@@ -1476,7 +1476,7 @@ class Agent:
1476
1476
 
1477
1477
  # Read existing session from storage
1478
1478
  if self.context is not None:
1479
- self.resolve_run_context()
1479
+ await self.aresolve_run_context()
1480
1480
 
1481
1481
  # Prepare arguments for the model
1482
1482
  self.set_default_model()
@@ -2152,7 +2152,7 @@ class Agent:
2152
2152
 
2153
2153
  # Read existing session from storage
2154
2154
  if self.context is not None:
2155
- self.resolve_run_context()
2155
+ await self.aresolve_run_context()
2156
2156
 
2157
2157
  # Prepare arguments for the model
2158
2158
  self.set_default_model()
agno/agent/metrics.py CHANGED
@@ -69,7 +69,10 @@ class SessionMetrics:
69
69
  # Add values from other
70
70
  if other.prompt_tokens_details:
71
71
  for key, value in other.prompt_tokens_details.items():
72
- result.prompt_tokens_details[key] = result.prompt_tokens_details.get(key, 0) + value
72
+ existing_value = result.prompt_tokens_details.get(key, 0)
73
+ if not isinstance(existing_value, int):
74
+ continue
75
+ result.prompt_tokens_details[key] = existing_value + value
73
76
 
74
77
  # Handle completion_tokens_details similarly
75
78
  if self.completion_tokens_details or other.completion_tokens_details:
agno/app/agui/utils.py CHANGED
@@ -27,6 +27,7 @@ from agno.models.message import Message
27
27
  from agno.run.response import RunEvent, RunResponseContentEvent, RunResponseEvent, RunResponsePausedEvent
28
28
  from agno.run.team import RunResponseContentEvent as TeamRunResponseContentEvent
29
29
  from agno.run.team import TeamRunEvent, TeamRunResponseEvent
30
+ from agno.utils.message import get_text_from_message
30
31
 
31
32
 
32
33
  @dataclass
@@ -106,17 +107,23 @@ def extract_team_response_chunk_content(response: TeamRunResponseContentEvent) -
106
107
  members_content.append(f"Team member: {member_content}")
107
108
  members_response = "\n".join(members_content) if members_content else ""
108
109
 
109
- return str(response.content) + members_response
110
+ # Handle structured outputs
111
+ main_content = get_text_from_message(response.content) if response.content is not None else ""
112
+
113
+ return main_content + members_response
110
114
 
111
115
 
112
116
  def extract_response_chunk_content(response: RunResponseContentEvent) -> str:
113
117
  """Given a response stream chunk, find and extract the content."""
118
+
114
119
  if hasattr(response, "messages") and response.messages: # type: ignore
115
120
  for msg in reversed(response.messages): # type: ignore
116
121
  if hasattr(msg, "role") and msg.role == "assistant" and hasattr(msg, "content") and msg.content:
117
- return str(msg.content)
122
+ # Handle structured outputs from messages
123
+ return get_text_from_message(msg.content)
118
124
 
119
- return str(response.content) if response.content else ""
125
+ # Handle structured outputs
126
+ return get_text_from_message(response.content) if response.content is not None else ""
120
127
 
121
128
 
122
129
  def _create_events_from_chunk(
@@ -202,11 +209,11 @@ def _create_events_from_chunk(
202
209
 
203
210
  # Handle reasoning
204
211
  elif chunk.event == RunEvent.reasoning_started:
205
- step_event = StepStartedEvent(type=EventType.STEP_STARTED, step_name="reasoning")
206
- events_to_emit.append(step_event)
212
+ step_started_event = StepStartedEvent(type=EventType.STEP_STARTED, step_name="reasoning")
213
+ events_to_emit.append(step_started_event)
207
214
  elif chunk.event == RunEvent.reasoning_completed:
208
- step_event = StepFinishedEvent(type=EventType.STEP_FINISHED, step_name="reasoning")
209
- events_to_emit.append(step_event)
215
+ step_finished_event = StepFinishedEvent(type=EventType.STEP_FINISHED, step_name="reasoning")
216
+ events_to_emit.append(step_finished_event)
210
217
 
211
218
  return events_to_emit, message_started
212
219
 
@@ -220,7 +227,7 @@ def _create_completion_events(
220
227
  run_id: str,
221
228
  ) -> List[BaseEvent]:
222
229
  """Create events for run completion."""
223
- events_to_emit = []
230
+ events_to_emit: List[BaseEvent] = []
224
231
 
225
232
  # End remaining active tool calls if needed
226
233
  for tool_call_id in list(event_buffer.active_tool_call_ids):
@@ -271,7 +278,7 @@ def _create_completion_events(
271
278
 
272
279
  def _emit_event_logic(event: BaseEvent, event_buffer: EventBuffer) -> List[BaseEvent]:
273
280
  """Process an event through the buffer and return events to actually emit."""
274
- events_to_emit = []
281
+ events_to_emit: List[BaseEvent] = []
275
282
 
276
283
  if event_buffer.is_blocked():
277
284
  # Handle events related to the current blocking tool call
@@ -8,6 +8,7 @@ from agno.agent.agent import Agent, RunResponse
8
8
  from agno.media import Audio, File, Image, Video
9
9
  from agno.team.team import Team, TeamRunResponse
10
10
  from agno.utils.log import log_info, log_warning
11
+ from agno.utils.message import get_text_from_message
11
12
 
12
13
  try:
13
14
  import discord
@@ -167,7 +168,10 @@ class DiscordClient:
167
168
  thread=thread, message=f"Reasoning: \n{response.reasoning_content}", italics=True
168
169
  )
169
170
 
170
- await self._send_discord_messages(thread=thread, message=str(response.content))
171
+ # Handle structured outputs properly
172
+ content_message = get_text_from_message(response.content) if response.content is not None else ""
173
+
174
+ await self._send_discord_messages(thread=thread, message=content_message)
171
175
 
172
176
  async def _send_discord_messages(self, thread: discord.channel, message: str, italics: bool = False): # type: ignore
173
177
  if len(message) < 1500:
@@ -528,6 +528,7 @@ def get_async_playground_router(
528
528
  session_id=session.session_id,
529
529
  session_name=session.session_data.get("session_name") if session.session_data else None,
530
530
  created_at=session.created_at,
531
+ updated_at=session.updated_at,
531
532
  )
532
533
  )
533
534
  return agent_sessions
@@ -751,6 +752,7 @@ def get_async_playground_router(
751
752
  "session_id": session.session_id,
752
753
  "session_name": session.session_data.get("session_name") if session.session_data else None,
753
754
  "created_at": session.created_at,
755
+ "updated_at": session.updated_at,
754
756
  } # type: ignore
755
757
  )
756
758
  return workflow_sessions
@@ -945,6 +947,7 @@ def get_async_playground_router(
945
947
  session_id=session.session_id,
946
948
  session_name=session.session_data.get("session_name") if session.session_data else None,
947
949
  created_at=session.created_at,
950
+ updated_at=session.updated_at,
948
951
  )
949
952
  )
950
953
  return team_sessions
@@ -91,6 +91,7 @@ class AgentSessionsResponse(BaseModel):
91
91
  session_id: Optional[str] = None
92
92
  session_name: Optional[str] = None
93
93
  created_at: Optional[int] = None
94
+ updated_at: Optional[int] = None
94
95
 
95
96
 
96
97
  class MemoryResponse(BaseModel):
@@ -115,6 +116,7 @@ class WorkflowSessionResponse(BaseModel):
115
116
  session_id: Optional[str] = None
116
117
  session_name: Optional[str] = None
117
118
  created_at: Optional[int] = None
119
+ updated_at: Optional[int] = None
118
120
 
119
121
 
120
122
  class WorkflowGetResponse(BaseModel):
@@ -213,6 +215,7 @@ class TeamSessionResponse(BaseModel):
213
215
  session_id: Optional[str] = None
214
216
  session_name: Optional[str] = None
215
217
  created_at: Optional[int] = None
218
+ updated_at: Optional[int] = None
216
219
 
217
220
 
218
221
  class TeamRenameRequest(BaseModel):
@@ -528,6 +528,7 @@ def get_sync_playground_router(
528
528
  session_id=session.session_id,
529
529
  session_name=session.session_data.get("session_name") if session.session_data else None,
530
530
  created_at=session.created_at,
531
+ updated_at=session.updated_at,
531
532
  )
532
533
  )
533
534
  return agent_sessions
@@ -743,6 +744,7 @@ def get_sync_playground_router(
743
744
  "session_id": session.session_id,
744
745
  "session_name": session.session_data.get("session_name") if session.session_data else None,
745
746
  "created_at": session.created_at,
747
+ "updated_at": session.updated_at,
746
748
  } # type: ignore
747
749
  )
748
750
  return workflow_sessions
@@ -940,6 +942,7 @@ def get_sync_playground_router(
940
942
  session_id=session.session_id,
941
943
  session_name=session.session_data.get("session_name") if session.session_data else None,
942
944
  created_at=session.created_at,
945
+ updated_at=session.updated_at,
943
946
  )
944
947
  )
945
948
  return team_sessions
@@ -11,7 +11,7 @@ from agno.models.base import Model
11
11
  from agno.models.message import Citations, DocumentCitation, Message, UrlCitation
12
12
  from agno.models.response import ModelResponse
13
13
  from agno.utils.log import log_debug, log_error, log_warning
14
- from agno.utils.models.claude import MCPServerConfiguration, format_messages
14
+ from agno.utils.models.claude import MCPServerConfiguration, format_messages, format_tools_for_model
15
15
 
16
16
  try:
17
17
  from anthropic import (
@@ -176,59 +176,12 @@ class Claude(Model):
176
176
  request_kwargs["system"] = [{"text": system_message, "type": "text"}]
177
177
 
178
178
  if tools:
179
- request_kwargs["tools"] = self._format_tools_for_model(tools)
179
+ request_kwargs["tools"] = format_tools_for_model(tools)
180
180
 
181
181
  if request_kwargs:
182
182
  log_debug(f"Calling {self.provider} with request parameters: {request_kwargs}", log_level=2)
183
183
  return request_kwargs
184
184
 
185
- def _format_tools_for_model(self, tools: Optional[List[Dict[str, Any]]] = None) -> Optional[List[Dict[str, Any]]]:
186
- """
187
- Transforms function definitions into a format accepted by the Anthropic API.
188
- """
189
- if not tools:
190
- return None
191
-
192
- parsed_tools: List[Dict[str, Any]] = []
193
- for tool_def in tools:
194
- if tool_def.get("type", "") != "function":
195
- parsed_tools.append(tool_def)
196
- continue
197
-
198
- func_def = tool_def.get("function", {})
199
- parameters: Dict[str, Any] = func_def.get("parameters", {})
200
- properties: Dict[str, Any] = parameters.get("properties", {})
201
- required_params: List[str] = []
202
-
203
- for param_name, param_info in properties.items():
204
- param_type = param_info.get("type", "")
205
- param_type_list: List[str] = [param_type] if isinstance(param_type, str) else param_type or []
206
-
207
- if "null" not in param_type_list:
208
- required_params.append(param_name)
209
-
210
- input_properties: Dict[str, Dict[str, Union[str, List[str]]]] = {}
211
- for param_name, param_info in properties.items():
212
- input_properties[param_name] = {
213
- "description": param_info.get("description", ""),
214
- }
215
- if "type" not in param_info and "anyOf" in param_info:
216
- input_properties[param_name]["anyOf"] = param_info["anyOf"]
217
- else:
218
- input_properties[param_name]["type"] = param_info.get("type", "")
219
-
220
- tool = {
221
- "name": func_def.get("name") or "",
222
- "description": func_def.get("description") or "",
223
- "input_schema": {
224
- "type": parameters.get("type", "object"),
225
- "properties": input_properties,
226
- "required": required_params,
227
- },
228
- }
229
- parsed_tools.append(tool)
230
- return parsed_tools
231
-
232
185
  def invoke(
233
186
  self,
234
187
  messages: List[Message],
@@ -570,16 +523,7 @@ class Claude(Model):
570
523
  }
571
524
 
572
525
  elif isinstance(response, ContentBlockStopEvent):
573
- # Handle completed thinking content
574
- if response.content_block.type == "thinking": # type: ignore
575
- model_response.thinking = response.content_block.thinking # type: ignore
576
- # Store signature if available
577
- if hasattr(response.content_block, "signature"): # type: ignore
578
- model_response.provider_data = {
579
- "signature": response.content_block.signature, # type: ignore
580
- }
581
- # Handle tool calls
582
- elif response.content_block.type == "tool_use": # type: ignore
526
+ if response.content_block.type == "tool_use": # type: ignore
583
527
  tool_use = response.content_block # type: ignore
584
528
  tool_name = tool_use.name
585
529
  tool_input = tool_use.input
@@ -179,14 +179,10 @@ class AwsBedrock(Model):
179
179
  required = []
180
180
 
181
181
  for param_name, param_info in func_def.get("parameters", {}).get("properties", {}).items():
182
- param_type = param_info.get("type")
183
- if isinstance(param_type, list):
184
- param_type = [t for t in param_type if t != "null"][0]
182
+ properties[param_name] = param_info.copy()
185
183
 
186
- properties[param_name] = {
187
- "type": param_type or "string",
188
- "description": param_info.get("description") or "",
189
- }
184
+ if "description" not in properties[param_name]:
185
+ properties[param_name]["description"] = ""
190
186
 
191
187
  if "null" not in (
192
188
  param_info.get("type") if isinstance(param_info.get("type"), list) else [param_info.get("type")]
agno/tools/firecrawl.py CHANGED
@@ -6,7 +6,8 @@ from agno.tools import Toolkit
6
6
  from agno.utils.log import logger
7
7
 
8
8
  try:
9
- from firecrawl import FirecrawlApp, ScrapeOptions # type: ignore[attr-defined]
9
+ from firecrawl import FirecrawlApp # type: ignore[attr-defined]
10
+ from firecrawl.types import ScrapeOptions
10
11
  except ImportError:
11
12
  raise ImportError("`firecrawl-py` not installed. Please install using `pip install firecrawl-py`")
12
13
 
@@ -87,7 +88,7 @@ class FirecrawlTools(Toolkit):
87
88
  if self.formats:
88
89
  params["formats"] = self.formats
89
90
 
90
- scrape_result = self.app.scrape_url(url, **params)
91
+ scrape_result = self.app.scrape(url, **params)
91
92
  return json.dumps(scrape_result.model_dump(), cls=CustomJSONEncoder)
92
93
 
93
94
  def crawl_website(self, url: str, limit: Optional[int] = None) -> str:
@@ -108,7 +109,7 @@ class FirecrawlTools(Toolkit):
108
109
 
109
110
  params["poll_interval"] = self.poll_interval
110
111
 
111
- crawl_result = self.app.crawl_url(url, **params)
112
+ crawl_result = self.app.crawl(url, **params)
112
113
  return json.dumps(crawl_result.model_dump(), cls=CustomJSONEncoder)
113
114
 
114
115
  def map_website(self, url: str) -> str:
@@ -118,7 +119,7 @@ class FirecrawlTools(Toolkit):
118
119
  url (str): The URL to map.
119
120
 
120
121
  """
121
- map_result = self.app.map_url(url)
122
+ map_result = self.app.map(url)
122
123
  return json.dumps(map_result.model_dump(), cls=CustomJSONEncoder)
123
124
 
124
125
  def search(self, query: str, limit: Optional[int] = None):
agno/tools/linear.py CHANGED
@@ -217,7 +217,7 @@ class LinearTools(Toolkit):
217
217
  """
218
218
 
219
219
  query = """
220
- mutation IssueCreate ($title: String!, $description: String!, $teamId: String!, $projectId: String!, $assigneeId: String!){
220
+ mutation IssueCreate ($title: String!, $description: String!, $teamId: String!, $projectId: String, $assigneeId: String){
221
221
  issueCreate(
222
222
  input: { title: $title, description: $description, teamId: $teamId, projectId: $projectId, assigneeId: $assigneeId}
223
223
  ) {
agno/utils/gemini.py CHANGED
@@ -175,7 +175,37 @@ def convert_schema(schema_dict: Dict[str, Any], root_schema: Optional[Dict[str,
175
175
 
176
176
  elif schema_type == "array" and "items" in schema_dict:
177
177
  items = convert_schema(schema_dict["items"], root_schema)
178
- return Schema(type=Type.ARRAY, description=description, items=items)
178
+ min_items = schema_dict.get("minItems")
179
+ max_items = schema_dict.get("maxItems")
180
+ return Schema(
181
+ type=Type.ARRAY,
182
+ description=description,
183
+ items=items,
184
+ min_items=min_items,
185
+ max_items=max_items,
186
+ )
187
+
188
+ elif schema_type == "string":
189
+ schema_kwargs = {
190
+ "type": Type.STRING,
191
+ "description": description,
192
+ "default": default,
193
+ }
194
+ if "format" in schema_dict:
195
+ schema_kwargs["format"] = schema_dict["format"]
196
+ return Schema(**schema_kwargs)
197
+
198
+ elif schema_type in ("integer", "number"):
199
+ schema_kwargs = {
200
+ "type": schema_type.upper(),
201
+ "description": description,
202
+ "default": default,
203
+ }
204
+ if "maximum" in schema_dict:
205
+ schema_kwargs["maximum"] = schema_dict["maximum"]
206
+ if "minimum" in schema_dict:
207
+ schema_kwargs["minimum"] = schema_dict["minimum"]
208
+ return Schema(**schema_kwargs)
179
209
 
180
210
  elif schema_type == "" and "anyOf" in schema_dict:
181
211
  any_of = []
@@ -284,3 +284,52 @@ def format_messages(messages: List[Message]) -> Tuple[List[Dict[str, str]], str]
284
284
 
285
285
  chat_messages.append({"role": ROLE_MAP[message.role], "content": content}) # type: ignore
286
286
  return chat_messages, " ".join(system_messages)
287
+
288
+
289
+ def format_tools_for_model(tools: Optional[List[Dict[str, Any]]] = None) -> Optional[List[Dict[str, Any]]]:
290
+ """
291
+ Transforms function definitions into a format accepted by the Anthropic API.
292
+ """
293
+ if not tools:
294
+ return None
295
+
296
+ parsed_tools: List[Dict[str, Any]] = []
297
+ for tool_def in tools:
298
+ if tool_def.get("type", "") != "function":
299
+ parsed_tools.append(tool_def)
300
+ continue
301
+
302
+ func_def = tool_def.get("function", {})
303
+ parameters: Dict[str, Any] = func_def.get("parameters", {})
304
+ properties: Dict[str, Any] = parameters.get("properties", {})
305
+ required: List[str] = parameters.get("required", [])
306
+ required_params: List[str] = required
307
+
308
+ if not required_params:
309
+ for param_name, param_info in properties.items():
310
+ param_type = param_info.get("type", "")
311
+ param_type_list: List[str] = [param_type] if isinstance(param_type, str) else param_type or []
312
+
313
+ if "null" not in param_type_list:
314
+ required_params.append(param_name)
315
+
316
+ input_properties: Dict[str, Any] = {}
317
+ for param_name, param_info in properties.items():
318
+ # Preserve the complete schema structure for complex types
319
+ input_properties[param_name] = param_info.copy()
320
+
321
+ # Ensure description is present (default to empty if missing)
322
+ if "description" not in input_properties[param_name]:
323
+ input_properties[param_name]["description"] = ""
324
+
325
+ tool = {
326
+ "name": func_def.get("name") or "",
327
+ "description": func_def.get("description") or "",
328
+ "input_schema": {
329
+ "type": parameters.get("type", "object"),
330
+ "properties": input_properties,
331
+ "required": required_params,
332
+ },
333
+ }
334
+ parsed_tools.append(tool)
335
+ return parsed_tools
@@ -3273,7 +3273,8 @@ class Workflow:
3273
3273
  """Update executor with workflow_session_state"""
3274
3274
  if self.workflow_session_state is not None:
3275
3275
  # Update session_state with workflow_session_state
3276
- executor.workflow_session_state = self.workflow_session_state
3276
+ if hasattr(executor, "workflow_session_state"):
3277
+ executor.workflow_session_state = self.workflow_session_state
3277
3278
 
3278
3279
  def _save_run_to_storage(self, workflow_run_response: WorkflowRunResponse) -> None:
3279
3280
  """Helper method to save workflow run response to storage"""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agno
3
- Version: 1.8.1
3
+ Version: 1.8.2
4
4
  Summary: Agno: a lightweight library for building Multi-Agent Systems
5
5
  Author-email: Ashpreet Bedi <ashpreet@agno.com>
6
6
  License: Copyright (c) Agno, Inc.
@@ -1,12 +1,12 @@
1
- agno/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1
+ agno/__init__.py,sha256=fTmeyAdl4Mc1Y7_y_sACZTzXrc2Ymn8nMaFlgaawFvo,183
2
2
  agno/constants.py,sha256=UkeazwDTE0WS7NB1pw9GxFJPhCgWLepAaMsdmLknupQ,527
3
3
  agno/debug.py,sha256=zzYxYwfF5AfHgQ6JU7oCmPK4yc97Y5xxOb5fiezq8nA,449
4
4
  agno/exceptions.py,sha256=HWuuNFS5J0l1RYJsdUrSx51M22aFEoh9ltoeonXBoBw,2891
5
5
  agno/media.py,sha256=Vkd1rixJ8i5eeDLFxkOeDVFMljj0lidJr3gofYP1q3Y,13852
6
6
  agno/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  agno/agent/__init__.py,sha256=Ai6GVyw-0rkA2eYAfoEQIvbi_mrWQUxuPFaFbSDJYCQ,1306
8
- agno/agent/agent.py,sha256=DQEn-wNb9_kDoSKqI4nnwIktVFhfY6U-7U5Q0Pz0QS0,382035
9
- agno/agent/metrics.py,sha256=Lf7JYgPPdqRCyPfCDVUjnmUZ1SkWXrJClL80aW2ffEw,4379
8
+ agno/agent/agent.py,sha256=6FxPe2Ej24fQtdgNxZ2Bfk5udOQv8vHFdOsent_FLVI,382049
9
+ agno/agent/metrics.py,sha256=lGj4UQwaVrf7wCts5PMAmXTS-azcISlPCp0CCIeagvQ,4524
10
10
  agno/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  agno/api/agent.py,sha256=J-Y4HI-J0Bu6r9gxRYCM3U7SnVBGwLIouDy806KSIIw,2821
12
12
  agno/api/api.py,sha256=FV2Q20gVW1qVNupmJiGwrYRRpdI3KhBwGDN-8avy0Pk,2522
@@ -36,22 +36,22 @@ agno/app/agui/__init__.py,sha256=MGxPSk9a037TCVaVoPFBZ9KkVUiJRonAFgxROUWxosQ,61
36
36
  agno/app/agui/app.py,sha256=1uVog9E_V3dQkW-bgdVvbzRTaK3xOhjZQNVQ-vD5asM,575
37
37
  agno/app/agui/async_router.py,sha256=p1zbNBc7ZBGENyqdBauiB40U8fT6hXP6llqAiG3GQIM,4489
38
38
  agno/app/agui/sync_router.py,sha256=2UL4abcn_lp_DxhvZIgTmbDimWG1_hvgiNVAnjs8rgc,4375
39
- agno/app/agui/utils.py,sha256=SdcnW1sF7As2FFlAWiSo-EUODldDeWNpHgVgFjpmozU,15919
39
+ agno/app/agui/utils.py,sha256=8wn9SAzsEHRVWY47ubEhgjFm5pemtUnAWkyF54InHYU,16302
40
40
  agno/app/discord/__init__.py,sha256=4vYWlZXAx6Xs1U5Q5GBskSd6Q5gAJaIAhOk3vBFMbpU,79
41
- agno/app/discord/client.py,sha256=ev_P-SSQnpT0uCDeDzNaCkvgZrNCWySs3lwtACM1D0I,8127
41
+ agno/app/discord/client.py,sha256=Cbf9zoGlI47g6QzV4mKu3Yv5-o82qqYTbXryAdiIi_Q,8326
42
42
  agno/app/fastapi/__init__.py,sha256=nZbeAlzI88TLMWo_2K2e4XaohV2mjpY82iElFDhjVmY,70
43
43
  agno/app/fastapi/app.py,sha256=hMCxcMbZr7RqLOXMuI8e73xdaG9HyOKQ2eHGzatmfqU,3649
44
44
  agno/app/fastapi/async_router.py,sha256=o_C58t2k9vyQQ69Gt_0lG5rlf1Ird6QJNtIf7Y5mv-Y,19136
45
45
  agno/app/fastapi/sync_router.py,sha256=8lBSDKfUAdr54-r6qPRhN84SKiCDwffQEEKODhzh0Fk,18548
46
46
  agno/app/playground/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
47
  agno/app/playground/app.py,sha256=mZp15WZgHkarhtkAeXC4kSJuw13zEijIXRHywQSGQy8,8433
48
- agno/app/playground/async_router.py,sha256=wKRWZEZrE6NmVv84HwkWB2Y4iEPSwvlr028xDFN2SWY,44830
48
+ agno/app/playground/async_router.py,sha256=1OcsJk7_HGHD8RRZpsuteYpEu6vP_i43gZEdiZvUe4I,44986
49
49
  agno/app/playground/deploy.py,sha256=wiRIsFJ-9e2NvpOVJMUogBJky2gy1YE0yE3NAYu-G2I,8247
50
50
  agno/app/playground/operator.py,sha256=BRIzTXSugSdUUgIzZGK4d8PLQVRLjKVeRQlSt_HxvAw,7476
51
- agno/app/playground/schemas.py,sha256=ffkVv4a-cd80Nqr3B0UEAqSiBVr7OAHTs73KpG2EAYM,7529
51
+ agno/app/playground/schemas.py,sha256=oznbVVRQqG6pBkxjirICpI7ktmxdACufNJbPITZTg8s,7640
52
52
  agno/app/playground/serve.py,sha256=2weIO_M_MyD9xviLXPDg3weBnr7d-g3vd6fhi-td0GQ,1559
53
53
  agno/app/playground/settings.py,sha256=l54jm1qydY7gPoCpoM9CgFS7At7MramoqsV4uB8gl6U,1528
54
- agno/app/playground/sync_router.py,sha256=lLevHkkd0ErAIaYimqOkwkqoPTLSgdtUMtsuq5v64y0,44321
54
+ agno/app/playground/sync_router.py,sha256=O0aHkhW-1EskZ4tgogq1B35_psmOrJKpan5dsSyi_7M,44477
55
55
  agno/app/playground/utils.py,sha256=iiC6xCen5WCVjb_CclFBOM46K8d3jvfyQGqLvVdYIpk,1395
56
56
  agno/app/slack/__init__.py,sha256=RUX_cuNNkDeMbOd4bRnnE-o-oJb5EYezvfHgLqVaYNQ,64
57
57
  agno/app/slack/app.py,sha256=L3u54J1icZDcoQD7tug9x6ftIfWcMaKlOiUJh7T5Mm4,508
@@ -202,9 +202,9 @@ agno/models/response.py,sha256=iXUlBCM9FWZVRLygSQH8G-vhgKttQazLBa7L_NxgEjg,3771
202
202
  agno/models/aimlapi/__init__.py,sha256=ulPl-IAEcXvr83AXoCuZmOnoSZ0v47ZGTgEHSzUD2KM,78
203
203
  agno/models/aimlapi/aimlapi.py,sha256=o5pu9ypreAK-IkPAosHbLpAvbxu9u3jxBsgYPtS9bzo,1455
204
204
  agno/models/anthropic/__init__.py,sha256=nbReX3p17JCwfrMDR9hR7-OaEFZm80I7dng93dl-Fhw,77
205
- agno/models/anthropic/claude.py,sha256=TcfwuWl2JmnbdaMEItlr91cmRbNtF-Rz_kKn1tDjpkk,27221
205
+ agno/models/anthropic/claude.py,sha256=QLrmI1dyjMah3y0MJMAvZ2MRmnOsboSHihoXxA6v1AM,24669
206
206
  agno/models/aws/__init__.py,sha256=TbcwQwv9A7KjqBM5RQBR8x46GvyyCxbBCjwkpjfVGKE,352
207
- agno/models/aws/bedrock.py,sha256=Jj_M24JypERAgcQseMBi1v0jX4RrHWLd7sWWpc8f4bg,35314
207
+ agno/models/aws/bedrock.py,sha256=Yx09syx1Kv8awfHuy7jj_EK_gs-n6D2an3RUVRO2K2s,35123
208
208
  agno/models/aws/claude.py,sha256=3B-ghgJT-yhM8xJSspSFoSna7dpr10STA4Br4A7lzvc,13111
209
209
  agno/models/azure/__init__.py,sha256=EoFdJHjayvmv_VOmaW9cJguwA1K5OFS_nFeazyn0B2w,605
210
210
  agno/models/azure/ai_foundry.py,sha256=Fkn-BBPPUbw3vauiqqhSq4XQGMSq0TXBzshWCQIEuqg,16854
@@ -370,7 +370,7 @@ agno/tools/exa.py,sha256=dELwUmWs_i-kU4ZCe8ueYqttksG0GuUKNm7zNw9CPkQ,16319
370
370
  agno/tools/fal.py,sha256=DuYbviW-6WDaTq7nEJGRpQEr0UQFngPvuDPxSUtmT-o,4279
371
371
  agno/tools/file.py,sha256=zUl2GeshyEpnw_SpVwriTfGKDzpSHs4Rp0eCWPJWX_U,4215
372
372
  agno/tools/financial_datasets.py,sha256=rvGSjz7gRdouB0PRJGngRSlO0wOwQE7cnrI8YaNIEww,10437
373
- agno/tools/firecrawl.py,sha256=0jeJlupLXCJTf2tDckEXlCV6EpLeDEO_G27-w4EWDL0,4985
373
+ agno/tools/firecrawl.py,sha256=CMgXUHWFqyR2AMGHQTya7iHoXvK7JoDeYVRh6OG7DI0,5004
374
374
  agno/tools/function.py,sha256=VWgQAjIqxJl7MJrrMmMr7tNNvz3L3m7jXaUoIqxdlKY,36119
375
375
  agno/tools/giphy.py,sha256=HKzTHEmiUdrkJsguG0qkpnsmXPikbrQyCoAHvAzI6XU,2422
376
376
  agno/tools/github.py,sha256=mrXaJssPM5xrl25ZOgsb7B31QBgQomd3R97adcCLqMs,73558
@@ -384,7 +384,7 @@ agno/tools/hackernews.py,sha256=7Ot7N9BhCFGWiHbdwW8as4gAO7S2N5jw5WDVwuwOHNc,2558
384
384
  agno/tools/jina.py,sha256=Lhc4a7YjtS0yMd2_AODhs4lpReaMHKDC68pkwP2oHnY,3967
385
385
  agno/tools/jira.py,sha256=EapkMCd6oDPZeCrePtoJ9fO_sUlrxmDmdOh37btfVKE,5546
386
386
  agno/tools/knowledge.py,sha256=ORxD34H-ptqKLw66ShYMMeGhq_sijWUyKShwaaaeI_4,10895
387
- agno/tools/linear.py,sha256=bUiTeQbbRVggBTmEz_DJt38MZHviyRWmtWGXmdUuF2c,14498
387
+ agno/tools/linear.py,sha256=Pjgy1iidr7Qr6wXfKQgc7sHnKjQZ8ox2BqkcuyALcHo,14496
388
388
  agno/tools/linkup.py,sha256=N3YoPYirEvFLA3O0ZjqmW0DjsSBRHqtO2KrIK_HMcKc,1968
389
389
  agno/tools/local_file_system.py,sha256=LUfX9LlWf68PGgCPeOvfEVkRaFV_5NDO79KTLSucKjc,3029
390
390
  agno/tools/lumalab.py,sha256=_IdT7YE2AXyDgu7c8KlbAk0augEwpwwIzsVBT1_-4A4,6069
@@ -464,7 +464,7 @@ agno/utils/events.py,sha256=YbxGZGAxuj4Siqw7fXvmSKvFWW1VaBlf0uTQGFhTBYo,21788
464
464
  agno/utils/filesystem.py,sha256=D90lNq8EIhXUgLZrjQWn-qv62MhOLKhHz2GX0V6Pz2A,1020
465
465
  agno/utils/format_str.py,sha256=Zp9dDGMABUJzulp2bs41JiNv0MqmMX0qPToL7l_Ab1c,376
466
466
  agno/utils/functions.py,sha256=eHvGqO2uO63TR-QmmhZy2DEnC0xkAfhBG26z77T7jCo,6306
467
- agno/utils/gemini.py,sha256=xNy76HRmya7497Gnl_PXgMgoW05dgvSxy3yg6ll720o,9312
467
+ agno/utils/gemini.py,sha256=mj2G8xLBcwAFNSFBfYGl-HQYAyOzIbIup8QOK_oEs2U,10266
468
468
  agno/utils/git.py,sha256=NR8OUo1PTw-PSjAo7gHOuvt7Zxtv77_i41I0gxKeAFw,1626
469
469
  agno/utils/http.py,sha256=t7sr34VD9M___MYBlX6p4XKEqkvuXRJNJG7Y1ebU2bk,2673
470
470
  agno/utils/json_io.py,sha256=D_sNT1fJVN39LajJEmVa9NzTtWhHsVD4T1OYQ5r-Y9A,982
@@ -496,7 +496,7 @@ agno/utils/yaml_io.py,sha256=cwTqCE-eBGoi87KLDcwB6iyWe0NcvEmadQjWL1cQ7jE,860
496
496
  agno/utils/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
497
497
  agno/utils/models/ai_foundry.py,sha256=PmhETWhdqZCq8NbDe-MdZVuRXx6DbVOePCyPFiPLceo,1511
498
498
  agno/utils/models/aws_claude.py,sha256=UayU7E4PK-GCm1zEdD31iM8pSbPGtIGlPkrbaFRA34Q,5662
499
- agno/utils/models/claude.py,sha256=G43gfpT7zpo-_9vj6hGcdSxpGaJ2mqhuzYZf9DBz2ys,9357
499
+ agno/utils/models/claude.py,sha256=CQ36iQda9UOjAeou8q7U4FtVY6UFj13pvRyO0sIHlh8,11285
500
500
  agno/utils/models/cohere.py,sha256=SuZyupN1clBNMaSkHDQXWcTpY96rcF5EhMK5gpQAi94,3248
501
501
  agno/utils/models/llama.py,sha256=Z5fdOFUFnov1JgUDcP6ICK3M7o64UB1fkcwAs2XaZkM,2515
502
502
  agno/utils/models/mistral.py,sha256=v-ERNweHjmobUv5LOpB7XDxGZotXgGTC_hIFBJD1k3E,4013
@@ -551,16 +551,16 @@ agno/workflow/v2/router.py,sha256=e_2fIW4_-hFLBWt_CMfzWdCXzhc_kuGn00CtlKz5HU0,22
551
551
  agno/workflow/v2/step.py,sha256=kypeSrhWUP5NIsiBBwgtpLSbQjDaFWkX4-ts-l2ujkE,39366
552
552
  agno/workflow/v2/steps.py,sha256=CbczhOLuVKsoY7qO0NSYgq92dH4ZBHVvS5jP0bED61o,20390
553
553
  agno/workflow/v2/types.py,sha256=ECn3mE_R6M4pBpRr7a_8bY_vG37pYf22pRNYpR_4Fw8,13440
554
- agno/workflow/v2/workflow.py,sha256=8AoL_jFuxisYtB1NZJMffINDWY75nRDLykLe4E5nfKI,156106
554
+ agno/workflow/v2/workflow.py,sha256=CVKqlr-j9mtqa7MjwfOpwZoVd4k8LvC6jxbz58OFXfg,156170
555
555
  agno/workspace/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
556
556
  agno/workspace/config.py,sha256=c6bT4DrurY2T_1qfLUqSTSKzXDnU1gwmqQOk9Gb7QG0,15433
557
557
  agno/workspace/enums.py,sha256=MxF1CUMXBaZMTKLEfiR-7kEhTki2Gfz6W7u49RdYYaE,123
558
558
  agno/workspace/helpers.py,sha256=Mp-VlRsPVhW10CfDWYVhc9ANLk9RjNurDfCgXmycZCg,2066
559
559
  agno/workspace/operator.py,sha256=CNLwVR45eE5dSRjto2o0c9NgCi2xD-JZR5uLt9kfIt8,30758
560
560
  agno/workspace/settings.py,sha256=bcyHHN7lH1LPSMt4i_20XpTjZLoNXdzwyW-G9nHYV40,5703
561
- agno-1.8.1.dist-info/licenses/LICENSE,sha256=m2rfTWFUfIwCaQqgT2WeBjuKzMKEJRwnaiofg9n8MsQ,16751
562
- agno-1.8.1.dist-info/METADATA,sha256=_-DhUAh5k3DGfTzB4D5_er70GAjy2VxqR4Gx_Rsusgo,44612
563
- agno-1.8.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
564
- agno-1.8.1.dist-info/entry_points.txt,sha256=Be-iPnPVabMohESsuUdV5w6IAYEIlpc2emJZbyNnfGI,88
565
- agno-1.8.1.dist-info/top_level.txt,sha256=MKyeuVesTyOKIXUhc-d_tPa2Hrh0oTA4LM0izowpx70,5
566
- agno-1.8.1.dist-info/RECORD,,
561
+ agno-1.8.2.dist-info/licenses/LICENSE,sha256=m2rfTWFUfIwCaQqgT2WeBjuKzMKEJRwnaiofg9n8MsQ,16751
562
+ agno-1.8.2.dist-info/METADATA,sha256=vlStPRB06iknugb3p8fape5PRLcWQRybNm2L4Upa92E,44612
563
+ agno-1.8.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
564
+ agno-1.8.2.dist-info/entry_points.txt,sha256=Be-iPnPVabMohESsuUdV5w6IAYEIlpc2emJZbyNnfGI,88
565
+ agno-1.8.2.dist-info/top_level.txt,sha256=MKyeuVesTyOKIXUhc-d_tPa2Hrh0oTA4LM0izowpx70,5
566
+ agno-1.8.2.dist-info/RECORD,,
File without changes