agno 2.1.2__py3-none-any.whl → 2.1.3__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.
@@ -682,9 +682,7 @@ class FirestoreDb(BaseDb):
682
682
  log_error(f"Error deleting memories: {e}")
683
683
  raise e
684
684
 
685
- def get_all_memory_topics(
686
- self, create_collection_if_not_found: Optional[bool] = True
687
- ) -> List[str]:
685
+ def get_all_memory_topics(self, create_collection_if_not_found: Optional[bool] = True) -> List[str]:
688
686
  """Get all memory topics from the database.
689
687
 
690
688
  Returns:
@@ -472,7 +472,8 @@ class GcsJsonDb(BaseDb):
472
472
 
473
473
  # Filter out the memory, with optional user_id verification
474
474
  memories = [
475
- m for m in memories
475
+ m
476
+ for m in memories
476
477
  if not (m.get("memory_id") == memory_id and (user_id is None or m.get("user_id") == user_id))
477
478
  ]
478
479
 
@@ -499,7 +500,8 @@ class GcsJsonDb(BaseDb):
499
500
 
500
501
  # Filter out memories, with optional user_id verification
501
502
  memories = [
502
- m for m in memories
503
+ m
504
+ for m in memories
503
505
  if not (m.get("memory_id") in memory_ids and (user_id is None or m.get("user_id") == user_id))
504
506
  ]
505
507
 
@@ -642,7 +644,7 @@ class GcsJsonDb(BaseDb):
642
644
  user_stats[memory_user_id] = {
643
645
  "user_id": memory_user_id,
644
646
  "total_memories": 0,
645
- "last_memory_updated_at": 0
647
+ "last_memory_updated_at": 0,
646
648
  }
647
649
  user_stats[memory_user_id]["total_memories"] += 1
648
650
  updated_at = memory.get("updated_at", 0)
@@ -359,8 +359,7 @@ class InMemoryDb(BaseDb):
359
359
  # If user_id is provided, verify ownership before deleting
360
360
  if user_id is not None:
361
361
  self._memories = [
362
- m for m in self._memories
363
- if not (m.get("memory_id") == memory_id and m.get("user_id") == user_id)
362
+ m for m in self._memories if not (m.get("memory_id") == memory_id and m.get("user_id") == user_id)
364
363
  ]
365
364
  else:
366
365
  self._memories = [m for m in self._memories if m.get("memory_id") != memory_id]
@@ -388,8 +387,7 @@ class InMemoryDb(BaseDb):
388
387
  # If user_id is provided, verify ownership before deleting
389
388
  if user_id is not None:
390
389
  self._memories = [
391
- m for m in self._memories
392
- if not (m.get("memory_id") in memory_ids and m.get("user_id") == user_id)
390
+ m for m in self._memories if not (m.get("memory_id") in memory_ids and m.get("user_id") == user_id)
393
391
  ]
394
392
  else:
395
393
  self._memories = [m for m in self._memories if m.get("memory_id") not in memory_ids]
@@ -532,7 +530,11 @@ class InMemoryDb(BaseDb):
532
530
 
533
531
  if memory_user_id:
534
532
  if memory_user_id not in user_stats:
535
- user_stats[memory_user_id] = {"user_id": memory_user_id, "total_memories": 0, "last_memory_updated_at": 0}
533
+ user_stats[memory_user_id] = {
534
+ "user_id": memory_user_id,
535
+ "total_memories": 0,
536
+ "last_memory_updated_at": 0,
537
+ }
536
538
  user_stats[memory_user_id]["total_memories"] += 1
537
539
  updated_at = memory.get("updated_at", 0)
538
540
  if updated_at > user_stats[memory_user_id]["last_memory_updated_at"]:
@@ -360,7 +360,7 @@ class AwsBedrock(Model):
360
360
  formatted_messages, system_message = self._format_messages(messages)
361
361
 
362
362
  tool_config = None
363
- if tools:
363
+ if tools:
364
364
  tool_config = {"tools": self._format_tools_for_request(tools)}
365
365
 
366
366
  body = {
@@ -1,8 +1,11 @@
1
1
  from dataclasses import dataclass, field
2
2
  from os import getenv
3
- from typing import Optional
3
+ from typing import Any, Dict, List, Optional, Type, Union
4
+
5
+ from pydantic import BaseModel
4
6
 
5
7
  from agno.models.openai.like import OpenAILike
8
+ from agno.run.agent import RunOutput
6
9
 
7
10
 
8
11
  @dataclass
@@ -17,6 +20,9 @@ class OpenRouter(OpenAILike):
17
20
  api_key (Optional[str]): The API key.
18
21
  base_url (str): The base URL. Defaults to "https://openrouter.ai/api/v1".
19
22
  max_tokens (int): The maximum number of tokens. Defaults to 1024.
23
+ fallback_models (Optional[List[str]]): List of fallback model IDs to use if the primary model
24
+ fails due to rate limits, timeouts, or unavailability. OpenRouter will automatically try
25
+ these models in order. Example: ["anthropic/claude-sonnet-4", "deepseek/deepseek-r1"]
20
26
  """
