agno 2.3.6__py3-none-any.whl → 2.3.8__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/agent/agent.py +540 -369
- agno/db/mongo/async_mongo.py +0 -24
- agno/db/mongo/mongo.py +0 -16
- agno/db/mysql/mysql.py +0 -19
- agno/db/postgres/async_postgres.py +23 -28
- agno/db/postgres/postgres.py +0 -23
- agno/db/redis/redis.py +0 -4
- agno/db/singlestore/singlestore.py +0 -11
- agno/db/sqlite/async_sqlite.py +0 -24
- agno/db/sqlite/sqlite.py +0 -20
- agno/db/utils.py +2 -0
- agno/models/base.py +168 -15
- agno/models/openai/responses.py +3 -2
- agno/models/response.py +1 -1
- agno/os/interfaces/a2a/utils.py +1 -1
- agno/os/middleware/jwt.py +8 -6
- agno/os/routers/evals/utils.py +13 -3
- agno/run/agent.py +17 -0
- agno/run/requirement.py +98 -0
- agno/run/team.py +10 -0
- agno/team/team.py +179 -96
- agno/tools/postgres.py +76 -36
- agno/tools/redshift.py +406 -0
- agno/tools/toolkit.py +25 -0
- agno/tools/workflow.py +8 -1
- agno/utils/events.py +5 -1
- agno/workflow/parallel.py +8 -2
- agno/workflow/step.py +3 -3
- {agno-2.3.6.dist-info → agno-2.3.8.dist-info}/METADATA +5 -2
- {agno-2.3.6.dist-info → agno-2.3.8.dist-info}/RECORD +33 -32
- agno/tools/memori.py +0 -339
- {agno-2.3.6.dist-info → agno-2.3.8.dist-info}/WHEEL +0 -0
- {agno-2.3.6.dist-info → agno-2.3.8.dist-info}/licenses/LICENSE +0 -0
- {agno-2.3.6.dist-info → agno-2.3.8.dist-info}/top_level.txt +0 -0
agno/agent/agent.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import time
|
|
3
4
|
import warnings
|
|
4
5
|
from asyncio import CancelledError, create_task
|
|
5
6
|
from collections import ChainMap, deque
|
|
@@ -35,10 +36,8 @@ from agno.db.base import AsyncBaseDb, BaseDb, SessionType, UserMemory
|
|
|
35
36
|
from agno.db.schemas.culture import CulturalKnowledge
|
|
36
37
|
from agno.exceptions import (
|
|
37
38
|
InputCheckError,
|
|
38
|
-
ModelProviderError,
|
|
39
39
|
OutputCheckError,
|
|
40
40
|
RunCancelledException,
|
|
41
|
-
StopAgentRun,
|
|
42
41
|
)
|
|
43
42
|
from agno.filters import FilterExpr
|
|
44
43
|
from agno.guardrails import BaseGuardrail
|
|
@@ -68,6 +67,7 @@ from agno.run.cancel import (
|
|
|
68
67
|
register_run,
|
|
69
68
|
)
|
|
70
69
|
from agno.run.messages import RunMessages
|
|
70
|
+
from agno.run.requirement import RunRequirement
|
|
71
71
|
from agno.run.team import TeamRunOutputEvent
|
|
72
72
|
from agno.session import AgentSession, SessionSummaryManager, TeamSession, WorkflowSession
|
|
73
73
|
from agno.session.summary import SessionSummary
|
|
@@ -557,8 +557,12 @@ class Agent:
|
|
|
557
557
|
self.enable_user_memories = enable_user_memories
|
|
558
558
|
self.add_memories_to_context = add_memories_to_context
|
|
559
559
|
|
|
560
|
-
self.session_summary_manager = session_summary_manager
|
|
561
560
|
self.enable_session_summaries = enable_session_summaries
|
|
561
|
+
|
|
562
|
+
if session_summary_manager is not None:
|
|
563
|
+
self.session_summary_manager = session_summary_manager
|
|
564
|
+
self.enable_session_summaries = True
|
|
565
|
+
|
|
562
566
|
self.add_session_summary_to_context = add_session_summary_to_context
|
|
563
567
|
|
|
564
568
|
# Context compression settings
|
|
@@ -683,6 +687,7 @@ class Agent:
|
|
|
683
687
|
self._hooks_normalised = False
|
|
684
688
|
|
|
685
689
|
self._mcp_tools_initialized_on_run: List[Any] = []
|
|
690
|
+
self._connectable_tools_initialized_on_run: List[Any] = []
|
|
686
691
|
|
|
687
692
|
# Lazy-initialized shared thread pool executor for background tasks (memory, cultural knowledge, etc.)
|
|
688
693
|
self._background_executor: Optional[Any] = None
|
|
@@ -912,16 +917,48 @@ class Agent:
|
|
|
912
917
|
and any(c.__name__ in ["MCPTools", "MultiMCPTools"] for c in type(tool).__mro__)
|
|
913
918
|
and not tool.initialized # type: ignore
|
|
914
919
|
):
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
920
|
+
try:
|
|
921
|
+
# Connect the MCP server
|
|
922
|
+
await tool.connect() # type: ignore
|
|
923
|
+
self._mcp_tools_initialized_on_run.append(tool) # type: ignore
|
|
924
|
+
except Exception as e:
|
|
925
|
+
log_warning(f"Error connecting tool: {str(e)}")
|
|
918
926
|
|
|
919
927
|
async def _disconnect_mcp_tools(self) -> None:
|
|
920
928
|
"""Disconnect the MCP tools from the agent."""
|
|
921
929
|
for tool in self._mcp_tools_initialized_on_run:
|
|
922
|
-
|
|
930
|
+
try:
|
|
931
|
+
await tool.close()
|
|
932
|
+
except Exception as e:
|
|
933
|
+
log_warning(f"Error disconnecting tool: {str(e)}")
|
|
923
934
|
self._mcp_tools_initialized_on_run = []
|
|
924
935
|
|
|
936
|
+
def _connect_connectable_tools(self) -> None:
|
|
937
|
+
"""Connect tools that require connection management (e.g., database connections)."""
|
|
938
|
+
if self.tools:
|
|
939
|
+
for tool in self.tools:
|
|
940
|
+
if (
|
|
941
|
+
hasattr(tool, "requires_connect")
|
|
942
|
+
and tool.requires_connect
|
|
943
|
+
and hasattr(tool, "connect")
|
|
944
|
+
and tool not in self._connectable_tools_initialized_on_run
|
|
945
|
+
):
|
|
946
|
+
try:
|
|
947
|
+
tool.connect() # type: ignore
|
|
948
|
+
self._connectable_tools_initialized_on_run.append(tool)
|
|
949
|
+
except Exception as e:
|
|
950
|
+
log_warning(f"Error connecting tool: {str(e)}")
|
|
951
|
+
|
|
952
|
+
def _disconnect_connectable_tools(self) -> None:
|
|
953
|
+
"""Disconnect tools that require connection management."""
|
|
954
|
+
for tool in self._connectable_tools_initialized_on_run:
|
|
955
|
+
if hasattr(tool, "close"):
|
|
956
|
+
try:
|
|
957
|
+
tool.close() # type: ignore
|
|
958
|
+
except Exception as e:
|
|
959
|
+
log_warning(f"Error disconnecting tool: {str(e)}")
|
|
960
|
+
self._connectable_tools_initialized_on_run = []
|
|
961
|
+
|
|
925
962
|
def _initialize_session(
|
|
926
963
|
self,
|
|
927
964
|
session_id: Optional[str] = None,
|
|
@@ -1052,7 +1089,12 @@ class Agent:
|
|
|
1052
1089
|
# Start memory creation on a separate thread (runs concurrently with the main execution loop)
|
|
1053
1090
|
memory_future = None
|
|
1054
1091
|
# 4. Start memory creation in background thread if memory manager is enabled and agentic memory is disabled
|
|
1055
|
-
if
|
|
1092
|
+
if (
|
|
1093
|
+
run_messages.user_message is not None
|
|
1094
|
+
and self.memory_manager is not None
|
|
1095
|
+
and self.enable_user_memories
|
|
1096
|
+
and not self.enable_agentic_memory
|
|
1097
|
+
):
|
|
1056
1098
|
log_debug("Starting memory creation in background thread.")
|
|
1057
1099
|
memory_future = self.background_executor.submit(
|
|
1058
1100
|
self._make_memories, run_messages=run_messages, user_id=user_id
|
|
@@ -1141,7 +1183,7 @@ class Agent:
|
|
|
1141
1183
|
wait_for_open_threads(memory_future=memory_future, cultural_knowledge_future=cultural_knowledge_future)
|
|
1142
1184
|
|
|
1143
1185
|
# 12. Create session summary
|
|
1144
|
-
if self.session_summary_manager is not None:
|
|
1186
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
1145
1187
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
1146
1188
|
session.upsert_run(run=run_response)
|
|
1147
1189
|
try:
|
|
@@ -1175,6 +1217,8 @@ class Agent:
|
|
|
1175
1217
|
|
|
1176
1218
|
return run_response
|
|
1177
1219
|
finally:
|
|
1220
|
+
# Always disconnect connectable tools
|
|
1221
|
+
self._disconnect_connectable_tools()
|
|
1178
1222
|
# Always clean up the run tracking
|
|
1179
1223
|
cleanup_run(run_response.run_id) # type: ignore
|
|
1180
1224
|
|
|
@@ -1269,7 +1313,12 @@ class Agent:
|
|
|
1269
1313
|
# Start memory creation on a separate thread (runs concurrently with the main execution loop)
|
|
1270
1314
|
memory_future = None
|
|
1271
1315
|
# 4. Start memory creation in background thread if memory manager is enabled and agentic memory is disabled
|
|
1272
|
-
if
|
|
1316
|
+
if (
|
|
1317
|
+
run_messages.user_message is not None
|
|
1318
|
+
and self.memory_manager is not None
|
|
1319
|
+
and self.enable_user_memories
|
|
1320
|
+
and not self.enable_agentic_memory
|
|
1321
|
+
):
|
|
1273
1322
|
log_debug("Starting memory creation in background thread.")
|
|
1274
1323
|
memory_future = self.background_executor.submit(
|
|
1275
1324
|
self._make_memories, run_messages=run_messages, user_id=user_id
|
|
@@ -1414,7 +1463,7 @@ class Agent:
|
|
|
1414
1463
|
)
|
|
1415
1464
|
|
|
1416
1465
|
# 9. Create session summary
|
|
1417
|
-
if self.session_summary_manager is not None:
|
|
1466
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
1418
1467
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
1419
1468
|
session.upsert_run(run=run_response)
|
|
1420
1469
|
|
|
@@ -1493,6 +1542,8 @@ class Agent:
|
|
|
1493
1542
|
run_response=run_response, session=session, run_context=run_context, user_id=user_id
|
|
1494
1543
|
)
|
|
1495
1544
|
finally:
|
|
1545
|
+
# Always disconnect connectable tools
|
|
1546
|
+
self._disconnect_connectable_tools()
|
|
1496
1547
|
# Always clean up the run tracking
|
|
1497
1548
|
cleanup_run(run_response.run_id) # type: ignore
|
|
1498
1549
|
|
|
@@ -1512,7 +1563,6 @@ class Agent:
|
|
|
1512
1563
|
images: Optional[Sequence[Image]] = None,
|
|
1513
1564
|
videos: Optional[Sequence[Video]] = None,
|
|
1514
1565
|
files: Optional[Sequence[File]] = None,
|
|
1515
|
-
retries: Optional[int] = None,
|
|
1516
1566
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
1517
1567
|
add_history_to_context: Optional[bool] = None,
|
|
1518
1568
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -1540,7 +1590,6 @@ class Agent:
|
|
|
1540
1590
|
images: Optional[Sequence[Image]] = None,
|
|
1541
1591
|
videos: Optional[Sequence[Video]] = None,
|
|
1542
1592
|
files: Optional[Sequence[File]] = None,
|
|
1543
|
-
retries: Optional[int] = None,
|
|
1544
1593
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
1545
1594
|
add_history_to_context: Optional[bool] = None,
|
|
1546
1595
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -1569,7 +1618,6 @@ class Agent:
|
|
|
1569
1618
|
images: Optional[Sequence[Image]] = None,
|
|
1570
1619
|
videos: Optional[Sequence[Video]] = None,
|
|
1571
1620
|
files: Optional[Sequence[File]] = None,
|
|
1572
|
-
retries: Optional[int] = None,
|
|
1573
1621
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
1574
1622
|
add_history_to_context: Optional[bool] = None,
|
|
1575
1623
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -1672,159 +1720,163 @@ class Agent:
|
|
|
1672
1720
|
# output_schema parameter takes priority, even if run_context was provided
|
|
1673
1721
|
run_context.output_schema = output_schema
|
|
1674
1722
|
|
|
1675
|
-
#
|
|
1676
|
-
|
|
1677
|
-
self._resolve_run_dependencies(run_context=run_context)
|
|
1723
|
+
# Set up retry logic
|
|
1724
|
+
num_attempts = self.retries + 1
|
|
1678
1725
|
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
)
|
|
1682
|
-
add_session_state = (
|
|
1683
|
-
add_session_state_to_context
|
|
1684
|
-
if add_session_state_to_context is not None
|
|
1685
|
-
else self.add_session_state_to_context
|
|
1686
|
-
)
|
|
1687
|
-
add_history = add_history_to_context if add_history_to_context is not None else self.add_history_to_context
|
|
1726
|
+
for attempt in range(num_attempts):
|
|
1727
|
+
log_debug(f"Retrying Agent run {run_id}. Attempt {attempt + 1} of {num_attempts}...")
|
|
1688
1728
|
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1729
|
+
try:
|
|
1730
|
+
# Resolve dependencies
|
|
1731
|
+
if run_context.dependencies is not None:
|
|
1732
|
+
self._resolve_run_dependencies(run_context=run_context)
|
|
1733
|
+
|
|
1734
|
+
add_dependencies = (
|
|
1735
|
+
add_dependencies_to_context
|
|
1736
|
+
if add_dependencies_to_context is not None
|
|
1737
|
+
else self.add_dependencies_to_context
|
|
1738
|
+
)
|
|
1739
|
+
add_session_state = (
|
|
1740
|
+
add_session_state_to_context
|
|
1741
|
+
if add_session_state_to_context is not None
|
|
1742
|
+
else self.add_session_state_to_context
|
|
1743
|
+
)
|
|
1744
|
+
add_history = (
|
|
1745
|
+
add_history_to_context if add_history_to_context is not None else self.add_history_to_context
|
|
1746
|
+
)
|
|
1692
1747
|
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1748
|
+
# When filters are passed manually
|
|
1749
|
+
if self.knowledge_filters or knowledge_filters:
|
|
1750
|
+
run_context.knowledge_filters = self._get_effective_filters(knowledge_filters)
|
|
1696
1751
|
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
1701
|
-
DeprecationWarning,
|
|
1702
|
-
stacklevel=2,
|
|
1703
|
-
)
|
|
1704
|
-
stream_events = stream_events or stream_intermediate_steps
|
|
1752
|
+
# Use stream override value when necessary
|
|
1753
|
+
if stream is None:
|
|
1754
|
+
stream = False if self.stream is None else self.stream
|
|
1705
1755
|
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1756
|
+
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
1757
|
+
if stream_intermediate_steps is not None:
|
|
1758
|
+
warnings.warn(
|
|
1759
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
1760
|
+
DeprecationWarning,
|
|
1761
|
+
stacklevel=2,
|
|
1762
|
+
)
|
|
1763
|
+
stream_events = stream_events or stream_intermediate_steps
|
|
1712
1764
|
|
|
1713
|
-
|
|
1714
|
-
|
|
1765
|
+
# Can't stream events if streaming is disabled
|
|
1766
|
+
if stream is False:
|
|
1767
|
+
stream_events = False
|
|
1715
1768
|
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
self.model = cast(Model, self.model)
|
|
1769
|
+
if stream_events is None:
|
|
1770
|
+
stream_events = False if self.stream_events is None else self.stream_events
|
|
1719
1771
|
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
merge_dictionaries(metadata, self.metadata)
|
|
1772
|
+
self.stream = self.stream or stream
|
|
1773
|
+
self.stream_events = self.stream_events or stream_events
|
|
1723
1774
|
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
user_id=user_id,
|
|
1730
|
-
agent_name=self.name,
|
|
1731
|
-
metadata=run_context.metadata,
|
|
1732
|
-
session_state=run_context.session_state,
|
|
1733
|
-
input=run_input,
|
|
1734
|
-
)
|
|
1775
|
+
# Prepare arguments for the model
|
|
1776
|
+
response_format = (
|
|
1777
|
+
self._get_response_format(run_context=run_context) if self.parser_model is None else None
|
|
1778
|
+
)
|
|
1779
|
+
self.model = cast(Model, self.model)
|
|
1735
1780
|
|
|
1736
|
-
|
|
1737
|
-
|
|
1781
|
+
# Merge agent metadata with run metadata
|
|
1782
|
+
if self.metadata is not None and metadata is not None:
|
|
1783
|
+
merge_dictionaries(metadata, self.metadata)
|
|
1738
1784
|
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1785
|
+
# Create a new run_response for this attempt
|
|
1786
|
+
run_response = RunOutput(
|
|
1787
|
+
run_id=run_id,
|
|
1788
|
+
session_id=session_id,
|
|
1789
|
+
agent_id=self.id,
|
|
1790
|
+
user_id=user_id,
|
|
1791
|
+
agent_name=self.name,
|
|
1792
|
+
metadata=run_context.metadata,
|
|
1793
|
+
session_state=run_context.session_state,
|
|
1794
|
+
input=run_input,
|
|
1795
|
+
)
|
|
1742
1796
|
|
|
1743
|
-
|
|
1744
|
-
|
|
1797
|
+
run_response.model = self.model.id if self.model is not None else None
|
|
1798
|
+
run_response.model_provider = self.model.provider if self.model is not None else None
|
|
1745
1799
|
|
|
1746
|
-
|
|
1747
|
-
|
|
1800
|
+
# Start the run metrics timer, to calculate the run duration
|
|
1801
|
+
run_response.metrics = Metrics()
|
|
1802
|
+
run_response.metrics.start_timer()
|
|
1748
1803
|
|
|
1749
|
-
|
|
1804
|
+
yield_run_output = yield_run_output or yield_run_response # For backwards compatibility
|
|
1750
1805
|
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
return response_iterator
|
|
1770
|
-
else:
|
|
1771
|
-
response = self._run(
|
|
1772
|
-
run_response=run_response,
|
|
1773
|
-
run_context=run_context,
|
|
1774
|
-
session=agent_session,
|
|
1775
|
-
user_id=user_id,
|
|
1776
|
-
add_history_to_context=add_history,
|
|
1777
|
-
add_dependencies_to_context=add_dependencies,
|
|
1778
|
-
add_session_state_to_context=add_session_state,
|
|
1779
|
-
response_format=response_format,
|
|
1780
|
-
debug_mode=debug_mode,
|
|
1781
|
-
background_tasks=background_tasks,
|
|
1782
|
-
**kwargs,
|
|
1783
|
-
)
|
|
1784
|
-
return response
|
|
1785
|
-
except (InputCheckError, OutputCheckError) as e:
|
|
1786
|
-
log_error(f"Validation failed: {str(e)} | Check: {e.check_trigger}")
|
|
1787
|
-
raise e
|
|
1788
|
-
except ModelProviderError as e:
|
|
1789
|
-
log_warning(f"Attempt {attempt + 1}/{num_attempts} failed: {str(e)}")
|
|
1790
|
-
if isinstance(e, StopAgentRun):
|
|
1791
|
-
raise e
|
|
1792
|
-
last_exception = e
|
|
1793
|
-
if attempt < num_attempts - 1: # Don't sleep on the last attempt
|
|
1794
|
-
if self.exponential_backoff:
|
|
1795
|
-
delay = 2**attempt * self.delay_between_retries
|
|
1806
|
+
try:
|
|
1807
|
+
if stream:
|
|
1808
|
+
response_iterator = self._run_stream(
|
|
1809
|
+
run_response=run_response,
|
|
1810
|
+
run_context=run_context,
|
|
1811
|
+
session=agent_session,
|
|
1812
|
+
user_id=user_id,
|
|
1813
|
+
add_history_to_context=add_history,
|
|
1814
|
+
add_dependencies_to_context=add_dependencies,
|
|
1815
|
+
add_session_state_to_context=add_session_state,
|
|
1816
|
+
response_format=response_format,
|
|
1817
|
+
stream_events=stream_events,
|
|
1818
|
+
yield_run_output=yield_run_output,
|
|
1819
|
+
debug_mode=debug_mode,
|
|
1820
|
+
background_tasks=background_tasks,
|
|
1821
|
+
**kwargs,
|
|
1822
|
+
)
|
|
1823
|
+
return response_iterator
|
|
1796
1824
|
else:
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
reason="Operation cancelled by user",
|
|
1825
|
+
response = self._run(
|
|
1826
|
+
run_response=run_response,
|
|
1827
|
+
run_context=run_context,
|
|
1828
|
+
session=agent_session,
|
|
1829
|
+
user_id=user_id,
|
|
1830
|
+
add_history_to_context=add_history,
|
|
1831
|
+
add_dependencies_to_context=add_dependencies,
|
|
1832
|
+
add_session_state_to_context=add_session_state,
|
|
1833
|
+
response_format=response_format,
|
|
1834
|
+
debug_mode=debug_mode,
|
|
1835
|
+
background_tasks=background_tasks,
|
|
1836
|
+
**kwargs,
|
|
1810
1837
|
)
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1838
|
+
return response
|
|
1839
|
+
except (InputCheckError, OutputCheckError) as e:
|
|
1840
|
+
log_error(f"Validation failed: {str(e)} | Check: {e.check_trigger}")
|
|
1841
|
+
raise e
|
|
1842
|
+
except KeyboardInterrupt:
|
|
1843
|
+
run_response.content = "Operation cancelled by user"
|
|
1844
|
+
run_response.status = RunStatus.cancelled
|
|
1814
1845
|
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1846
|
+
if stream:
|
|
1847
|
+
return generator_wrapper( # type: ignore
|
|
1848
|
+
create_run_cancelled_event(
|
|
1849
|
+
from_run_response=run_response,
|
|
1850
|
+
reason="Operation cancelled by user",
|
|
1851
|
+
)
|
|
1852
|
+
)
|
|
1853
|
+
else:
|
|
1854
|
+
return run_response
|
|
1855
|
+
except Exception as e:
|
|
1856
|
+
# Check if this is the last attempt
|
|
1857
|
+
if attempt < num_attempts - 1:
|
|
1858
|
+
# Calculate delay with exponential backoff if enabled
|
|
1859
|
+
if self.exponential_backoff:
|
|
1860
|
+
delay = self.delay_between_retries * (2**attempt)
|
|
1861
|
+
else:
|
|
1862
|
+
delay = self.delay_between_retries
|
|
1863
|
+
|
|
1864
|
+
log_warning(f"Attempt {attempt + 1}/{num_attempts} failed: {str(e)}. Retrying in {delay}s...")
|
|
1865
|
+
time.sleep(delay)
|
|
1866
|
+
continue
|
|
1867
|
+
else:
|
|
1868
|
+
# Final attempt failed - re-raise the exception
|
|
1869
|
+
log_error(f"All {num_attempts} attempts failed. Final error: {str(e)}")
|
|
1870
|
+
raise
|
|
1871
|
+
except Exception as e:
|
|
1872
|
+
log_error(f"Unexpected error: {str(e)}")
|
|
1873
|
+
if attempt == num_attempts - 1:
|
|
1874
|
+
if stream:
|
|
1875
|
+
return generator_wrapper(create_run_error_event(run_response, error=str(e))) # type: ignore
|
|
1876
|
+
raise e
|
|
1822
1877
|
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
if stream:
|
|
1826
|
-
return generator_wrapper(create_run_error_event(run_response, error=str(last_exception))) # type: ignore
|
|
1827
|
-
raise Exception(f"Failed after {num_attempts} attempts.")
|
|
1878
|
+
# If we get here, all retries failed (shouldn't happen with current logic)
|
|
1879
|
+
raise Exception(f"Failed after {num_attempts} attempts.")
|
|
1828
1880
|
|
|
1829
1881
|
async def _arun(
|
|
1830
1882
|
self,
|
|
@@ -1943,7 +1995,12 @@ class Agent:
|
|
|
1943
1995
|
|
|
1944
1996
|
# 7. Start memory creation as a background task (runs concurrently with the main execution)
|
|
1945
1997
|
memory_task = None
|
|
1946
|
-
if
|
|
1998
|
+
if (
|
|
1999
|
+
run_messages.user_message is not None
|
|
2000
|
+
and self.memory_manager is not None
|
|
2001
|
+
and self.enable_user_memories
|
|
2002
|
+
and not self.enable_agentic_memory
|
|
2003
|
+
):
|
|
1947
2004
|
log_debug("Starting memory creation in background task.")
|
|
1948
2005
|
memory_task = create_task(self._amake_memories(run_messages=run_messages, user_id=user_id))
|
|
1949
2006
|
|
|
@@ -2033,7 +2090,7 @@ class Agent:
|
|
|
2033
2090
|
await await_for_open_threads(memory_task=memory_task, cultural_knowledge_task=cultural_knowledge_task)
|
|
2034
2091
|
|
|
2035
2092
|
# 15. Create session summary
|
|
2036
|
-
if self.session_summary_manager is not None:
|
|
2093
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
2037
2094
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
2038
2095
|
agent_session.upsert_run(run=run_response)
|
|
2039
2096
|
try:
|
|
@@ -2075,6 +2132,8 @@ class Agent:
|
|
|
2075
2132
|
return run_response
|
|
2076
2133
|
|
|
2077
2134
|
finally:
|
|
2135
|
+
# Always disconnect connectable tools
|
|
2136
|
+
self._disconnect_connectable_tools()
|
|
2078
2137
|
# Always disconnect MCP tools
|
|
2079
2138
|
await self._disconnect_mcp_tools()
|
|
2080
2139
|
|
|
@@ -2221,7 +2280,12 @@ class Agent:
|
|
|
2221
2280
|
|
|
2222
2281
|
# 7. Start memory creation as a background task (runs concurrently with the main execution)
|
|
2223
2282
|
memory_task = None
|
|
2224
|
-
if
|
|
2283
|
+
if (
|
|
2284
|
+
run_messages.user_message is not None
|
|
2285
|
+
and self.memory_manager is not None
|
|
2286
|
+
and self.enable_user_memories
|
|
2287
|
+
and not self.enable_agentic_memory
|
|
2288
|
+
):
|
|
2225
2289
|
log_debug("Starting memory creation in background task.")
|
|
2226
2290
|
memory_task = create_task(self._amake_memories(run_messages=run_messages, user_id=user_id))
|
|
2227
2291
|
|
|
@@ -2357,7 +2421,7 @@ class Agent:
|
|
|
2357
2421
|
yield item
|
|
2358
2422
|
|
|
2359
2423
|
# 12. Create session summary
|
|
2360
|
-
if self.session_summary_manager is not None:
|
|
2424
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
2361
2425
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
2362
2426
|
agent_session.upsert_run(run=run_response)
|
|
2363
2427
|
|
|
@@ -2442,6 +2506,8 @@ class Agent:
|
|
|
2442
2506
|
user_id=user_id,
|
|
2443
2507
|
)
|
|
2444
2508
|
finally:
|
|
2509
|
+
# Always disconnect connectable tools
|
|
2510
|
+
self._disconnect_connectable_tools()
|
|
2445
2511
|
# Always disconnect MCP tools
|
|
2446
2512
|
await self._disconnect_mcp_tools()
|
|
2447
2513
|
|
|
@@ -2479,7 +2545,6 @@ class Agent:
|
|
|
2479
2545
|
files: Optional[Sequence[File]] = None,
|
|
2480
2546
|
stream_events: Optional[bool] = None,
|
|
2481
2547
|
stream_intermediate_steps: Optional[bool] = None,
|
|
2482
|
-
retries: Optional[int] = None,
|
|
2483
2548
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
2484
2549
|
add_history_to_context: Optional[bool] = None,
|
|
2485
2550
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -2506,7 +2571,6 @@ class Agent:
|
|
|
2506
2571
|
files: Optional[Sequence[File]] = None,
|
|
2507
2572
|
stream_events: Optional[bool] = None,
|
|
2508
2573
|
stream_intermediate_steps: Optional[bool] = None,
|
|
2509
|
-
retries: Optional[int] = None,
|
|
2510
2574
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
2511
2575
|
add_history_to_context: Optional[bool] = None,
|
|
2512
2576
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -2535,7 +2599,6 @@ class Agent:
|
|
|
2535
2599
|
files: Optional[Sequence[File]] = None,
|
|
2536
2600
|
stream_events: Optional[bool] = None,
|
|
2537
2601
|
stream_intermediate_steps: Optional[bool] = None,
|
|
2538
|
-
retries: Optional[int] = None,
|
|
2539
2602
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
2540
2603
|
add_history_to_context: Optional[bool] = None,
|
|
2541
2604
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -2672,9 +2735,6 @@ class Agent:
|
|
|
2672
2735
|
# Prepare arguments for the model (must be after run_context is fully initialized)
|
|
2673
2736
|
response_format = self._get_response_format(run_context=run_context) if self.parser_model is None else None
|
|
2674
2737
|
|
|
2675
|
-
# If no retries are set, use the agent's default retries
|
|
2676
|
-
retries = retries if retries is not None else self.retries
|
|
2677
|
-
|
|
2678
2738
|
# Create a new run_response for this attempt
|
|
2679
2739
|
run_response = RunOutput(
|
|
2680
2740
|
run_id=run_id,
|
|
@@ -2694,12 +2754,13 @@ class Agent:
|
|
|
2694
2754
|
run_response.metrics = Metrics()
|
|
2695
2755
|
run_response.metrics.start_timer()
|
|
2696
2756
|
|
|
2697
|
-
last_exception = None
|
|
2698
|
-
num_attempts = retries + 1
|
|
2699
|
-
|
|
2700
2757
|
yield_run_output = yield_run_output or yield_run_response # For backwards compatibility
|
|
2701
2758
|
|
|
2759
|
+
# Set up retry logic
|
|
2760
|
+
num_attempts = self.retries + 1
|
|
2761
|
+
|
|
2702
2762
|
for attempt in range(num_attempts):
|
|
2763
|
+
log_debug(f"Retrying Agent run {run_id}. Attempt {attempt + 1} of {num_attempts}...")
|
|
2703
2764
|
try:
|
|
2704
2765
|
# Pass the new run_response to _arun
|
|
2705
2766
|
if stream:
|
|
@@ -2732,23 +2793,9 @@ class Agent:
|
|
|
2732
2793
|
background_tasks=background_tasks,
|
|
2733
2794
|
**kwargs,
|
|
2734
2795
|
)
|
|
2735
|
-
|
|
2736
2796
|
except (InputCheckError, OutputCheckError) as e:
|
|
2737
2797
|
log_error(f"Validation failed: {str(e)} | Check trigger: {e.check_trigger}")
|
|
2738
2798
|
raise e
|
|
2739
|
-
except ModelProviderError as e:
|
|
2740
|
-
log_warning(f"Attempt {attempt + 1}/{num_attempts} failed: {str(e)}")
|
|
2741
|
-
if isinstance(e, StopAgentRun):
|
|
2742
|
-
raise e
|
|
2743
|
-
last_exception = e
|
|
2744
|
-
if attempt < num_attempts - 1: # Don't sleep on the last attempt
|
|
2745
|
-
if self.exponential_backoff:
|
|
2746
|
-
delay = 2**attempt * self.delay_between_retries
|
|
2747
|
-
else:
|
|
2748
|
-
delay = self.delay_between_retries
|
|
2749
|
-
import time
|
|
2750
|
-
|
|
2751
|
-
time.sleep(delay)
|
|
2752
2799
|
except KeyboardInterrupt:
|
|
2753
2800
|
run_response.content = "Operation cancelled by user"
|
|
2754
2801
|
run_response.status = RunStatus.cancelled
|
|
@@ -2762,20 +2809,27 @@ class Agent:
|
|
|
2762
2809
|
)
|
|
2763
2810
|
else:
|
|
2764
2811
|
return run_response
|
|
2812
|
+
except Exception as e:
|
|
2813
|
+
# Check if this is the last attempt
|
|
2814
|
+
if attempt < num_attempts - 1:
|
|
2815
|
+
# Calculate delay with exponential backoff if enabled
|
|
2816
|
+
if self.exponential_backoff:
|
|
2817
|
+
delay = self.delay_between_retries * (2**attempt)
|
|
2818
|
+
else:
|
|
2819
|
+
delay = self.delay_between_retries
|
|
2765
2820
|
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2821
|
+
log_warning(f"Attempt {attempt + 1}/{num_attempts} failed: {str(e)}. Retrying in {delay}s...")
|
|
2822
|
+
time.sleep(delay)
|
|
2823
|
+
continue
|
|
2824
|
+
else:
|
|
2825
|
+
# Final attempt failed - re-raise the exception
|
|
2826
|
+
log_error(f"All {num_attempts} attempts failed. Final error: {str(e)}")
|
|
2827
|
+
if stream:
|
|
2828
|
+
return async_generator_wrapper(create_run_error_event(run_response, error=str(e))) # type: ignore
|
|
2829
|
+
raise e
|
|
2771
2830
|
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
raise last_exception
|
|
2775
|
-
else:
|
|
2776
|
-
if stream:
|
|
2777
|
-
return async_generator_wrapper(create_run_error_event(run_response, error=str(last_exception))) # type: ignore
|
|
2778
|
-
raise Exception(f"Failed after {num_attempts} attempts.")
|
|
2831
|
+
# If we get here, all retries failed
|
|
2832
|
+
raise Exception(f"Failed after {num_attempts} attempts.")
|
|
2779
2833
|
|
|
2780
2834
|
@overload
|
|
2781
2835
|
def continue_run(
|
|
@@ -2784,16 +2838,17 @@ class Agent:
|
|
|
2784
2838
|
*,
|
|
2785
2839
|
run_id: Optional[str] = None,
|
|
2786
2840
|
updated_tools: Optional[List[ToolExecution]] = None,
|
|
2841
|
+
requirements: Optional[List[RunRequirement]] = None,
|
|
2787
2842
|
stream: Literal[False] = False,
|
|
2788
2843
|
stream_events: Optional[bool] = None,
|
|
2789
2844
|
stream_intermediate_steps: Optional[bool] = None,
|
|
2790
2845
|
user_id: Optional[str] = None,
|
|
2791
2846
|
session_id: Optional[str] = None,
|
|
2792
|
-
retries: Optional[int] = None,
|
|
2793
2847
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
2794
2848
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
2795
2849
|
metadata: Optional[Dict[str, Any]] = None,
|
|
2796
2850
|
debug_mode: Optional[bool] = None,
|
|
2851
|
+
yield_run_output: bool = False,
|
|
2797
2852
|
) -> RunOutput: ...
|
|
2798
2853
|
|
|
2799
2854
|
@overload
|
|
@@ -2803,16 +2858,17 @@ class Agent:
|
|
|
2803
2858
|
*,
|
|
2804
2859
|
run_id: Optional[str] = None,
|
|
2805
2860
|
updated_tools: Optional[List[ToolExecution]] = None,
|
|
2861
|
+
requirements: Optional[List[RunRequirement]] = None,
|
|
2806
2862
|
stream: Literal[True] = True,
|
|
2807
2863
|
stream_events: Optional[bool] = False,
|
|
2808
2864
|
stream_intermediate_steps: Optional[bool] = None,
|
|
2809
2865
|
user_id: Optional[str] = None,
|
|
2810
2866
|
session_id: Optional[str] = None,
|
|
2811
|
-
retries: Optional[int] = None,
|
|
2812
2867
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
2813
2868
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
2814
2869
|
metadata: Optional[Dict[str, Any]] = None,
|
|
2815
2870
|
debug_mode: Optional[bool] = None,
|
|
2871
|
+
yield_run_output: bool = False,
|
|
2816
2872
|
) -> Iterator[RunOutputEvent]: ...
|
|
2817
2873
|
|
|
2818
2874
|
def continue_run(
|
|
@@ -2821,36 +2877,37 @@ class Agent:
|
|
|
2821
2877
|
*,
|
|
2822
2878
|
run_id: Optional[str] = None, # type: ignore
|
|
2823
2879
|
updated_tools: Optional[List[ToolExecution]] = None,
|
|
2880
|
+
requirements: Optional[List[RunRequirement]] = None,
|
|
2824
2881
|
stream: Optional[bool] = None,
|
|
2825
2882
|
stream_events: Optional[bool] = False,
|
|
2826
2883
|
stream_intermediate_steps: Optional[bool] = None,
|
|
2827
2884
|
user_id: Optional[str] = None,
|
|
2828
2885
|
session_id: Optional[str] = None,
|
|
2829
2886
|
run_context: Optional[RunContext] = None,
|
|
2830
|
-
retries: Optional[int] = None,
|
|
2831
2887
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
2832
2888
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
2833
2889
|
metadata: Optional[Dict[str, Any]] = None,
|
|
2834
2890
|
debug_mode: Optional[bool] = None,
|
|
2891
|
+
yield_run_output: bool = False,
|
|
2835
2892
|
**kwargs,
|
|
2836
|
-
) -> Union[RunOutput, Iterator[RunOutputEvent]]:
|
|
2893
|
+
) -> Union[RunOutput, Iterator[Union[RunOutputEvent, RunOutput]]]:
|
|
2837
2894
|
"""Continue a previous run.
|
|
2838
2895
|
|
|
2839
2896
|
Args:
|
|
2840
2897
|
run_response: The run response to continue.
|
|
2841
2898
|
run_id: The run id to continue. Alternative to passing run_response.
|
|
2842
|
-
|
|
2899
|
+
requirements: The requirements to continue the run. This or updated_tools is required with `run_id`.
|
|
2843
2900
|
stream: Whether to stream the response.
|
|
2844
2901
|
stream_events: Whether to stream all events.
|
|
2845
2902
|
user_id: The user id to continue the run for.
|
|
2846
2903
|
session_id: The session id to continue the run for.
|
|
2847
2904
|
run_context: The run context to use for the run.
|
|
2848
|
-
retries: The number of retries to continue the run for.
|
|
2849
2905
|
knowledge_filters: The knowledge filters to use for the run.
|
|
2850
2906
|
dependencies: The dependencies to use for the run.
|
|
2851
2907
|
metadata: The metadata to use for the run.
|
|
2852
2908
|
debug_mode: Whether to enable debug mode.
|
|
2853
2909
|
(deprecated) stream_intermediate_steps: Whether to stream all steps.
|
|
2910
|
+
(deprecated) updated_tools: Use 'requirements' instead.
|
|
2854
2911
|
"""
|
|
2855
2912
|
if run_response is None and run_id is None:
|
|
2856
2913
|
raise ValueError("Either run_response or run_id must be provided.")
|
|
@@ -2899,106 +2956,129 @@ class Agent:
|
|
|
2899
2956
|
dependencies=dependencies,
|
|
2900
2957
|
)
|
|
2901
2958
|
|
|
2902
|
-
# Resolve
|
|
2903
|
-
|
|
2904
|
-
self._resolve_run_dependencies(run_context=run_context)
|
|
2905
|
-
|
|
2906
|
-
# When filters are passed manually
|
|
2907
|
-
if self.knowledge_filters or run_context.knowledge_filters or knowledge_filters:
|
|
2908
|
-
run_context.knowledge_filters = self._get_effective_filters(knowledge_filters)
|
|
2909
|
-
|
|
2910
|
-
# Merge agent metadata with run metadata
|
|
2911
|
-
run_context.metadata = metadata
|
|
2912
|
-
if self.metadata is not None:
|
|
2913
|
-
if run_context.metadata is None:
|
|
2914
|
-
run_context.metadata = self.metadata
|
|
2915
|
-
else:
|
|
2916
|
-
merge_dictionaries(run_context.metadata, self.metadata)
|
|
2917
|
-
|
|
2918
|
-
# If no retries are set, use the agent's default retries
|
|
2919
|
-
retries = retries if retries is not None else self.retries
|
|
2920
|
-
|
|
2921
|
-
# Use stream override value when necessary
|
|
2922
|
-
if stream is None:
|
|
2923
|
-
stream = False if self.stream is None else self.stream
|
|
2924
|
-
|
|
2925
|
-
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
2926
|
-
if stream_intermediate_steps is not None:
|
|
2927
|
-
warnings.warn(
|
|
2928
|
-
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
2929
|
-
DeprecationWarning,
|
|
2930
|
-
stacklevel=2,
|
|
2931
|
-
)
|
|
2932
|
-
stream_events = stream_events or stream_intermediate_steps
|
|
2933
|
-
|
|
2934
|
-
# Can't stream events if streaming is disabled
|
|
2935
|
-
if stream is False:
|
|
2936
|
-
stream_events = False
|
|
2959
|
+
# Resolve retry parameters
|
|
2960
|
+
num_attempts = self.retries + 1
|
|
2937
2961
|
|
|
2938
|
-
|
|
2939
|
-
|
|
2962
|
+
for attempt in range(num_attempts):
|
|
2963
|
+
log_debug(f"Retrying Agent continue_run {run_id}. Attempt {attempt + 1} of {num_attempts}...")
|
|
2940
2964
|
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2965
|
+
try:
|
|
2966
|
+
# Resolve dependencies
|
|
2967
|
+
if run_context.dependencies is not None:
|
|
2968
|
+
self._resolve_run_dependencies(run_context=run_context)
|
|
2969
|
+
|
|
2970
|
+
# When filters are passed manually
|
|
2971
|
+
if self.knowledge_filters or run_context.knowledge_filters or knowledge_filters:
|
|
2972
|
+
run_context.knowledge_filters = self._get_effective_filters(knowledge_filters)
|
|
2973
|
+
|
|
2974
|
+
# Merge agent metadata with run metadata
|
|
2975
|
+
run_context.metadata = metadata
|
|
2976
|
+
if self.metadata is not None:
|
|
2977
|
+
if run_context.metadata is None:
|
|
2978
|
+
run_context.metadata = self.metadata
|
|
2979
|
+
else:
|
|
2980
|
+
merge_dictionaries(run_context.metadata, self.metadata)
|
|
2981
|
+
|
|
2982
|
+
# Use stream override value when necessary
|
|
2983
|
+
if stream is None:
|
|
2984
|
+
stream = False if self.stream is None else self.stream
|
|
2985
|
+
|
|
2986
|
+
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
2987
|
+
if stream_intermediate_steps is not None:
|
|
2988
|
+
warnings.warn(
|
|
2989
|
+
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
2990
|
+
DeprecationWarning,
|
|
2991
|
+
stacklevel=2,
|
|
2992
|
+
)
|
|
2993
|
+
stream_events = stream_events or stream_intermediate_steps
|
|
2994
|
+
|
|
2995
|
+
# Can't stream events if streaming is disabled
|
|
2996
|
+
if stream is False:
|
|
2997
|
+
stream_events = False
|
|
2998
|
+
|
|
2999
|
+
if stream_events is None:
|
|
3000
|
+
stream_events = False if self.stream_events is None else self.stream_events
|
|
3001
|
+
|
|
3002
|
+
# Can't stream events if streaming is disabled
|
|
3003
|
+
if stream is False:
|
|
3004
|
+
stream_events = False
|
|
3005
|
+
|
|
3006
|
+
self.stream = self.stream or stream
|
|
3007
|
+
self.stream_events = self.stream_events or stream_events
|
|
3008
|
+
|
|
3009
|
+
# Run can be continued from previous run response or from passed run_response context
|
|
3010
|
+
if run_response is not None:
|
|
3011
|
+
# The run is continued from a provided run_response. This contains the updated tools.
|
|
3012
|
+
input = run_response.messages or []
|
|
3013
|
+
elif run_id is not None:
|
|
3014
|
+
# The run is continued from a run_id, one of requirements or updated_tool (deprecated) is required.
|
|
3015
|
+
if updated_tools is None and requirements is None:
|
|
3016
|
+
raise ValueError(
|
|
3017
|
+
"To continue a run from a given run_id, the requirements parameter must be provided."
|
|
3018
|
+
)
|
|
2944
3019
|
|
|
2945
|
-
|
|
2946
|
-
|
|
3020
|
+
runs = agent_session.runs
|
|
3021
|
+
run_response = next((r for r in runs if r.run_id == run_id), None) # type: ignore
|
|
3022
|
+
if run_response is None:
|
|
3023
|
+
raise RuntimeError(f"No runs found for run ID {run_id}")
|
|
2947
3024
|
|
|
2948
|
-
|
|
2949
|
-
if run_response is not None:
|
|
2950
|
-
# The run is continued from a provided run_response. This contains the updated tools.
|
|
2951
|
-
input = run_response.messages or []
|
|
2952
|
-
elif run_id is not None:
|
|
2953
|
-
# The run is continued from a run_id. This requires the updated tools to be passed.
|
|
2954
|
-
if updated_tools is None:
|
|
2955
|
-
raise ValueError("Updated tools are required to continue a run from a run_id.")
|
|
3025
|
+
input = run_response.messages or []
|
|
2956
3026
|
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
3027
|
+
# If we have updated_tools, set them in the run_response
|
|
3028
|
+
if updated_tools is not None:
|
|
3029
|
+
warnings.warn(
|
|
3030
|
+
"The 'updated_tools' parameter is deprecated and will be removed in future versions. Use 'requirements' instead.",
|
|
3031
|
+
DeprecationWarning,
|
|
3032
|
+
stacklevel=2,
|
|
3033
|
+
)
|
|
3034
|
+
run_response.tools = updated_tools
|
|
3035
|
+
|
|
3036
|
+
# If we have requirements, get the updated tools and set them in the run_response
|
|
3037
|
+
elif requirements is not None:
|
|
3038
|
+
run_response.requirements = requirements
|
|
3039
|
+
updated_tools = [req.tool_execution for req in requirements if req.tool_execution is not None]
|
|
3040
|
+
if updated_tools and run_response.tools:
|
|
3041
|
+
updated_tools_map = {tool.tool_call_id: tool for tool in updated_tools}
|
|
3042
|
+
run_response.tools = [
|
|
3043
|
+
updated_tools_map.get(tool.tool_call_id, tool) for tool in run_response.tools
|
|
3044
|
+
]
|
|
3045
|
+
else:
|
|
3046
|
+
run_response.tools = updated_tools
|
|
3047
|
+
else:
|
|
3048
|
+
raise ValueError("Either run_response or run_id must be provided.")
|
|
2965
3049
|
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
3050
|
+
# Prepare arguments for the model
|
|
3051
|
+
self._set_default_model()
|
|
3052
|
+
response_format = self._get_response_format(run_context=run_context)
|
|
3053
|
+
self.model = cast(Model, self.model)
|
|
2970
3054
|
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
3055
|
+
processed_tools = self.get_tools(
|
|
3056
|
+
run_response=run_response,
|
|
3057
|
+
run_context=run_context,
|
|
3058
|
+
session=agent_session,
|
|
3059
|
+
user_id=user_id,
|
|
3060
|
+
)
|
|
2977
3061
|
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
3062
|
+
_tools = self._determine_tools_for_model(
|
|
3063
|
+
model=self.model,
|
|
3064
|
+
processed_tools=processed_tools,
|
|
3065
|
+
run_response=run_response,
|
|
3066
|
+
run_context=run_context,
|
|
3067
|
+
session=agent_session,
|
|
3068
|
+
)
|
|
2985
3069
|
|
|
2986
|
-
|
|
2987
|
-
num_attempts = retries + 1
|
|
2988
|
-
for attempt in range(num_attempts):
|
|
2989
|
-
run_response = cast(RunOutput, run_response)
|
|
3070
|
+
run_response = cast(RunOutput, run_response)
|
|
2990
3071
|
|
|
2991
|
-
|
|
3072
|
+
log_debug(f"Agent Run Start: {run_response.run_id}", center=True)
|
|
2992
3073
|
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
3074
|
+
# Prepare run messages
|
|
3075
|
+
run_messages = self._get_continue_run_messages(
|
|
3076
|
+
input=input,
|
|
3077
|
+
)
|
|
2997
3078
|
|
|
2998
|
-
|
|
2999
|
-
|
|
3079
|
+
# Reset the run state
|
|
3080
|
+
run_response.status = RunStatus.running
|
|
3000
3081
|
|
|
3001
|
-
try:
|
|
3002
3082
|
if stream:
|
|
3003
3083
|
response_iterator = self._continue_run_stream(
|
|
3004
3084
|
run_response=run_response,
|
|
@@ -3009,6 +3089,7 @@ class Agent:
|
|
|
3009
3089
|
session=agent_session,
|
|
3010
3090
|
response_format=response_format,
|
|
3011
3091
|
stream_events=stream_events,
|
|
3092
|
+
yield_run_output=yield_run_output,
|
|
3012
3093
|
debug_mode=debug_mode,
|
|
3013
3094
|
background_tasks=background_tasks,
|
|
3014
3095
|
**kwargs,
|
|
@@ -3028,42 +3109,34 @@ class Agent:
|
|
|
3028
3109
|
**kwargs,
|
|
3029
3110
|
)
|
|
3030
3111
|
return response
|
|
3031
|
-
except
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3112
|
+
except KeyboardInterrupt:
|
|
3113
|
+
if stream:
|
|
3114
|
+
return generator_wrapper( # type: ignore
|
|
3115
|
+
create_run_cancelled_event(run_response, "Operation cancelled by user") # type: ignore
|
|
3116
|
+
)
|
|
3117
|
+
else:
|
|
3118
|
+
run_response.content = "Operation cancelled by user" # type: ignore
|
|
3119
|
+
run_response.status = RunStatus.cancelled # type: ignore
|
|
3120
|
+
return run_response # type: ignore
|
|
3121
|
+
except Exception as e:
|
|
3122
|
+
# Check if this is the last attempt
|
|
3123
|
+
if attempt < num_attempts - 1:
|
|
3124
|
+
# Calculate delay with exponential backoff if enabled
|
|
3037
3125
|
if self.exponential_backoff:
|
|
3038
|
-
delay = 2**attempt
|
|
3126
|
+
delay = self.delay_between_retries * (2**attempt)
|
|
3039
3127
|
else:
|
|
3040
3128
|
delay = self.delay_between_retries
|
|
3041
|
-
import time
|
|
3042
3129
|
|
|
3130
|
+
log_warning(f"Attempt {attempt + 1}/{num_attempts} failed: {str(e)}. Retrying in {delay}s...")
|
|
3043
3131
|
time.sleep(delay)
|
|
3044
|
-
|
|
3045
|
-
if stream:
|
|
3046
|
-
return generator_wrapper( # type: ignore
|
|
3047
|
-
create_run_cancelled_event(run_response, "Operation cancelled by user")
|
|
3048
|
-
)
|
|
3132
|
+
continue
|
|
3049
3133
|
else:
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3134
|
+
# Final attempt failed - re-raise the exception
|
|
3135
|
+
log_error(f"All {num_attempts} attempts failed. Final error: {str(e)}")
|
|
3136
|
+
raise
|
|
3053
3137
|
|
|
3054
3138
|
# If we get here, all retries failed
|
|
3055
|
-
|
|
3056
|
-
log_error(
|
|
3057
|
-
f"Failed after {num_attempts} attempts. Last error using {last_exception.model_name}({last_exception.model_id})"
|
|
3058
|
-
)
|
|
3059
|
-
|
|
3060
|
-
if stream:
|
|
3061
|
-
return generator_wrapper(create_run_error_event(run_response, error=str(last_exception))) # type: ignore
|
|
3062
|
-
raise last_exception
|
|
3063
|
-
else:
|
|
3064
|
-
if stream:
|
|
3065
|
-
return generator_wrapper(create_run_error_event(run_response, error=str(last_exception))) # type: ignore
|
|
3066
|
-
raise Exception(f"Failed after {num_attempts} attempts.")
|
|
3139
|
+
raise Exception(f"Failed after {num_attempts} attempts.")
|
|
3067
3140
|
|
|
3068
3141
|
def _continue_run(
|
|
3069
3142
|
self,
|
|
@@ -3148,7 +3221,7 @@ class Agent:
|
|
|
3148
3221
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
3149
3222
|
|
|
3150
3223
|
# 7. Create session summary
|
|
3151
|
-
if self.session_summary_manager is not None:
|
|
3224
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
3152
3225
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
3153
3226
|
session.upsert_run(run=run_response)
|
|
3154
3227
|
|
|
@@ -3182,6 +3255,8 @@ class Agent:
|
|
|
3182
3255
|
|
|
3183
3256
|
return run_response
|
|
3184
3257
|
finally:
|
|
3258
|
+
# Always disconnect connectable tools
|
|
3259
|
+
self._disconnect_connectable_tools()
|
|
3185
3260
|
# Always clean up the run tracking
|
|
3186
3261
|
cleanup_run(run_response.run_id) # type: ignore
|
|
3187
3262
|
|
|
@@ -3196,9 +3271,10 @@ class Agent:
|
|
|
3196
3271
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
3197
3272
|
stream_events: bool = False,
|
|
3198
3273
|
debug_mode: Optional[bool] = None,
|
|
3274
|
+
yield_run_output: bool = False,
|
|
3199
3275
|
background_tasks: Optional[Any] = None,
|
|
3200
3276
|
**kwargs,
|
|
3201
|
-
) -> Iterator[RunOutputEvent]:
|
|
3277
|
+
) -> Iterator[Union[RunOutputEvent, RunOutput]]:
|
|
3202
3278
|
"""Continue a previous run.
|
|
3203
3279
|
|
|
3204
3280
|
Steps:
|
|
@@ -3281,7 +3357,7 @@ class Agent:
|
|
|
3281
3357
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
3282
3358
|
|
|
3283
3359
|
# 4. Create session summary
|
|
3284
|
-
if self.session_summary_manager is not None:
|
|
3360
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
3285
3361
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
3286
3362
|
session.upsert_run(run=run_response)
|
|
3287
3363
|
|
|
@@ -3331,6 +3407,9 @@ class Agent:
|
|
|
3331
3407
|
if stream_events:
|
|
3332
3408
|
yield completed_event # type: ignore
|
|
3333
3409
|
|
|
3410
|
+
if yield_run_output:
|
|
3411
|
+
yield run_response
|
|
3412
|
+
|
|
3334
3413
|
# Log Agent Telemetry
|
|
3335
3414
|
self._log_agent_telemetry(session_id=session.session_id, run_id=run_response.run_id)
|
|
3336
3415
|
|
|
@@ -3355,6 +3434,8 @@ class Agent:
|
|
|
3355
3434
|
run_response=run_response, session=session, run_context=run_context, user_id=user_id
|
|
3356
3435
|
)
|
|
3357
3436
|
finally:
|
|
3437
|
+
# Always disconnect connectable tools
|
|
3438
|
+
self._disconnect_connectable_tools()
|
|
3358
3439
|
# Always clean up the run tracking
|
|
3359
3440
|
cleanup_run(run_response.run_id) # type: ignore
|
|
3360
3441
|
|
|
@@ -3368,9 +3449,9 @@ class Agent:
|
|
|
3368
3449
|
stream_intermediate_steps: Optional[bool] = None,
|
|
3369
3450
|
run_id: Optional[str] = None,
|
|
3370
3451
|
updated_tools: Optional[List[ToolExecution]] = None,
|
|
3452
|
+
requirements: Optional[List[RunRequirement]] = None,
|
|
3371
3453
|
user_id: Optional[str] = None,
|
|
3372
3454
|
session_id: Optional[str] = None,
|
|
3373
|
-
retries: Optional[int] = None,
|
|
3374
3455
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
3375
3456
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
3376
3457
|
metadata: Optional[Dict[str, Any]] = None,
|
|
@@ -3388,9 +3469,9 @@ class Agent:
|
|
|
3388
3469
|
stream_intermediate_steps: Optional[bool] = None,
|
|
3389
3470
|
run_id: Optional[str] = None,
|
|
3390
3471
|
updated_tools: Optional[List[ToolExecution]] = None,
|
|
3472
|
+
requirements: Optional[List[RunRequirement]] = None,
|
|
3391
3473
|
user_id: Optional[str] = None,
|
|
3392
3474
|
session_id: Optional[str] = None,
|
|
3393
|
-
retries: Optional[int] = None,
|
|
3394
3475
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
3395
3476
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
3396
3477
|
metadata: Optional[Dict[str, Any]] = None,
|
|
@@ -3404,13 +3485,13 @@ class Agent:
|
|
|
3404
3485
|
*,
|
|
3405
3486
|
run_id: Optional[str] = None, # type: ignore
|
|
3406
3487
|
updated_tools: Optional[List[ToolExecution]] = None,
|
|
3488
|
+
requirements: Optional[List[RunRequirement]] = None,
|
|
3407
3489
|
stream: Optional[bool] = None,
|
|
3408
3490
|
stream_events: Optional[bool] = None,
|
|
3409
3491
|
stream_intermediate_steps: Optional[bool] = None,
|
|
3410
3492
|
user_id: Optional[str] = None,
|
|
3411
3493
|
session_id: Optional[str] = None,
|
|
3412
3494
|
run_context: Optional[RunContext] = None,
|
|
3413
|
-
retries: Optional[int] = None,
|
|
3414
3495
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
3415
3496
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
3416
3497
|
metadata: Optional[Dict[str, Any]] = None,
|
|
@@ -3423,19 +3504,20 @@ class Agent:
|
|
|
3423
3504
|
Args:
|
|
3424
3505
|
run_response: The run response to continue.
|
|
3425
3506
|
run_id: The run id to continue. Alternative to passing run_response.
|
|
3426
|
-
|
|
3507
|
+
|
|
3508
|
+
requirements: The requirements to continue the run. This or updated_tools is required with `run_id`.
|
|
3427
3509
|
stream: Whether to stream the response.
|
|
3428
3510
|
stream_events: Whether to stream all events.
|
|
3429
3511
|
user_id: The user id to continue the run for.
|
|
3430
3512
|
session_id: The session id to continue the run for.
|
|
3431
3513
|
run_context: The run context to use for the run.
|
|
3432
|
-
retries: The number of retries to continue the run for.
|
|
3433
3514
|
knowledge_filters: The knowledge filters to use for the run.
|
|
3434
3515
|
dependencies: The dependencies to use for continuing the run.
|
|
3435
3516
|
metadata: The metadata to use for continuing the run.
|
|
3436
3517
|
debug_mode: Whether to enable debug mode.
|
|
3437
3518
|
yield_run_output: Whether to yield the run response.
|
|
3438
3519
|
(deprecated) stream_intermediate_steps: Whether to stream all steps.
|
|
3520
|
+
(deprecated) updated_tools: Use 'requirements' instead.
|
|
3439
3521
|
"""
|
|
3440
3522
|
if run_response is None and run_id is None:
|
|
3441
3523
|
raise ValueError("Either run_response or run_id must be provided.")
|
|
@@ -3443,6 +3525,12 @@ class Agent:
|
|
|
3443
3525
|
if run_response is None and (run_id is not None and (session_id is None and self.session_id is None)):
|
|
3444
3526
|
raise ValueError("Session ID is required to continue a run from a run_id.")
|
|
3445
3527
|
|
|
3528
|
+
if updated_tools is not None:
|
|
3529
|
+
warnings.warn(
|
|
3530
|
+
"The 'updated_tools' parameter is deprecated and will be removed in future versions. Use 'requirements' instead.",
|
|
3531
|
+
DeprecationWarning,
|
|
3532
|
+
stacklevel=2,
|
|
3533
|
+
)
|
|
3446
3534
|
background_tasks = kwargs.pop("background_tasks", None)
|
|
3447
3535
|
if background_tasks is not None:
|
|
3448
3536
|
from fastapi import BackgroundTasks
|
|
@@ -3460,9 +3548,6 @@ class Agent:
|
|
|
3460
3548
|
|
|
3461
3549
|
dependencies = dependencies if dependencies is not None else self.dependencies
|
|
3462
3550
|
|
|
3463
|
-
# If no retries are set, use the agent's default retries
|
|
3464
|
-
retries = retries if retries is not None else self.retries
|
|
3465
|
-
|
|
3466
3551
|
# Use stream override value when necessary
|
|
3467
3552
|
if stream is None:
|
|
3468
3553
|
stream = False if self.stream is None else self.stream
|
|
@@ -3502,6 +3587,9 @@ class Agent:
|
|
|
3502
3587
|
else:
|
|
3503
3588
|
merge_dictionaries(metadata, self.metadata)
|
|
3504
3589
|
|
|
3590
|
+
# Resolve retry parameters
|
|
3591
|
+
num_attempts = self.retries + 1
|
|
3592
|
+
|
|
3505
3593
|
# Prepare arguments for the model
|
|
3506
3594
|
response_format = self._get_response_format(run_context=run_context)
|
|
3507
3595
|
self.model = cast(Model, self.model)
|
|
@@ -3517,15 +3605,16 @@ class Agent:
|
|
|
3517
3605
|
metadata=metadata,
|
|
3518
3606
|
)
|
|
3519
3607
|
|
|
3520
|
-
last_exception = None
|
|
3521
|
-
num_attempts = retries + 1
|
|
3522
3608
|
for attempt in range(num_attempts):
|
|
3609
|
+
log_debug(f"Retrying Agent acontinue_run {run_id}. Attempt {attempt + 1} of {num_attempts}...")
|
|
3610
|
+
|
|
3523
3611
|
try:
|
|
3524
3612
|
if stream:
|
|
3525
3613
|
return self._acontinue_run_stream(
|
|
3526
3614
|
run_response=run_response,
|
|
3527
3615
|
run_context=run_context,
|
|
3528
3616
|
updated_tools=updated_tools,
|
|
3617
|
+
requirements=requirements,
|
|
3529
3618
|
run_id=run_id,
|
|
3530
3619
|
user_id=user_id,
|
|
3531
3620
|
session_id=session_id,
|
|
@@ -3542,6 +3631,7 @@ class Agent:
|
|
|
3542
3631
|
run_response=run_response,
|
|
3543
3632
|
run_context=run_context,
|
|
3544
3633
|
updated_tools=updated_tools,
|
|
3634
|
+
requirements=requirements,
|
|
3545
3635
|
run_id=run_id,
|
|
3546
3636
|
user_id=user_id,
|
|
3547
3637
|
response_format=response_format,
|
|
@@ -3549,19 +3639,6 @@ class Agent:
|
|
|
3549
3639
|
background_tasks=background_tasks,
|
|
3550
3640
|
**kwargs,
|
|
3551
3641
|
)
|
|
3552
|
-
except ModelProviderError as e:
|
|
3553
|
-
log_warning(f"Attempt {attempt + 1}/{num_attempts} failed: {str(e)}")
|
|
3554
|
-
if isinstance(e, StopAgentRun):
|
|
3555
|
-
raise e
|
|
3556
|
-
last_exception = e
|
|
3557
|
-
if attempt < num_attempts - 1: # Don't sleep on the last attempt
|
|
3558
|
-
if self.exponential_backoff:
|
|
3559
|
-
delay = 2**attempt * self.delay_between_retries
|
|
3560
|
-
else:
|
|
3561
|
-
delay = self.delay_between_retries
|
|
3562
|
-
import time
|
|
3563
|
-
|
|
3564
|
-
time.sleep(delay)
|
|
3565
3642
|
except KeyboardInterrupt:
|
|
3566
3643
|
run_response = cast(RunOutput, run_response)
|
|
3567
3644
|
if stream:
|
|
@@ -3572,19 +3649,25 @@ class Agent:
|
|
|
3572
3649
|
run_response.content = "Operation cancelled by user"
|
|
3573
3650
|
run_response.status = RunStatus.cancelled
|
|
3574
3651
|
return run_response
|
|
3652
|
+
except Exception as e:
|
|
3653
|
+
# Check if this is the last attempt
|
|
3654
|
+
if attempt < num_attempts - 1:
|
|
3655
|
+
# Calculate delay with exponential backoff if enabled
|
|
3656
|
+
if self.exponential_backoff:
|
|
3657
|
+
delay = self.delay_between_retries * (2**attempt)
|
|
3658
|
+
else:
|
|
3659
|
+
delay = self.delay_between_retries
|
|
3660
|
+
|
|
3661
|
+
log_warning(f"Attempt {attempt + 1}/{num_attempts} failed: {str(e)}. Retrying in {delay}s...")
|
|
3662
|
+
time.sleep(delay)
|
|
3663
|
+
continue
|
|
3664
|
+
else:
|
|
3665
|
+
# Final attempt failed - re-raise the exception
|
|
3666
|
+
log_error(f"All {num_attempts} attempts failed. Final error: {str(e)}")
|
|
3667
|
+
raise
|
|
3575
3668
|
|
|
3576
3669
|
# If we get here, all retries failed
|
|
3577
|
-
|
|
3578
|
-
log_error(
|
|
3579
|
-
f"Failed after {num_attempts} attempts. Last error using {last_exception.model_name}({last_exception.model_id})"
|
|
3580
|
-
)
|
|
3581
|
-
if stream:
|
|
3582
|
-
return async_generator_wrapper(create_run_error_event(run_response, error=str(last_exception))) # type: ignore
|
|
3583
|
-
raise last_exception
|
|
3584
|
-
else:
|
|
3585
|
-
if stream:
|
|
3586
|
-
return async_generator_wrapper(create_run_error_event(run_response, error=str(last_exception))) # type: ignore
|
|
3587
|
-
raise Exception(f"Failed after {num_attempts} attempts.")
|
|
3670
|
+
raise Exception(f"Failed after {num_attempts} attempts.")
|
|
3588
3671
|
|
|
3589
3672
|
async def _acontinue_run(
|
|
3590
3673
|
self,
|
|
@@ -3592,6 +3675,7 @@ class Agent:
|
|
|
3592
3675
|
run_context: RunContext,
|
|
3593
3676
|
run_response: Optional[RunOutput] = None,
|
|
3594
3677
|
updated_tools: Optional[List[ToolExecution]] = None,
|
|
3678
|
+
requirements: Optional[List[RunRequirement]] = None,
|
|
3595
3679
|
run_id: Optional[str] = None,
|
|
3596
3680
|
user_id: Optional[str] = None,
|
|
3597
3681
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
@@ -3644,15 +3728,29 @@ class Agent:
|
|
|
3644
3728
|
input = run_response.messages or []
|
|
3645
3729
|
elif run_id is not None:
|
|
3646
3730
|
# The run is continued from a run_id. This requires the updated tools to be passed.
|
|
3647
|
-
if updated_tools is None:
|
|
3648
|
-
raise ValueError("
|
|
3731
|
+
if updated_tools is None and requirements is None:
|
|
3732
|
+
raise ValueError("Either updated tools or requirements are required to continue a run from a run_id.")
|
|
3649
3733
|
|
|
3650
3734
|
runs = agent_session.runs
|
|
3651
3735
|
run_response = next((r for r in runs if r.run_id == run_id), None) # type: ignore
|
|
3652
3736
|
if run_response is None:
|
|
3653
3737
|
raise RuntimeError(f"No runs found for run ID {run_id}")
|
|
3654
|
-
|
|
3738
|
+
|
|
3655
3739
|
input = run_response.messages or []
|
|
3740
|
+
|
|
3741
|
+
# If we have updated_tools, set them in the run_response
|
|
3742
|
+
if updated_tools is not None:
|
|
3743
|
+
run_response.tools = updated_tools
|
|
3744
|
+
|
|
3745
|
+
# If we have requirements, get the updated tools and set them in the run_response
|
|
3746
|
+
elif requirements is not None:
|
|
3747
|
+
run_response.requirements = requirements
|
|
3748
|
+
updated_tools = [req.tool_execution for req in requirements if req.tool_execution is not None]
|
|
3749
|
+
if updated_tools and run_response.tools:
|
|
3750
|
+
updated_tools_map = {tool.tool_call_id: tool for tool in updated_tools}
|
|
3751
|
+
run_response.tools = [updated_tools_map.get(tool.tool_call_id, tool) for tool in run_response.tools]
|
|
3752
|
+
else:
|
|
3753
|
+
run_response.tools = updated_tools
|
|
3656
3754
|
else:
|
|
3657
3755
|
raise ValueError("Either run_response or run_id must be provided.")
|
|
3658
3756
|
|
|
@@ -3748,7 +3846,7 @@ class Agent:
|
|
|
3748
3846
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
3749
3847
|
|
|
3750
3848
|
# 13. Create session summary
|
|
3751
|
-
if self.session_summary_manager is not None:
|
|
3849
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
3752
3850
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
3753
3851
|
agent_session.upsert_run(run=run_response)
|
|
3754
3852
|
|
|
@@ -3791,6 +3889,8 @@ class Agent:
|
|
|
3791
3889
|
|
|
3792
3890
|
return run_response
|
|
3793
3891
|
finally:
|
|
3892
|
+
# Always disconnect connectable tools
|
|
3893
|
+
self._disconnect_connectable_tools()
|
|
3794
3894
|
# Always disconnect MCP tools
|
|
3795
3895
|
await self._disconnect_mcp_tools()
|
|
3796
3896
|
|
|
@@ -3803,6 +3903,7 @@ class Agent:
|
|
|
3803
3903
|
run_context: RunContext,
|
|
3804
3904
|
run_response: Optional[RunOutput] = None,
|
|
3805
3905
|
updated_tools: Optional[List[ToolExecution]] = None,
|
|
3906
|
+
requirements: Optional[List[RunRequirement]] = None,
|
|
3806
3907
|
run_id: Optional[str] = None,
|
|
3807
3908
|
user_id: Optional[str] = None,
|
|
3808
3909
|
response_format: Optional[Union[Dict, Type[BaseModel]]] = None,
|
|
@@ -3852,17 +3953,32 @@ class Agent:
|
|
|
3852
3953
|
if run_response is not None:
|
|
3853
3954
|
# The run is continued from a provided run_response. This contains the updated tools.
|
|
3854
3955
|
input = run_response.messages or []
|
|
3956
|
+
|
|
3855
3957
|
elif run_id is not None:
|
|
3856
|
-
# The run is continued from a run_id. This requires the updated tools to be passed.
|
|
3857
|
-
if updated_tools is None:
|
|
3858
|
-
raise ValueError("
|
|
3958
|
+
# The run is continued from a run_id. This requires the updated tools or requirements to be passed.
|
|
3959
|
+
if updated_tools is None and requirements is None:
|
|
3960
|
+
raise ValueError("Either updated tools or requirements are required to continue a run from a run_id.")
|
|
3859
3961
|
|
|
3860
3962
|
runs = agent_session.runs
|
|
3861
3963
|
run_response = next((r for r in runs if r.run_id == run_id), None) # type: ignore
|
|
3862
3964
|
if run_response is None:
|
|
3863
3965
|
raise RuntimeError(f"No runs found for run ID {run_id}")
|
|
3864
|
-
|
|
3966
|
+
|
|
3865
3967
|
input = run_response.messages or []
|
|
3968
|
+
|
|
3969
|
+
# If we have updated_tools, set them in the run_response
|
|
3970
|
+
if updated_tools is not None:
|
|
3971
|
+
run_response.tools = updated_tools
|
|
3972
|
+
|
|
3973
|
+
# If we have requirements, get the updated tools and set them in the run_response
|
|
3974
|
+
elif requirements is not None:
|
|
3975
|
+
run_response.requirements = requirements
|
|
3976
|
+
updated_tools = [req.tool_execution for req in requirements if req.tool_execution is not None]
|
|
3977
|
+
if updated_tools and run_response.tools:
|
|
3978
|
+
updated_tools_map = {tool.tool_call_id: tool for tool in updated_tools}
|
|
3979
|
+
run_response.tools = [updated_tools_map.get(tool.tool_call_id, tool) for tool in run_response.tools]
|
|
3980
|
+
else:
|
|
3981
|
+
run_response.tools = updated_tools
|
|
3866
3982
|
else:
|
|
3867
3983
|
raise ValueError("Either run_response or run_id must be provided.")
|
|
3868
3984
|
|
|
@@ -4003,7 +4119,7 @@ class Agent:
|
|
|
4003
4119
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
4004
4120
|
|
|
4005
4121
|
# 9. Create session summary
|
|
4006
|
-
if self.session_summary_manager is not None:
|
|
4122
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
4007
4123
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
4008
4124
|
agent_session.upsert_run(run=run_response)
|
|
4009
4125
|
|
|
@@ -4081,6 +4197,8 @@ class Agent:
|
|
|
4081
4197
|
user_id=user_id,
|
|
4082
4198
|
)
|
|
4083
4199
|
finally:
|
|
4200
|
+
# Always disconnect connectable tools
|
|
4201
|
+
self._disconnect_connectable_tools()
|
|
4084
4202
|
# Always disconnect MCP tools
|
|
4085
4203
|
await self._disconnect_mcp_tools()
|
|
4086
4204
|
|
|
@@ -4496,6 +4614,7 @@ class Agent:
|
|
|
4496
4614
|
create_run_paused_event(
|
|
4497
4615
|
from_run_response=run_response,
|
|
4498
4616
|
tools=run_response.tools,
|
|
4617
|
+
requirements=run_response.requirements,
|
|
4499
4618
|
),
|
|
4500
4619
|
run_response,
|
|
4501
4620
|
events_to_skip=self.events_to_skip, # type: ignore
|
|
@@ -4544,6 +4663,7 @@ class Agent:
|
|
|
4544
4663
|
create_run_paused_event(
|
|
4545
4664
|
from_run_response=run_response,
|
|
4546
4665
|
tools=run_response.tools,
|
|
4666
|
+
requirements=run_response.requirements,
|
|
4547
4667
|
),
|
|
4548
4668
|
run_response,
|
|
4549
4669
|
events_to_skip=self.events_to_skip, # type: ignore
|
|
@@ -5359,7 +5479,7 @@ class Agent:
|
|
|
5359
5479
|
run_response.images = []
|
|
5360
5480
|
run_response.images.append(image)
|
|
5361
5481
|
|
|
5362
|
-
# Handle tool interruption events
|
|
5482
|
+
# Handle tool interruption events (HITL flow)
|
|
5363
5483
|
elif model_response_event.event == ModelResponseEvent.tool_call_paused.value:
|
|
5364
5484
|
# Add tool calls to the run_response
|
|
5365
5485
|
tool_executions_list = model_response_event.tool_executions
|
|
@@ -5369,6 +5489,10 @@ class Agent:
|
|
|
5369
5489
|
run_response.tools = tool_executions_list
|
|
5370
5490
|
else:
|
|
5371
5491
|
run_response.tools.extend(tool_executions_list)
|
|
5492
|
+
# Add requirement to the run_response
|
|
5493
|
+
if run_response.requirements is None:
|
|
5494
|
+
run_response.requirements = []
|
|
5495
|
+
run_response.requirements.append(RunRequirement(tool_execution=tool_executions_list[-1]))
|
|
5372
5496
|
|
|
5373
5497
|
# If the model response is a tool_call_started, add the tool call to the run_response
|
|
5374
5498
|
elif (
|
|
@@ -5536,7 +5660,12 @@ class Agent:
|
|
|
5536
5660
|
user_message_str = (
|
|
5537
5661
|
run_messages.user_message.get_content_string() if run_messages.user_message is not None else None
|
|
5538
5662
|
)
|
|
5539
|
-
if
|
|
5663
|
+
if (
|
|
5664
|
+
user_message_str is not None
|
|
5665
|
+
and user_message_str.strip() != ""
|
|
5666
|
+
and self.memory_manager is not None
|
|
5667
|
+
and self.enable_user_memories
|
|
5668
|
+
):
|
|
5540
5669
|
log_debug("Managing user memories")
|
|
5541
5670
|
self.memory_manager.create_user_memories( # type: ignore
|
|
5542
5671
|
message=user_message_str,
|
|
@@ -5564,7 +5693,7 @@ class Agent:
|
|
|
5564
5693
|
for msg in parsed_messages
|
|
5565
5694
|
if msg.content and (not isinstance(msg.content, str) or msg.content.strip() != "")
|
|
5566
5695
|
]
|
|
5567
|
-
if len(non_empty_messages) > 0 and self.memory_manager is not None:
|
|
5696
|
+
if len(non_empty_messages) > 0 and self.memory_manager is not None and self.enable_user_memories:
|
|
5568
5697
|
self.memory_manager.create_user_memories(messages=non_empty_messages, user_id=user_id, agent_id=self.id) # type: ignore
|
|
5569
5698
|
else:
|
|
5570
5699
|
log_warning("Unable to add messages to memory")
|
|
@@ -5577,7 +5706,12 @@ class Agent:
|
|
|
5577
5706
|
user_message_str = (
|
|
5578
5707
|
run_messages.user_message.get_content_string() if run_messages.user_message is not None else None
|
|
5579
5708
|
)
|
|
5580
|
-
if
|
|
5709
|
+
if (
|
|
5710
|
+
user_message_str is not None
|
|
5711
|
+
and user_message_str.strip() != ""
|
|
5712
|
+
and self.memory_manager is not None
|
|
5713
|
+
and self.enable_user_memories
|
|
5714
|
+
):
|
|
5581
5715
|
log_debug("Managing user memories")
|
|
5582
5716
|
await self.memory_manager.acreate_user_memories( # type: ignore
|
|
5583
5717
|
message=user_message_str,
|
|
@@ -5605,7 +5739,7 @@ class Agent:
|
|
|
5605
5739
|
for msg in parsed_messages
|
|
5606
5740
|
if msg.content and (not isinstance(msg.content, str) or msg.content.strip() != "")
|
|
5607
5741
|
]
|
|
5608
|
-
if len(non_empty_messages) > 0 and self.memory_manager is not None:
|
|
5742
|
+
if len(non_empty_messages) > 0 and self.memory_manager is not None and self.enable_user_memories:
|
|
5609
5743
|
await self.memory_manager.acreate_user_memories( # type: ignore
|
|
5610
5744
|
messages=non_empty_messages, user_id=user_id, agent_id=self.id
|
|
5611
5745
|
)
|
|
@@ -5649,6 +5783,9 @@ class Agent:
|
|
|
5649
5783
|
) -> List[Union[Toolkit, Callable, Function, Dict]]:
|
|
5650
5784
|
agent_tools: List[Union[Toolkit, Callable, Function, Dict]] = []
|
|
5651
5785
|
|
|
5786
|
+
# Connect tools that require connection management
|
|
5787
|
+
self._connect_connectable_tools()
|
|
5788
|
+
|
|
5652
5789
|
# Add provided tools
|
|
5653
5790
|
if self.tools is not None:
|
|
5654
5791
|
# If not running in async mode, raise if any tool is async
|
|
@@ -5695,6 +5832,7 @@ class Agent:
|
|
|
5695
5832
|
run_response=run_response,
|
|
5696
5833
|
async_mode=False,
|
|
5697
5834
|
knowledge_filters=run_context.knowledge_filters,
|
|
5835
|
+
run_context=run_context,
|
|
5698
5836
|
)
|
|
5699
5837
|
)
|
|
5700
5838
|
else:
|
|
@@ -5703,6 +5841,7 @@ class Agent:
|
|
|
5703
5841
|
run_response=run_response,
|
|
5704
5842
|
async_mode=False,
|
|
5705
5843
|
knowledge_filters=run_context.knowledge_filters,
|
|
5844
|
+
run_context=run_context,
|
|
5706
5845
|
)
|
|
5707
5846
|
)
|
|
5708
5847
|
|
|
@@ -5721,6 +5860,9 @@ class Agent:
|
|
|
5721
5860
|
) -> List[Union[Toolkit, Callable, Function, Dict]]:
|
|
5722
5861
|
agent_tools: List[Union[Toolkit, Callable, Function, Dict]] = []
|
|
5723
5862
|
|
|
5863
|
+
# Connect tools that require connection management
|
|
5864
|
+
self._connect_connectable_tools()
|
|
5865
|
+
|
|
5724
5866
|
# Connect MCP tools
|
|
5725
5867
|
await self._connect_mcp_tools()
|
|
5726
5868
|
|
|
@@ -5783,6 +5925,7 @@ class Agent:
|
|
|
5783
5925
|
run_response=run_response,
|
|
5784
5926
|
async_mode=True,
|
|
5785
5927
|
knowledge_filters=run_context.knowledge_filters,
|
|
5928
|
+
run_context=run_context,
|
|
5786
5929
|
)
|
|
5787
5930
|
)
|
|
5788
5931
|
else:
|
|
@@ -5791,6 +5934,7 @@ class Agent:
|
|
|
5791
5934
|
run_response=run_response,
|
|
5792
5935
|
async_mode=True,
|
|
5793
5936
|
knowledge_filters=run_context.knowledge_filters,
|
|
5937
|
+
run_context=run_context,
|
|
5794
5938
|
)
|
|
5795
5939
|
)
|
|
5796
5940
|
|
|
@@ -6927,12 +7071,13 @@ class Agent:
|
|
|
6927
7071
|
Optional[List[UserMemory]]: The user memories.
|
|
6928
7072
|
"""
|
|
6929
7073
|
if self.memory_manager is None:
|
|
6930
|
-
|
|
7074
|
+
self._set_memory_manager()
|
|
7075
|
+
|
|
6931
7076
|
user_id = user_id if user_id is not None else self.user_id
|
|
6932
7077
|
if user_id is None:
|
|
6933
7078
|
user_id = "default"
|
|
6934
7079
|
|
|
6935
|
-
return self.memory_manager.get_user_memories(user_id=user_id)
|
|
7080
|
+
return self.memory_manager.get_user_memories(user_id=user_id) # type: ignore
|
|
6936
7081
|
|
|
6937
7082
|
async def aget_user_memories(self, user_id: Optional[str] = None) -> Optional[List[UserMemory]]:
|
|
6938
7083
|
"""Get the user memories for the given user ID.
|
|
@@ -6943,12 +7088,13 @@ class Agent:
|
|
|
6943
7088
|
Optional[List[UserMemory]]: The user memories.
|
|
6944
7089
|
"""
|
|
6945
7090
|
if self.memory_manager is None:
|
|
6946
|
-
|
|
7091
|
+
self._set_memory_manager()
|
|
7092
|
+
|
|
6947
7093
|
user_id = user_id if user_id is not None else self.user_id
|
|
6948
7094
|
if user_id is None:
|
|
6949
7095
|
user_id = "default"
|
|
6950
7096
|
|
|
6951
|
-
return await self.memory_manager.aget_user_memories(user_id=user_id)
|
|
7097
|
+
return await self.memory_manager.aget_user_memories(user_id=user_id) # type: ignore
|
|
6952
7098
|
|
|
6953
7099
|
def get_culture_knowledge(self) -> Optional[List[CulturalKnowledge]]:
|
|
6954
7100
|
"""Get the cultural knowledge the agent has access to
|
|
@@ -7820,7 +7966,7 @@ class Agent:
|
|
|
7820
7966
|
retrieval_timer = Timer()
|
|
7821
7967
|
retrieval_timer.start()
|
|
7822
7968
|
docs_from_knowledge = self.get_relevant_docs_from_knowledge(
|
|
7823
|
-
query=user_msg_content, filters=knowledge_filters, **kwargs
|
|
7969
|
+
query=user_msg_content, filters=knowledge_filters, run_context=run_context, **kwargs
|
|
7824
7970
|
)
|
|
7825
7971
|
if docs_from_knowledge is not None:
|
|
7826
7972
|
references = MessageReferences(
|
|
@@ -7994,7 +8140,7 @@ class Agent:
|
|
|
7994
8140
|
retrieval_timer = Timer()
|
|
7995
8141
|
retrieval_timer.start()
|
|
7996
8142
|
docs_from_knowledge = await self.aget_relevant_docs_from_knowledge(
|
|
7997
|
-
query=user_msg_content, filters=knowledge_filters, **kwargs
|
|
8143
|
+
query=user_msg_content, filters=knowledge_filters, run_context=run_context, **kwargs
|
|
7998
8144
|
)
|
|
7999
8145
|
if docs_from_knowledge is not None:
|
|
8000
8146
|
references = MessageReferences(
|
|
@@ -8575,6 +8721,7 @@ class Agent:
|
|
|
8575
8721
|
num_documents: Optional[int] = None,
|
|
8576
8722
|
filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
8577
8723
|
validate_filters: bool = False,
|
|
8724
|
+
run_context: Optional[RunContext] = None,
|
|
8578
8725
|
**kwargs,
|
|
8579
8726
|
) -> Optional[List[Union[Dict[str, Any], str]]]:
|
|
8580
8727
|
"""Get relevant docs from the knowledge base to answer a query.
|
|
@@ -8584,6 +8731,7 @@ class Agent:
|
|
|
8584
8731
|
num_documents (Optional[int]): Number of documents to return.
|
|
8585
8732
|
filters (Optional[Dict[str, Any]]): Filters to apply to the search.
|
|
8586
8733
|
validate_filters (bool): Whether to validate the filters against known valid filter keys.
|
|
8734
|
+
run_context (Optional[RunContext]): Runtime context containing dependencies and other context.
|
|
8587
8735
|
**kwargs: Additional keyword arguments.
|
|
8588
8736
|
|
|
8589
8737
|
Returns:
|
|
@@ -8591,6 +8739,9 @@ class Agent:
|
|
|
8591
8739
|
"""
|
|
8592
8740
|
from agno.knowledge.document import Document
|
|
8593
8741
|
|
|
8742
|
+
# Extract dependencies from run_context if available
|
|
8743
|
+
dependencies = run_context.dependencies if run_context else None
|
|
8744
|
+
|
|
8594
8745
|
if num_documents is None and self.knowledge is not None:
|
|
8595
8746
|
num_documents = self.knowledge.max_results
|
|
8596
8747
|
# Validate the filters against known valid filter keys
|
|
@@ -8622,6 +8773,11 @@ class Agent:
|
|
|
8622
8773
|
knowledge_retriever_kwargs = {"agent": self}
|
|
8623
8774
|
if "filters" in sig.parameters:
|
|
8624
8775
|
knowledge_retriever_kwargs["filters"] = filters
|
|
8776
|
+
if "run_context" in sig.parameters:
|
|
8777
|
+
knowledge_retriever_kwargs["run_context"] = run_context
|
|
8778
|
+
elif "dependencies" in sig.parameters:
|
|
8779
|
+
# Backward compatibility: support dependencies parameter
|
|
8780
|
+
knowledge_retriever_kwargs["dependencies"] = dependencies
|
|
8625
8781
|
knowledge_retriever_kwargs.update({"query": query, "num_documents": num_documents, **kwargs})
|
|
8626
8782
|
return self.knowledge_retriever(**knowledge_retriever_kwargs)
|
|
8627
8783
|
except Exception as e:
|
|
@@ -8660,11 +8816,15 @@ class Agent:
|
|
|
8660
8816
|
num_documents: Optional[int] = None,
|
|
8661
8817
|
filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
8662
8818
|
validate_filters: bool = False,
|
|
8819
|
+
run_context: Optional[RunContext] = None,
|
|
8663
8820
|
**kwargs,
|
|
8664
8821
|
) -> Optional[List[Union[Dict[str, Any], str]]]:
|
|
8665
8822
|
"""Get relevant documents from knowledge base asynchronously."""
|
|
8666
8823
|
from agno.knowledge.document import Document
|
|
8667
8824
|
|
|
8825
|
+
# Extract dependencies from run_context if available
|
|
8826
|
+
dependencies = run_context.dependencies if run_context else None
|
|
8827
|
+
|
|
8668
8828
|
if num_documents is None and self.knowledge is not None:
|
|
8669
8829
|
num_documents = self.knowledge.max_results
|
|
8670
8830
|
|
|
@@ -8696,6 +8856,11 @@ class Agent:
|
|
|
8696
8856
|
knowledge_retriever_kwargs = {"agent": self}
|
|
8697
8857
|
if "filters" in sig.parameters:
|
|
8698
8858
|
knowledge_retriever_kwargs["filters"] = filters
|
|
8859
|
+
if "run_context" in sig.parameters:
|
|
8860
|
+
knowledge_retriever_kwargs["run_context"] = run_context
|
|
8861
|
+
elif "dependencies" in sig.parameters:
|
|
8862
|
+
# Backward compatibility: support dependencies parameter
|
|
8863
|
+
knowledge_retriever_kwargs["dependencies"] = dependencies
|
|
8699
8864
|
knowledge_retriever_kwargs.update({"query": query, "num_documents": num_documents, **kwargs})
|
|
8700
8865
|
result = self.knowledge_retriever(**knowledge_retriever_kwargs)
|
|
8701
8866
|
|
|
@@ -10038,6 +10203,7 @@ class Agent:
|
|
|
10038
10203
|
run_response: RunOutput,
|
|
10039
10204
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
10040
10205
|
async_mode: bool = False,
|
|
10206
|
+
run_context: Optional[RunContext] = None,
|
|
10041
10207
|
) -> Function:
|
|
10042
10208
|
"""Factory function to create a search_knowledge_base function with filters."""
|
|
10043
10209
|
|
|
@@ -10054,7 +10220,9 @@ class Agent:
|
|
|
10054
10220
|
# Get the relevant documents from the knowledge base, passing filters
|
|
10055
10221
|
retrieval_timer = Timer()
|
|
10056
10222
|
retrieval_timer.start()
|
|
10057
|
-
docs_from_knowledge = self.get_relevant_docs_from_knowledge(
|
|
10223
|
+
docs_from_knowledge = self.get_relevant_docs_from_knowledge(
|
|
10224
|
+
query=query, filters=knowledge_filters, run_context=run_context
|
|
10225
|
+
)
|
|
10058
10226
|
if docs_from_knowledge is not None:
|
|
10059
10227
|
references = MessageReferences(
|
|
10060
10228
|
query=query,
|
|
@@ -10085,7 +10253,9 @@ class Agent:
|
|
|
10085
10253
|
"""
|
|
10086
10254
|
retrieval_timer = Timer()
|
|
10087
10255
|
retrieval_timer.start()
|
|
10088
|
-
docs_from_knowledge = await self.aget_relevant_docs_from_knowledge(
|
|
10256
|
+
docs_from_knowledge = await self.aget_relevant_docs_from_knowledge(
|
|
10257
|
+
query=query, filters=knowledge_filters, run_context=run_context
|
|
10258
|
+
)
|
|
10089
10259
|
if docs_from_knowledge is not None:
|
|
10090
10260
|
references = MessageReferences(
|
|
10091
10261
|
query=query,
|
|
@@ -10114,6 +10284,7 @@ class Agent:
|
|
|
10114
10284
|
run_response: RunOutput,
|
|
10115
10285
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
10116
10286
|
async_mode: bool = False,
|
|
10287
|
+
run_context: Optional[RunContext] = None,
|
|
10117
10288
|
) -> Function:
|
|
10118
10289
|
"""Factory function to create a search_knowledge_base function with filters."""
|
|
10119
10290
|
|
|
@@ -10134,7 +10305,7 @@ class Agent:
|
|
|
10134
10305
|
retrieval_timer = Timer()
|
|
10135
10306
|
retrieval_timer.start()
|
|
10136
10307
|
docs_from_knowledge = self.get_relevant_docs_from_knowledge(
|
|
10137
|
-
query=query, filters=search_filters, validate_filters=True
|
|
10308
|
+
query=query, filters=search_filters, validate_filters=True, run_context=run_context
|
|
10138
10309
|
)
|
|
10139
10310
|
if docs_from_knowledge is not None:
|
|
10140
10311
|
references = MessageReferences(
|
|
@@ -10171,7 +10342,7 @@ class Agent:
|
|
|
10171
10342
|
retrieval_timer = Timer()
|
|
10172
10343
|
retrieval_timer.start()
|
|
10173
10344
|
docs_from_knowledge = await self.aget_relevant_docs_from_knowledge(
|
|
10174
|
-
query=query, filters=search_filters, validate_filters=True
|
|
10345
|
+
query=query, filters=search_filters, validate_filters=True, run_context=run_context
|
|
10175
10346
|
)
|
|
10176
10347
|
if docs_from_knowledge is not None:
|
|
10177
10348
|
references = MessageReferences(
|