21
27
 
22
28
  id: str = "gpt-4o"
@@ -26,3 +32,35 @@ class OpenRouter(OpenAILike):
26
32
  api_key: Optional[str] = field(default_factory=lambda: getenv("OPENROUTER_API_KEY"))
27
33
  base_url: str = "https://openrouter.ai/api/v1"
28
34
  max_tokens: int = 1024
35
+ models: Optional[List[str]] = None # Dynamic model routing https://openrouter.ai/docs/features/model-routing
36
+
37
+ def get_request_params(
38
+ self,
39
+ response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
40
+ tools: Optional[List[Dict[str, Any]]] = None,
41
+ tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
42
+ run_response: Optional[RunOutput] = None,
43
+ ) -> Dict[str, Any]:
44
+ """
45
+ Returns keyword arguments for API requests, including fallback models configuration.
46
+
47
+ Returns:
48
+ Dict[str, Any]: A dictionary of keyword arguments for API requests.
49
+ """
50
+ # Get base request params from parent class
51
+ request_params = super().get_request_params(
52
+ response_format=response_format, tools=tools, tool_choice=tool_choice, run_response=run_response
53
+ )
54
+
55
+ # Add fallback models to extra_body if specified
56
+ if self.models:
57
+ # Get existing extra_body or create new dict
58
+ extra_body = request_params.get("extra_body") or {}
59
+
60
+ # Merge fallback models into extra_body
61
+ extra_body["models"] = self.models
62
+
63
+ # Update request params
64
+ request_params["extra_body"] = extra_body
65
+
66
+ return request_params
File without changes
@@ -0,0 +1,74 @@
1
+ from dataclasses import dataclass
2
+ from os import getenv
3
+ from typing import Any, Dict, Optional
4
+
5
+ from agno.models.anthropic import Claude as AnthropicClaude
6
+
7
+ try:
8
+ from anthropic import AnthropicVertex as AnthropicClient
9
+ from anthropic import (
10
+ AsyncAnthropicVertex as AsyncAnthropicClient,
11
+ )
12
+ except ImportError as e:
13
+ raise ImportError("`anthropic` not installed. Please install it with `pip install anthropic`") from e
14
+
15
+
16
+ @dataclass
17
+ class Claude(AnthropicClaude):
18
+ """
19
+ A class representing Anthropic Claude model.
20
+
21
+ For more information, see: https://docs.anthropic.com/en/api/messages
22
+ """
23
+
24
+ id: str = "claude-sonnet-4@20250514"
25
+ name: str = "Claude"
26
+ provider: str = "VertexAI"
27
+
28
+ # Client parameters
29
+ region: Optional[str] = None
30
+ project_id: Optional[str] = None
31
+ base_url: Optional[str] = None
32
+
33
+ # Anthropic clients
34
+ client: Optional[AnthropicClient] = None
35
+ async_client: Optional[AsyncAnthropicClient] = None
36
+
37
+ def _get_client_params(self) -> Dict[str, Any]:
38
+ client_params: Dict[str, Any] = {}
39
+
40
+ # Add API key to client parameters
41
+ client_params["region"] = self.region or getenv("CLOUD_ML_REGION")
42
+ client_params["project_id"] = self.project_id or getenv("ANTHROPIC_VERTEX_PROJECT_ID")
43
+ client_params["base_url"] = self.base_url or getenv("ANTHROPIC_VERTEX_BASE_URL")
44
+ if self.timeout is not None:
45
+ client_params["timeout"] = self.timeout
46
+
47
+ # Add additional client parameters
48
+ if self.client_params is not None:
49
+ client_params.update(self.client_params)
50
+ if self.default_headers is not None:
51
+ client_params["default_headers"] = self.default_headers
52
+ return client_params
53
+
54
+ def get_client(self) -> AnthropicClient:
55
+ """
56
+ Returns an instance of the Anthropic client.
57
+ """
58
+ if self.client and not self.client.is_closed():
59
+ return self.client
60
+
61
+ _client_params = self._get_client_params()
62
+ self.client = AnthropicClient(**_client_params)
63
+ return self.client
64
+
65
+ def get_async_client(self) -> AsyncAnthropicClient:
66
+ """
67
+ Returns an instance of the async Anthropic client.
68
+ """
69
+ if self.async_client:
70
+ return self.async_client
71
+
72
+ _client_params = self._get_client_params()
73
+ self.async_client = AsyncAnthropicClient(**_client_params)
74
+ return self.async_client
agno/os/app.py CHANGED
@@ -64,6 +64,30 @@ async def mcp_lifespan(_, mcp_tools):
64
64
  await tool.close()
65
65
 
66
66
 
67
+ def _combine_app_lifespans(lifespans: list) -> Any:
68
+ """Combine multiple FastAPI app lifespan context managers into one."""
69
+ if len(lifespans) == 1:
70
+ return lifespans[0]
71
+
72
+ from contextlib import asynccontextmanager
73
+
74
+ @asynccontextmanager
75
+ async def combined_lifespan(app):
76
+ async def _run_nested(index: int):
77
+ if index >= len(lifespans):
78
+ yield
79
+ return
80
+
81
+ async with lifespans[index](app):
82
+ async for _ in _run_nested(index + 1):
83
+ yield
84
+
85
+ async for _ in _run_nested(0):
86
+ yield
87
+
88
+ return combined_lifespan
89
+
90
+
67
91
  class AgentOS:
68
92
  def __init__(
69
93
  self,
@@ -220,7 +244,7 @@ class AgentOS:
220
244
  async with mcp_tools_lifespan(app): # type: ignore
221
245
  yield
222
246
 
223
- app_lifespan = combined_lifespan # type: ignore
247
+ app_lifespan = combined_lifespan
224
248
  else:
225
249
  app_lifespan = mcp_tools_lifespan
226
250
 
@@ -237,6 +261,32 @@ class AgentOS:
237
261
  def get_app(self) -> FastAPI:
238
262
  if self.base_app:
239
263
  fastapi_app = self.base_app
264
+
265
+ # Initialize MCP server if enabled
266
+ if self.enable_mcp_server:
267
+ from agno.os.mcp import get_mcp_server
268
+
269
+ self._mcp_app = get_mcp_server(self)
270
+
271
+ # Collect all lifespans that need to be combined
272
+ lifespans = []
273
+
274
+ if fastapi_app.router.lifespan_context:
275
+ lifespans.append(fastapi_app.router.lifespan_context)
276
+
277
+ if self.mcp_tools:
278
+ lifespans.append(partial(mcp_lifespan, mcp_tools=self.mcp_tools))
279
+
280
+ if self.enable_mcp_server and self._mcp_app:
281
+ lifespans.append(self._mcp_app.lifespan)
282
+
283
+ if self.lifespan:
284
+ lifespans.append(self.lifespan)
285
+
286
+ # Combine lifespans and set them in the app
287
+ if lifespans:
288
+ fastapi_app.router.lifespan_context = _combine_app_lifespans(lifespans)
289
+
240
290
  else:
241
291
  if self.enable_mcp_server:
242
292
  from contextlib import asynccontextmanager
@@ -255,7 +305,7 @@ class AgentOS:
255
305
  async with self._mcp_app.lifespan(app): # type: ignore
256
306
  yield
257
307
 
258
- final_lifespan = combined_lifespan # type: ignore
308
+ final_lifespan = combined_lifespan
259
309
 
260
310
  fastapi_app = self._make_app(lifespan=final_lifespan)
261
311
  else:
agno/os/mcp.py CHANGED
@@ -78,21 +78,21 @@ def get_mcp_server(
78
78
  agent = get_agent_by_id(agent_id, os.agents)
79
79
  if agent is None:
80
80
  raise Exception(f"Agent {agent_id} not found")
81
- return agent.run(message)
81
+ return await agent.arun(message)
82
82
 
83
83
  @mcp.tool(name="run_team", description="Run a team", tags={"core"}) # type: ignore
84
84
  async def run_team(team_id: str, message: str) -> TeamRunOutput:
85
85
  team = get_team_by_id(team_id, os.teams)
86
86
  if team is None:
87
87
  raise Exception(f"Team {team_id} not found")
88
- return team.run(message)
88
+ return await team.arun(message)
89
89
 
90
90
  @mcp.tool(name="run_workflow", description="Run a workflow", tags={"core"}) # type: ignore
91
91
  async def run_workflow(workflow_id: str, message: str) -> WorkflowRunOutput:
92
92
  workflow = get_workflow_by_id(workflow_id, os.workflows)
93
93
  if workflow is None:
94
94
  raise Exception(f"Workflow {workflow_id} not found")
95
- return workflow.run(message)
95
+ return await workflow.arun(message)
96
96
 
97
97
  # Session Management Tools
98
98
  @mcp.tool(name="get_sessions_for_agent", description="Get list of sessions for an agent", tags={"session"}) # type: ignore
agno/os/utils.py CHANGED
@@ -96,7 +96,7 @@ def get_session_name(session: Dict[str, Any]) -> str:
96
96
  run = None
97
97
  for r in runs:
98
98
  # If agent_id is not present, it's a team run
99
- if not r.get("agent_id"):
99
+ if not r.get("agent_id"):
100
100
  run = r
101
101
  break
102
102
  # Fallback to first run if no team run found
@@ -112,6 +112,7 @@ def get_session_name(session: Dict[str, Any]) -> str:
112
112
  elif isinstance(workflow_input, dict):
113
113
  try:
114
114
  import json
115
+
115
116
  return json.dumps(workflow_input)
116
117
  except (TypeError, ValueError):
117
118
  pass
agno/tools/file.py CHANGED
@@ -75,7 +75,9 @@ class FileTools(Toolkit):
75
75
  """
76
76
  try:
77
77
  log_info(f"Reading files in : {self.base_dir}")
78
- return json.dumps([str(file_path) for file_path in self.base_dir.iterdir()], indent=4)
78
+ return json.dumps(
79
+ [str(file_path.relative_to(self.base_dir)) for file_path in self.base_dir.iterdir()], indent=4
80
+ )
79
81
  except Exception as e:
80
82
  log_error(f"Error reading files: {e}")
81
83
  return f"Error reading files: {e}"
@@ -93,7 +95,7 @@ class FileTools(Toolkit):
93
95
  log_debug(f"Searching files in {self.base_dir} with pattern {pattern}")
94
96
  matching_files = list(self.base_dir.glob(pattern))
95
97
 
96
- file_paths = [str(file_path) for file_path in matching_files]
98
+ file_paths = [str(file_path.relative_to(self.base_dir)) for file_path in matching_files]
97
99
 
98
100
  result = {
99
101
  "pattern": pattern,
agno/utils/merge_dict.py CHANGED
@@ -27,7 +27,7 @@ def merge_parallel_session_states(original_state: Dict[str, Any], modified_state
27
27
  """
28
28
  if not original_state or not modified_states:
29
29
  return
30
-
30
+
31
31
  # Collect all actual changes (keys where value differs from original)
32
32
  all_changes = {}
33
33
  for modified_state in modified_states:
@@ -35,7 +35,7 @@ def merge_parallel_session_states(original_state: Dict[str, Any], modified_state
35
35
  for key, value in modified_state.items():
36
36
  if key not in original_state or original_state[key] != value:
37
37
  all_changes[key] = value
38
-
38
+
39
39
  # Apply all collected changes to the original state
40
40
  for key, value in all_changes.items():
41
- original_state[key] = value
41
+ original_state[key] = value
agno/workflow/parallel.py CHANGED
@@ -14,8 +14,8 @@ from agno.run.workflow import (
14
14
  WorkflowRunOutput,
15
15
  WorkflowRunOutputEvent,
16
16
  )
17
- from agno.utils.merge_dict import merge_parallel_session_states
18
17
  from agno.utils.log import log_debug, logger
18
+ from agno.utils.merge_dict import merge_parallel_session_states
19
19
  from agno.workflow.condition import Condition
20
20
  from agno.workflow.step import Step
21
21
  from agno.workflow.types import StepInput, StepOutput, StepType
@@ -220,7 +220,7 @@ class Parallel:
220
220
  idx, step = step_with_index
221
221
  # Use the individual session_state copy for this step
222
222
  step_session_state = session_state_copies[idx]
223
-
223
+
224
224
  try:
225
225
  step_result = step.execute(
226
226
  step_input,
@@ -350,7 +350,7 @@ class Parallel:
350
350
  idx, step = step_with_index
351
351
  # Use the individual session_state copy for this step
352
352
  step_session_state = session_state_copies[idx]
353
-
353
+
354
354
  try:
355
355
  step_events = []
356
356
 
@@ -506,7 +506,7 @@ class Parallel:
506
506
  idx, step = step_with_index
507
507
  # Use the individual session_state copy for this step
508
508
  step_session_state = session_state_copies[idx]
509
-
509
+
510
510
  try:
511
511
  inner_step_result = await step.aexecute(
512
512
  step_input,
@@ -637,7 +637,7 @@ class Parallel:
637
637
  idx, step = step_with_index
638
638
  # Use the individual session_state copy for this step
639
639
  step_session_state = session_state_copies[idx]
640
-
640
+
641
641
  try:
642
642
  step_events = []
643
643
 
agno/workflow/workflow.py CHANGED
@@ -875,9 +875,7 @@ class Workflow:
875
875
  return func(**call_kwargs)
876
876
  except TypeError as e:
877
877
  # If signature inspection fails, fall back to original method
878
- logger.error(
879
- f"Function signature inspection failed: {e}. Falling back to original calling convention."
880
- )
878
+ logger.error(f"Function signature inspection failed: {e}. Falling back to original calling convention.")
881
879
  return func(**kwargs)
882
880
 
883
881
  def _execute(
@@ -892,7 +890,8 @@ class Workflow:
892
890
  from inspect import isasyncgenfunction, iscoroutinefunction, isgeneratorfunction
893
891
 
894
892
  workflow_run_response.status = RunStatus.running
895
- register_run(workflow_run_response.run_id) # type: ignore
893
+ if workflow_run_response.run_id:
894
+ register_run(workflow_run_response.run_id) # type: ignore
896
895
 
897
896
  if callable(self.steps):
898
897
  if iscoroutinefunction(self.steps) or isasyncgenfunction(self.steps):
@@ -1346,7 +1345,8 @@ class Workflow:
1346
1345
  workflow_run_response.status = RunStatus.running
1347
1346
 
1348
1347
  # Register run for cancellation tracking
1349
- register_run(workflow_run_response.run_id) # type: ignore
1348
+ if workflow_run_response.run_id:
1349
+ register_run(workflow_run_response.run_id) # type: ignore
1350
1350
 
1351
1351
  if callable(self.steps):
1352
1352
  # Execute the workflow with the custom executor
@@ -1507,6 +1507,10 @@ class Workflow:
1507
1507
 
1508
1508
  workflow_run_response.status = RunStatus.running
1509
1509
 
1510
+ # Register run for cancellation tracking
1511
+ if workflow_run_response.run_id:
1512
+ register_run(workflow_run_response.run_id)
1513
+
1510
1514
  workflow_started_event = WorkflowStartedEvent(
1511
1515
  run_id=workflow_run_response.run_id or "",
1512
1516
  workflow_name=workflow_run_response.workflow_name,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agno
3
- Version: 2.1.2
3
+ Version: 2.1.3
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
@@ -35,14 +35,14 @@ agno/db/dynamo/dynamo.py,sha256=o4zmI2Nvul4ZLRoUokUCwko1n4dKsJe6hB0xRbb3dpA,7148
35
35
  agno/db/dynamo/schemas.py,sha256=ZqeR4QdqMVi53iz2qcs-d5Y6MDfmhHSuP7vot__hLoI,11638
36
36
  agno/db/dynamo/utils.py,sha256=3Kwkq7FqUac6Q6BjwuzWzfyo4ANnS8FIz7_n3EEnbYo,25047
37
37
  agno/db/firestore/__init__.py,sha256=lYAJjUs4jMxJFty1GYZw464K35zeuBlcoFR9uuIQYtI,79
38
- agno/db/firestore/firestore.py,sha256=zfmEZiCXpxuTgoruVXLjy8TLjqw8dptgsvvP9f4B7Gs,61519
38
+ agno/db/firestore/firestore.py,sha256=Z548061P68EeyH7H8RexEgn6i2W6DLSjDO9dz3A7OZA,61505
39
39
  agno/db/firestore/schemas.py,sha256=k8YuG_PC_Hd3WCLaDkk4bAJP8BmAWmrt6VXuG1wr2Ak,4132
40
40
  agno/db/firestore/utils.py,sha256=FVR1XQjnsZsG3IrFyvTOHICd0lgD99aajUJ-UAvVEOg,10332
41
41
  agno/db/gcs_json/__init__.py,sha256=aTR4o3aFrzfANHtRw7nX9uc5_GsY52ch0rmoo7uXuc4,76
42
- agno/db/gcs_json/gcs_json_db.py,sha256=mjyqMjvXBJoM4L0OOyO19NLQIanReS64Pb7bM__RYJw,46974
42
+ agno/db/gcs_json/gcs_json_db.py,sha256=jVj8i70XDO7O1E8wIr_xAeC1Shng_vpOzZui--8eMFQ,47007
43
43
  agno/db/gcs_json/utils.py,sha256=Ist4HuQoYvC2BKr01oTxDp9mfMirz1UBBDKElbXg2bg,6610
44
44
  agno/db/in_memory/__init__.py,sha256=OvR_FONhOh9PmcRfUA_6gvplZT5UGIBAgVKqVg6SWTA,80
45
- agno/db/in_memory/in_memory_db.py,sha256=gieZm2o9EH-vJwxaqxiK_3qfs0hVDazYWpxGdHVl3F0,41214
45
+ agno/db/in_memory/in_memory_db.py,sha256=MwHk7EcKIHpOFXBJSeb1z6tCSyjUKW3zZpUmyHqWTpM,41285
46
46
  agno/db/in_memory/utils.py,sha256=X02wny18w5uvGE3caokPbCQTG6t7OErWNPkK3Umru3s,5780
47
47
  agno/db/json/__init__.py,sha256=zyPTmVF9S-OwXCL7FSkrDmunZ_Q14YZO3NYUv1Pa14Y,62
48
48
  agno/db/json/json_db.py,sha256=WkPhdkvDKYOc6Q-QUOlhV1G9-VPo0YQzpU1qrmPHMis,47585
@@ -163,7 +163,7 @@ agno/models/aimlapi/aimlapi.py,sha256=9Qh-b8HvFSvmPP3VBNGT00qy9izHLMWgR-KDQCE5CM
163
163
  agno/models/anthropic/__init__.py,sha256=nbReX3p17JCwfrMDR9hR7-OaEFZm80I7dng93dl-Fhw,77
164
164
  agno/models/anthropic/claude.py,sha256=7chDZrLdh_ocFLOy3qHwOY_pfZrJ-EWrB3otLv97fNU,26488
165
165
  agno/models/aws/__init__.py,sha256=TbcwQwv9A7KjqBM5RQBR8x46GvyyCxbBCjwkpjfVGKE,352
166
- agno/models/aws/bedrock.py,sha256=8Yhxumoy2yL9QScVAZqm2jKoHP39lXCsd718N9-_Tao,28881
166
+ agno/models/aws/bedrock.py,sha256=ScZcGwOMh-N0DfArXtDVzKy467QPAN0OS8llBNAc8cQ,28880
167
167
  agno/models/aws/claude.py,sha256=sL47z9fM3jxGbARkr0mlAVYEKKX854J3u-Qeb5gIADo,14746
168
168
  agno/models/azure/__init__.py,sha256=EoFdJHjayvmv_VOmaW9cJguwA1K5OFS_nFeazyn0B2w,605
169
169
  agno/models/azure/ai_foundry.py,sha256=V75lk4pH_RVFzVhWYz9-ZSA3dcaQe2SpRF1lrAm_agw,18673
@@ -220,7 +220,7 @@ agno/models/openai/chat.py,sha256=ZdFj0xeCEGI1_UR_q_IsHl_KqoQ076g8LG5g32zJRYc,37
220
220
  agno/models/openai/like.py,sha256=wmw9PfAVqluBs4MMY73dgjelKn1yl5JDKyCRvaNFjFw,745
221
221
  agno/models/openai/responses.py,sha256=HyrfTZF8AkjdxktKhos9Riuos03nkhSvreeQGAyn81A,47116
222
222
  agno/models/openrouter/__init__.py,sha256=ZpZhNyy_EGSXp58uC9e2iyjnxBctql7GaY8rUG-599I,90
223
- agno/models/openrouter/openrouter.py,sha256=FX0P9mPEHyTuiVQNs-c84Ehy0RIGEmvdy6WM_-KhxUQ,907
223
+ agno/models/openrouter/openrouter.py,sha256=YXjTHcETz4mn-exBr0GyAbP7_XeQMJkF7Pdf2XBRdFw,2595
224
224
  agno/models/perplexity/__init__.py,sha256=JNmOElDLwcZ9_Lk5owkEdgwmAhaH3YJ-VJqOI8rgp5c,90
225
225
  agno/models/perplexity/perplexity.py,sha256=d17a9pbSrTIM2PIwCPq8_QrgcNmv1klMsS8rWnEa1fI,6988
226
226
  agno/models/portkey/__init__.py,sha256=CjGmltOuDlYfuJgpYHmfRkKiIS9W9MH4oYaGKaNNZeM,71
@@ -235,19 +235,21 @@ agno/models/together/__init__.py,sha256=y6-pgHLEInpJtffjLGHkUWTDpoQNnMlKHa4fstyH
235
235
  agno/models/together/together.py,sha256=27e-0IqlsFYh0d40XiOjx18GjOqytFI7vwcnCk8JApg,950
236
236
  agno/models/vercel/__init__.py,sha256=BYQD23dB-dmIXm8iy4S6yxXRW8xg24E9TLOgwckH674,55
237
237
  agno/models/vercel/v0.py,sha256=48Na0ZFBnRw3hUFUqO5xMO78jzOYnBj-o5kLLg4F188,826
238
+ agno/models/vertexai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
239
+ agno/models/vertexai/claude.py,sha256=7dw2oF4rQ7-ZncsSTxuXVVtUWpQ1ijSGZkWPFredepM,2454
238
240
  agno/models/vllm/__init__.py,sha256=G8cpCZtu4zJvMGud5eSYMMxGBpNTe9jM4W-p0XUeCGE,59
239
241
  agno/models/vllm/vllm.py,sha256=UtiiSvUR4pG_1CzuhY5MWduRgzM2hGVTakKJ6ZBdQmo,2730
240
242
  agno/models/xai/__init__.py,sha256=ukcCxnCHxTtkJNA2bAMTX4MhCv1wJcbiq8ZIfYczIxs,55
241
243
  agno/models/xai/xai.py,sha256=jA6_39tfapkjkHKdzbKaNq1t9qIvO1IaZY1hQqEmFVs,4181
242
244
  agno/os/__init__.py,sha256=h8oQu7vhD5RZf09jkyM_Kt1Kdq_d5kFB9gJju8QPwcY,55
243
- agno/os/app.py,sha256=8qX4zF16Ly-U0zxrNwuA_L8BIea6bMLRYqiP_qonr10,24937
245
+ agno/os/app.py,sha256=MGUa56gOj7-O9x5xZriwxsRuiC2m93H_B206ScnzqAY,26434
244
246
  agno/os/auth.py,sha256=FyBtAKWtg-qSunCas5m5pK1dVEmikOSZvcCp5r25tTA,1844
245
247
  agno/os/config.py,sha256=u4R9yazQXIcKjR3QzEIZw_XAe_OHp3xn0ff7SVkj2jA,2893
246
- agno/os/mcp.py,sha256=w9x8dN-UuIhRrU8azvjPB95RHIcOKh5IXlRCClCfpN4,8104
248
+ agno/os/mcp.py,sha256=BQk3EXCyU3-KHJn7829aOs7txV9TE3p7bwPlYJ7iFGc,8125
247
249
  agno/os/router.py,sha256=-w_VXQm2QscNAAeDehAgQ9CStNpPr06qhPmYYhiZslM,69930
248
250
  agno/os/schema.py,sha256=bdmGLQoBJyetiAZeajJG_gEKLaQSSEwiDwKy0q4Pa-M,38278
249
251
  agno/os/settings.py,sha256=Cn5_8lZI8Vx1UaUYqs9h6Qp4IMDFn4f3c35uppiaMy4,1343
250
- agno/os/utils.py,sha256=IUi608rikks17lsOFia6LK_6YlMB6M5xe6pS90t0xV4,17901
252
+ agno/os/utils.py,sha256=scwbYQ_OhsSvdAKnN2LHpj_TB_vwsQx23lkswIz_TZs,17900
251
253
  agno/os/interfaces/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
252
254
  agno/os/interfaces/base.py,sha256=vXkr1tRjWHTcmBlQFzvQjqURLhObmFtUAx82uij_j48,542
253
255
  agno/os/interfaces/a2a/__init__.py,sha256=Fs7--dx9drvtVS9QjsCCm0P7c-hJ7TzU8gNwKTQsZDA,62
@@ -344,7 +346,7 @@ agno/tools/email.py,sha256=YmqNngDMDfJn-TCrxGV9IxRh2xcLmxQh7NOuuKTyUwU,2359
344
346
  agno/tools/evm.py,sha256=lX8KhpfHBcYANuNLmNI7EmwrnkE1anXjWGsGuM3_hRM,5371
345
347
  agno/tools/exa.py,sha256=vwTcNo8iOh_0QDSV1dpgf7qtKpRW4cm9KPRIN3GcLWw,16844
346
348
  agno/tools/fal.py,sha256=49rgpgfpk-aKUs18x8vDH1Wa4jNOPKN3iczfqWMo8xw,4633
347
- agno/tools/file.py,sha256=h3CiiM0wREK3vR_PlYFwJ8zYBFFjNmReNnAm9-JPgCU,4322
349
+ agno/tools/file.py,sha256=SVikIqRyxGW7byyqk0GSuz4KCUZGxZEsE_EK8ag3aak,4406
348
350
  agno/tools/file_generation.py,sha256=OMRG1CkpnZTCMxnKXGHfkfdXUYEur9jsdyCNxujWHS4,13896
349
351
  agno/tools/financial_datasets.py,sha256=NiXwyiYIFCawI8rR7JLJNIfwoQlranUeCcABHKhLHfw,9190
350
352
  agno/tools/firecrawl.py,sha256=sMV6XRaSIyTSkTJbtMdIQPTsN11ozJ78YDDi04kBvQE,5341
@@ -450,7 +452,7 @@ agno/utils/location.py,sha256=VhXIwSWdr7L4DEJoUeVI92Y-rJ32NUcYzFRnzLgX-es,658
450
452
  agno/utils/log.py,sha256=Ycg4_MEkXyOz25OkY272JHWxIZP1nB4OScwJ-r8BMGk,7791
451
453
  agno/utils/mcp.py,sha256=v5juISDNtdQaUK1DmJnAAGuNiSp0491TDwErgjEdhF8,5113
452
454
  agno/utils/media.py,sha256=Lk0sbSHmoKlQi3hLKorowCKGF74xdeMfqIj6Gt21Zek,5891
453
- agno/utils/merge_dict.py,sha256=L-t3BuKZD5fG-7fscTGG2nKSKcVCXXkdGgKR1TgQRXQ,1497
455
+ agno/utils/merge_dict.py,sha256=K_dZdwi46gjDFn7wgqZ9_fycRIZGJCnUxFVKCrQ6PYc,1490
454
456
  agno/utils/message.py,sha256=HcTDVdgZOfwqGL0YW5QNEeNoSLUvTawCo6_USJzsd6M,2423
455
457
  agno/utils/openai.py,sha256=quhHsggz0uSZc9Lt-aVsveHSS1LT2r1fMgC0IpG43Tg,10300
456
458
  agno/utils/pickle.py,sha256=Ip6CPNxAWF3MVrUhMTW7e3IcpKhYG0IA-NKbdUYr94c,1008
@@ -530,14 +532,14 @@ agno/vectordb/weaviate/weaviate.py,sha256=ZXK81-mTZmPUzUi2U6B5oY2vvJ5eWCv2Hqrwin
530
532
  agno/workflow/__init__.py,sha256=lwavZXIkgqajbSf1jMqzE7kbXBIFmk5niI_NgpVI-gA,542
531
533
  agno/workflow/condition.py,sha256=JFWPnwEeOIkQWexGYDK9pToPyf_siRCW92rkFdA4yTc,28452
532
534
  agno/workflow/loop.py,sha256=cTVkRX5pwfZH5O19Q3W3YS9bcSKmEszkDwfR0V72rV8,30635
533
- agno/workflow/parallel.py,sha256=msc1n1ga5KZjMySZ7JGFVAMYCgJ8PjPIcR0ue5GnIG0,33667
535
+ agno/workflow/parallel.py,sha256=FjsGDKTie8Rt_xDrQs7vMczx_XsaNrAbajWCEk81-wI,33619
534
536
  agno/workflow/router.py,sha256=ZAiVsh2F_9ssKj0_RzHWzfgimaZ5hfb3Ni1Xx_SkVR0,26625
535
537
  agno/workflow/step.py,sha256=JgqvINTmY8Y0RnQP5wQ4v03K479XK3YTa36ZZWYg_Z8,52289
536
538
  agno/workflow/steps.py,sha256=uRE4oGWs2cA-TrX881AEa69zu6rheXH81mNOZiRrNvg,23719
537
539
  agno/workflow/types.py,sha256=ajZg2hQ9VmJQrmqwXpsIAOnkelYQmWNjbb7ZS-Y3Xpo,17632
538
- agno/workflow/workflow.py,sha256=QSMWhff996gYkPOzcj-qv_HA51z54ts9a4UTemOMTkA,115187
539
- agno-2.1.2.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
540
- agno-2.1.2.dist-info/METADATA,sha256=WBDPmWLZjVh7nMQW8a056PVRP3eWEPv_7NybMJPuXSM,22009
541
- agno-2.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
542
- agno-2.1.2.dist-info/top_level.txt,sha256=MKyeuVesTyOKIXUhc-d_tPa2Hrh0oTA4LM0izowpx70,5
543
- agno-2.1.2.dist-info/RECORD,,
540
+ agno/workflow/workflow.py,sha256=WH0MfGx5iVepwOJfbV1IuO_aHGeMbxc8yuCnWzZWQaM,115393
541
+ agno-2.1.3.dist-info/licenses/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
542
+ agno-2.1.3.dist-info/METADATA,sha256=-BO85k6qLtl1kDextO3Ca-UyHnPNBJpcWTs0WBsU6Bo,22009
543
+ agno-2.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
544
+ agno-2.1.3.dist-info/top_level.txt,sha256=MKyeuVesTyOKIXUhc-d_tPa2Hrh0oTA4LM0izowpx70,5
545
+ agno-2.1.3.dist-info/RECORD,,
File without changes