agno 2.3.7__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 +371 -367
- 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 +0 -21
- 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/models/base.py +134 -11
- agno/models/openai/responses.py +3 -2
- agno/os/interfaces/a2a/utils.py +1 -1
- agno/os/middleware/jwt.py +8 -6
- agno/team/team.py +88 -86
- agno/tools/workflow.py +8 -1
- agno/workflow/parallel.py +8 -2
- agno/workflow/step.py +3 -3
- {agno-2.3.7.dist-info → agno-2.3.8.dist-info}/METADATA +2 -2
- {agno-2.3.7.dist-info → agno-2.3.8.dist-info}/RECORD +23 -24
- agno/tools/memori.py +0 -339
- {agno-2.3.7.dist-info → agno-2.3.8.dist-info}/WHEEL +0 -0
- {agno-2.3.7.dist-info → agno-2.3.8.dist-info}/licenses/LICENSE +0 -0
- {agno-2.3.7.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
|
|
@@ -558,8 +557,12 @@ class Agent:
|
|
|
558
557
|
self.enable_user_memories = enable_user_memories
|
|
559
558
|
self.add_memories_to_context = add_memories_to_context
|
|
560
559
|
|
|
561
|
-
self.session_summary_manager = session_summary_manager
|
|
562
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
|
+
|
|
563
566
|
self.add_session_summary_to_context = add_session_summary_to_context
|
|
564
567
|
|
|
565
568
|
# Context compression settings
|
|
@@ -1086,7 +1089,12 @@ class Agent:
|
|
|
1086
1089
|
# Start memory creation on a separate thread (runs concurrently with the main execution loop)
|
|
1087
1090
|
memory_future = None
|
|
1088
1091
|
# 4. Start memory creation in background thread if memory manager is enabled and agentic memory is disabled
|
|
1089
|
-
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
|
+
):
|
|
1090
1098
|
log_debug("Starting memory creation in background thread.")
|
|
1091
1099
|
memory_future = self.background_executor.submit(
|
|
1092
1100
|
self._make_memories, run_messages=run_messages, user_id=user_id
|
|
@@ -1175,7 +1183,7 @@ class Agent:
|
|
|
1175
1183
|
wait_for_open_threads(memory_future=memory_future, cultural_knowledge_future=cultural_knowledge_future)
|
|
1176
1184
|
|
|
1177
1185
|
# 12. Create session summary
|
|
1178
|
-
if self.session_summary_manager is not None:
|
|
1186
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
1179
1187
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
1180
1188
|
session.upsert_run(run=run_response)
|
|
1181
1189
|
try:
|
|
@@ -1305,7 +1313,12 @@ class Agent:
|
|
|
1305
1313
|
# Start memory creation on a separate thread (runs concurrently with the main execution loop)
|
|
1306
1314
|
memory_future = None
|
|
1307
1315
|
# 4. Start memory creation in background thread if memory manager is enabled and agentic memory is disabled
|
|
1308
|
-
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
|
+
):
|
|
1309
1322
|
log_debug("Starting memory creation in background thread.")
|
|
1310
1323
|
memory_future = self.background_executor.submit(
|
|
1311
1324
|
self._make_memories, run_messages=run_messages, user_id=user_id
|
|
@@ -1450,7 +1463,7 @@ class Agent:
|
|
|
1450
1463
|
)
|
|
1451
1464
|
|
|
1452
1465
|
# 9. Create session summary
|
|
1453
|
-
if self.session_summary_manager is not None:
|
|
1466
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
1454
1467
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
1455
1468
|
session.upsert_run(run=run_response)
|
|
1456
1469
|
|
|
@@ -1550,7 +1563,6 @@ class Agent:
|
|
|
1550
1563
|
images: Optional[Sequence[Image]] = None,
|
|
1551
1564
|
videos: Optional[Sequence[Video]] = None,
|
|
1552
1565
|
files: Optional[Sequence[File]] = None,
|
|
1553
|
-
retries: Optional[int] = None,
|
|
1554
1566
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
1555
1567
|
add_history_to_context: Optional[bool] = None,
|
|
1556
1568
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -1578,7 +1590,6 @@ class Agent:
|
|
|
1578
1590
|
images: Optional[Sequence[Image]] = None,
|
|
1579
1591
|
videos: Optional[Sequence[Video]] = None,
|
|
1580
1592
|
files: Optional[Sequence[File]] = None,
|
|
1581
|
-
retries: Optional[int] = None,
|
|
1582
1593
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
1583
1594
|
add_history_to_context: Optional[bool] = None,
|
|
1584
1595
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -1607,7 +1618,6 @@ class Agent:
|
|
|
1607
1618
|
images: Optional[Sequence[Image]] = None,
|
|
1608
1619
|
videos: Optional[Sequence[Video]] = None,
|
|
1609
1620
|
files: Optional[Sequence[File]] = None,
|
|
1610
|
-
retries: Optional[int] = None,
|
|
1611
1621
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
1612
1622
|
add_history_to_context: Optional[bool] = None,
|
|
1613
1623
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -1710,159 +1720,163 @@ class Agent:
|
|
|
1710
1720
|
# output_schema parameter takes priority, even if run_context was provided
|
|
1711
1721
|
run_context.output_schema = output_schema
|
|
1712
1722
|
|
|
1713
|
-
#
|
|
1714
|
-
|
|
1715
|
-
self._resolve_run_dependencies(run_context=run_context)
|
|
1716
|
-
|
|
1717
|
-
add_dependencies = (
|
|
1718
|
-
add_dependencies_to_context if add_dependencies_to_context is not None else self.add_dependencies_to_context
|
|
1719
|
-
)
|
|
1720
|
-
add_session_state = (
|
|
1721
|
-
add_session_state_to_context
|
|
1722
|
-
if add_session_state_to_context is not None
|
|
1723
|
-
else self.add_session_state_to_context
|
|
1724
|
-
)
|
|
1725
|
-
add_history = add_history_to_context if add_history_to_context is not None else self.add_history_to_context
|
|
1723
|
+
# Set up retry logic
|
|
1724
|
+
num_attempts = self.retries + 1
|
|
1726
1725
|
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
run_context.knowledge_filters = self._get_effective_filters(knowledge_filters)
|
|
1726
|
+
for attempt in range(num_attempts):
|
|
1727
|
+
log_debug(f"Retrying Agent run {run_id}. Attempt {attempt + 1} of {num_attempts}...")
|
|
1730
1728
|
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
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
|
+
)
|
|
1734
1747
|
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
1739
|
-
DeprecationWarning,
|
|
1740
|
-
stacklevel=2,
|
|
1741
|
-
)
|
|
1742
|
-
stream_events = stream_events or stream_intermediate_steps
|
|
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)
|
|
1743
1751
|
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1752
|
+
# Use stream override value when necessary
|
|
1753
|
+
if stream is None:
|
|
1754
|
+
stream = False if self.stream is None else self.stream
|
|
1747
1755
|
|
|
1748
|
-
|
|
1749
|
-
|
|
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
|
|
1750
1764
|
|
|
1751
|
-
|
|
1752
|
-
|
|
1765
|
+
# Can't stream events if streaming is disabled
|
|
1766
|
+
if stream is False:
|
|
1767
|
+
stream_events = False
|
|
1753
1768
|
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
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
|
|
1757
1771
|
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
merge_dictionaries(metadata, self.metadata)
|
|
1772
|
+
self.stream = self.stream or stream
|
|
1773
|
+
self.stream_events = self.stream_events or stream_events
|
|
1761
1774
|
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
user_id=user_id,
|
|
1768
|
-
agent_name=self.name,
|
|
1769
|
-
metadata=run_context.metadata,
|
|
1770
|
-
session_state=run_context.session_state,
|
|
1771
|
-
input=run_input,
|
|
1772
|
-
)
|
|
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)
|
|
1773
1780
|
|
|
1774
|
-
|
|
1775
|
-
|
|
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)
|
|
1776
1784
|
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
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
|
+
)
|
|
1780
1796
|
|
|
1781
|
-
|
|
1782
|
-
|
|
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
|
|
1783
1799
|
|
|
1784
|
-
|
|
1785
|
-
|
|
1800
|
+
# Start the run metrics timer, to calculate the run duration
|
|
1801
|
+
run_response.metrics = Metrics()
|
|
1802
|
+
run_response.metrics.start_timer()
|
|
1786
1803
|
|
|
1787
|
-
|
|
1804
|
+
yield_run_output = yield_run_output or yield_run_response # For backwards compatibility
|
|
1788
1805
|
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
return response_iterator
|
|
1808
|
-
else:
|
|
1809
|
-
response = self._run(
|
|
1810
|
-
run_response=run_response,
|
|
1811
|
-
run_context=run_context,
|
|
1812
|
-
session=agent_session,
|
|
1813
|
-
user_id=user_id,
|
|
1814
|
-
add_history_to_context=add_history,
|
|
1815
|
-
add_dependencies_to_context=add_dependencies,
|
|
1816
|
-
add_session_state_to_context=add_session_state,
|
|
1817
|
-
response_format=response_format,
|
|
1818
|
-
debug_mode=debug_mode,
|
|
1819
|
-
background_tasks=background_tasks,
|
|
1820
|
-
**kwargs,
|
|
1821
|
-
)
|
|
1822
|
-
return response
|
|
1823
|
-
except (InputCheckError, OutputCheckError) as e:
|
|
1824
|
-
log_error(f"Validation failed: {str(e)} | Check: {e.check_trigger}")
|
|
1825
|
-
raise e
|
|
1826
|
-
except ModelProviderError as e:
|
|
1827
|
-
log_warning(f"Attempt {attempt + 1}/{num_attempts} failed: {str(e)}")
|
|
1828
|
-
if isinstance(e, StopAgentRun):
|
|
1829
|
-
raise e
|
|
1830
|
-
last_exception = e
|
|
1831
|
-
if attempt < num_attempts - 1: # Don't sleep on the last attempt
|
|
1832
|
-
if self.exponential_backoff:
|
|
1833
|
-
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
|
|
1834
1824
|
else:
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
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,
|
|
1848
1837
|
)
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
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
|
|
1852
1845
|
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
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
|
|
1860
1877
|
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
if stream:
|
|
1864
|
-
return generator_wrapper(create_run_error_event(run_response, error=str(last_exception))) # type: ignore
|
|
1865
|
-
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.")
|
|
1866
1880
|
|
|
1867
1881
|
async def _arun(
|
|
1868
1882
|
self,
|
|
@@ -1981,7 +1995,12 @@ class Agent:
|
|
|
1981
1995
|
|
|
1982
1996
|
# 7. Start memory creation as a background task (runs concurrently with the main execution)
|
|
1983
1997
|
memory_task = None
|
|
1984
|
-
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
|
+
):
|
|
1985
2004
|
log_debug("Starting memory creation in background task.")
|
|
1986
2005
|
memory_task = create_task(self._amake_memories(run_messages=run_messages, user_id=user_id))
|
|
1987
2006
|
|
|
@@ -2071,7 +2090,7 @@ class Agent:
|
|
|
2071
2090
|
await await_for_open_threads(memory_task=memory_task, cultural_knowledge_task=cultural_knowledge_task)
|
|
2072
2091
|
|
|
2073
2092
|
# 15. Create session summary
|
|
2074
|
-
if self.session_summary_manager is not None:
|
|
2093
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
2075
2094
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
2076
2095
|
agent_session.upsert_run(run=run_response)
|
|
2077
2096
|
try:
|
|
@@ -2261,7 +2280,12 @@ class Agent:
|
|
|
2261
2280
|
|
|
2262
2281
|
# 7. Start memory creation as a background task (runs concurrently with the main execution)
|
|
2263
2282
|
memory_task = None
|
|
2264
|
-
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
|
+
):
|
|
2265
2289
|
log_debug("Starting memory creation in background task.")
|
|
2266
2290
|
memory_task = create_task(self._amake_memories(run_messages=run_messages, user_id=user_id))
|
|
2267
2291
|
|
|
@@ -2397,7 +2421,7 @@ class Agent:
|
|
|
2397
2421
|
yield item
|
|
2398
2422
|
|
|
2399
2423
|
# 12. Create session summary
|
|
2400
|
-
if self.session_summary_manager is not None:
|
|
2424
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
2401
2425
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
2402
2426
|
agent_session.upsert_run(run=run_response)
|
|
2403
2427
|
|
|
@@ -2521,7 +2545,6 @@ class Agent:
|
|
|
2521
2545
|
files: Optional[Sequence[File]] = None,
|
|
2522
2546
|
stream_events: Optional[bool] = None,
|
|
2523
2547
|
stream_intermediate_steps: Optional[bool] = None,
|
|
2524
|
-
retries: Optional[int] = None,
|
|
2525
2548
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
2526
2549
|
add_history_to_context: Optional[bool] = None,
|
|
2527
2550
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -2548,7 +2571,6 @@ class Agent:
|
|
|
2548
2571
|
files: Optional[Sequence[File]] = None,
|
|
2549
2572
|
stream_events: Optional[bool] = None,
|
|
2550
2573
|
stream_intermediate_steps: Optional[bool] = None,
|
|
2551
|
-
retries: Optional[int] = None,
|
|
2552
2574
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
2553
2575
|
add_history_to_context: Optional[bool] = None,
|
|
2554
2576
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -2577,7 +2599,6 @@ class Agent:
|
|
|
2577
2599
|
files: Optional[Sequence[File]] = None,
|
|
2578
2600
|
stream_events: Optional[bool] = None,
|
|
2579
2601
|
stream_intermediate_steps: Optional[bool] = None,
|
|
2580
|
-
retries: Optional[int] = None,
|
|
2581
2602
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
2582
2603
|
add_history_to_context: Optional[bool] = None,
|
|
2583
2604
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -2714,9 +2735,6 @@ class Agent:
|
|
|
2714
2735
|
# Prepare arguments for the model (must be after run_context is fully initialized)
|
|
2715
2736
|
response_format = self._get_response_format(run_context=run_context) if self.parser_model is None else None
|
|
2716
2737
|
|
|
2717
|
-
# If no retries are set, use the agent's default retries
|
|
2718
|
-
retries = retries if retries is not None else self.retries
|
|
2719
|
-
|
|
2720
2738
|
# Create a new run_response for this attempt
|
|
2721
2739
|
run_response = RunOutput(
|
|
2722
2740
|
run_id=run_id,
|
|
@@ -2736,12 +2754,13 @@ class Agent:
|
|
|
2736
2754
|
run_response.metrics = Metrics()
|
|
2737
2755
|
run_response.metrics.start_timer()
|
|
2738
2756
|
|
|
2739
|
-
last_exception = None
|
|
2740
|
-
num_attempts = retries + 1
|
|
2741
|
-
|
|
2742
2757
|
yield_run_output = yield_run_output or yield_run_response # For backwards compatibility
|
|
2743
2758
|
|
|
2759
|
+
# Set up retry logic
|
|
2760
|
+
num_attempts = self.retries + 1
|
|
2761
|
+
|
|
2744
2762
|
for attempt in range(num_attempts):
|
|
2763
|
+
log_debug(f"Retrying Agent run {run_id}. Attempt {attempt + 1} of {num_attempts}...")
|
|
2745
2764
|
try:
|
|
2746
2765
|
# Pass the new run_response to _arun
|
|
2747
2766
|
if stream:
|
|
@@ -2774,23 +2793,9 @@ class Agent:
|
|
|
2774
2793
|
background_tasks=background_tasks,
|
|
2775
2794
|
**kwargs,
|
|
2776
2795
|
)
|
|
2777
|
-
|
|
2778
2796
|
except (InputCheckError, OutputCheckError) as e:
|
|
2779
2797
|
log_error(f"Validation failed: {str(e)} | Check trigger: {e.check_trigger}")
|
|
2780
2798
|
raise e
|
|
2781
|
-
except ModelProviderError as e:
|
|
2782
|
-
log_warning(f"Attempt {attempt + 1}/{num_attempts} failed: {str(e)}")
|
|
2783
|
-
if isinstance(e, StopAgentRun):
|
|
2784
|
-
raise e
|
|
2785
|
-
last_exception = e
|
|
2786
|
-
if attempt < num_attempts - 1: # Don't sleep on the last attempt
|
|
2787
|
-
if self.exponential_backoff:
|
|
2788
|
-
delay = 2**attempt * self.delay_between_retries
|
|
2789
|
-
else:
|
|
2790
|
-
delay = self.delay_between_retries
|
|
2791
|
-
import time
|
|
2792
|
-
|
|
2793
|
-
time.sleep(delay)
|
|
2794
2799
|
except KeyboardInterrupt:
|
|
2795
2800
|
run_response.content = "Operation cancelled by user"
|
|
2796
2801
|
run_response.status = RunStatus.cancelled
|
|
@@ -2804,20 +2809,27 @@ class Agent:
|
|
|
2804
2809
|
)
|
|
2805
2810
|
else:
|
|
2806
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
|
|
2807
2820
|
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
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
|
|
2813
2830
|
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
raise last_exception
|
|
2817
|
-
else:
|
|
2818
|
-
if stream:
|
|
2819
|
-
return async_generator_wrapper(create_run_error_event(run_response, error=str(last_exception))) # type: ignore
|
|
2820
|
-
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.")
|
|
2821
2833
|
|
|
2822
2834
|
@overload
|
|
2823
2835
|
def continue_run(
|
|
@@ -2832,7 +2844,6 @@ class Agent:
|
|
|
2832
2844
|
stream_intermediate_steps: Optional[bool] = None,
|
|
2833
2845
|
user_id: Optional[str] = None,
|
|
2834
2846
|
session_id: Optional[str] = None,
|
|
2835
|
-
retries: Optional[int] = None,
|
|
2836
2847
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
2837
2848
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
2838
2849
|
metadata: Optional[Dict[str, Any]] = None,
|
|
@@ -2853,7 +2864,6 @@ class Agent:
|
|
|
2853
2864
|
stream_intermediate_steps: Optional[bool] = None,
|
|
2854
2865
|
user_id: Optional[str] = None,
|
|
2855
2866
|
session_id: Optional[str] = None,
|
|
2856
|
-
retries: Optional[int] = None,
|
|
2857
2867
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
2858
2868
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
2859
2869
|
metadata: Optional[Dict[str, Any]] = None,
|
|
@@ -2874,7 +2884,6 @@ class Agent:
|
|
|
2874
2884
|
user_id: Optional[str] = None,
|
|
2875
2885
|
session_id: Optional[str] = None,
|
|
2876
2886
|
run_context: Optional[RunContext] = None,
|
|
2877
|
-
retries: Optional[int] = None,
|
|
2878
2887
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
2879
2888
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
2880
2889
|
metadata: Optional[Dict[str, Any]] = None,
|
|
@@ -2893,7 +2902,6 @@ class Agent:
|
|
|
2893
2902
|
user_id: The user id to continue the run for.
|
|
2894
2903
|
session_id: The session id to continue the run for.
|
|
2895
2904
|
run_context: The run context to use for the run.
|
|
2896
|
-
retries: The number of retries to continue the run for.
|
|
2897
2905
|
knowledge_filters: The knowledge filters to use for the run.
|
|
2898
2906
|
dependencies: The dependencies to use for the run.
|
|
2899
2907
|
metadata: The metadata to use for the run.
|
|
@@ -2948,125 +2956,129 @@ class Agent:
|
|
|
2948
2956
|
dependencies=dependencies,
|
|
2949
2957
|
)
|
|
2950
2958
|
|
|
2951
|
-
# Resolve
|
|
2952
|
-
|
|
2953
|
-
self._resolve_run_dependencies(run_context=run_context)
|
|
2954
|
-
|
|
2955
|
-
# When filters are passed manually
|
|
2956
|
-
if self.knowledge_filters or run_context.knowledge_filters or knowledge_filters:
|
|
2957
|
-
run_context.knowledge_filters = self._get_effective_filters(knowledge_filters)
|
|
2958
|
-
|
|
2959
|
-
# Merge agent metadata with run metadata
|
|
2960
|
-
run_context.metadata = metadata
|
|
2961
|
-
if self.metadata is not None:
|
|
2962
|
-
if run_context.metadata is None:
|
|
2963
|
-
run_context.metadata = self.metadata
|
|
2964
|
-
else:
|
|
2965
|
-
merge_dictionaries(run_context.metadata, self.metadata)
|
|
2966
|
-
|
|
2967
|
-
# If no retries are set, use the agent's default retries
|
|
2968
|
-
retries = retries if retries is not None else self.retries
|
|
2969
|
-
|
|
2970
|
-
# Use stream override value when necessary
|
|
2971
|
-
if stream is None:
|
|
2972
|
-
stream = False if self.stream is None else self.stream
|
|
2973
|
-
|
|
2974
|
-
# Considering both stream_events and stream_intermediate_steps (deprecated)
|
|
2975
|
-
if stream_intermediate_steps is not None:
|
|
2976
|
-
warnings.warn(
|
|
2977
|
-
"The 'stream_intermediate_steps' parameter is deprecated and will be removed in future versions. Use 'stream_events' instead.",
|
|
2978
|
-
DeprecationWarning,
|
|
2979
|
-
stacklevel=2,
|
|
2980
|
-
)
|
|
2981
|
-
stream_events = stream_events or stream_intermediate_steps
|
|
2982
|
-
|
|
2983
|
-
# Can't stream events if streaming is disabled
|
|
2984
|
-
if stream is False:
|
|
2985
|
-
stream_events = False
|
|
2986
|
-
|
|
2987
|
-
if stream_events is None:
|
|
2988
|
-
stream_events = False if self.stream_events is None else self.stream_events
|
|
2989
|
-
|
|
2990
|
-
# Can't stream events if streaming is disabled
|
|
2991
|
-
if stream is False:
|
|
2992
|
-
stream_events = False
|
|
2993
|
-
|
|
2994
|
-
self.stream = self.stream or stream
|
|
2995
|
-
self.stream_events = self.stream_events or stream_events
|
|
2959
|
+
# Resolve retry parameters
|
|
2960
|
+
num_attempts = self.retries + 1
|
|
2996
2961
|
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
# The run is continued from a provided run_response. This contains the updated tools.
|
|
3000
|
-
input = run_response.messages or []
|
|
3001
|
-
elif run_id is not None:
|
|
3002
|
-
# The run is continued from a run_id, one of requirements or updated_tool (deprecated) is required.
|
|
3003
|
-
if updated_tools is None and requirements is None:
|
|
3004
|
-
raise ValueError("To continue a run from a given run_id, the requirements parameter must be provided.")
|
|
2962
|
+
for attempt in range(num_attempts):
|
|
2963
|
+
log_debug(f"Retrying Agent continue_run {run_id}. Attempt {attempt + 1} of {num_attempts}...")
|
|
3005
2964
|
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
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
|
+
)
|
|
3010
3019
|
|
|
3011
|
-
|
|
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}")
|
|
3012
3024
|
|
|
3013
|
-
|
|
3014
|
-
if updated_tools is not None:
|
|
3015
|
-
warnings.warn(
|
|
3016
|
-
"The 'updated_tools' parameter is deprecated and will be removed in future versions. Use 'requirements' instead.",
|
|
3017
|
-
DeprecationWarning,
|
|
3018
|
-
stacklevel=2,
|
|
3019
|
-
)
|
|
3020
|
-
run_response.tools = updated_tools
|
|
3025
|
+
input = run_response.messages or []
|
|
3021
3026
|
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
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
|
|
3029
3047
|
else:
|
|
3030
|
-
run_response
|
|
3031
|
-
else:
|
|
3032
|
-
raise ValueError("Either run_response or run_id must be provided.")
|
|
3048
|
+
raise ValueError("Either run_response or run_id must be provided.")
|
|
3033
3049
|
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
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)
|
|
3038
3054
|
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
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
|
+
)
|
|
3045
3061
|
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
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
|
+
)
|
|
3053
3069
|
|
|
3054
|
-
|
|
3055
|
-
num_attempts = retries + 1
|
|
3056
|
-
for attempt in range(num_attempts):
|
|
3057
|
-
run_response = cast(RunOutput, run_response)
|
|
3070
|
+
run_response = cast(RunOutput, run_response)
|
|
3058
3071
|
|
|
3059
|
-
|
|
3072
|
+
log_debug(f"Agent Run Start: {run_response.run_id}", center=True)
|
|
3060
3073
|
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3074
|
+
# Prepare run messages
|
|
3075
|
+
run_messages = self._get_continue_run_messages(
|
|
3076
|
+
input=input,
|
|
3077
|
+
)
|
|
3065
3078
|
|
|
3066
|
-
|
|
3067
|
-
|
|
3079
|
+
# Reset the run state
|
|
3080
|
+
run_response.status = RunStatus.running
|
|
3068
3081
|
|
|
3069
|
-
try:
|
|
3070
3082
|
if stream:
|
|
3071
3083
|
response_iterator = self._continue_run_stream(
|
|
3072
3084
|
run_response=run_response,
|
|
@@ -3097,42 +3109,34 @@ class Agent:
|
|
|
3097
3109
|
**kwargs,
|
|
3098
3110
|
)
|
|
3099
3111
|
return response
|
|
3100
|
-
except
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
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
|
|
3106
3125
|
if self.exponential_backoff:
|
|
3107
|
-
delay = 2**attempt
|
|
3126
|
+
delay = self.delay_between_retries * (2**attempt)
|
|
3108
3127
|
else:
|
|
3109
3128
|
delay = self.delay_between_retries
|
|
3110
|
-
import time
|
|
3111
3129
|
|
|
3130
|
+
log_warning(f"Attempt {attempt + 1}/{num_attempts} failed: {str(e)}. Retrying in {delay}s...")
|
|
3112
3131
|
time.sleep(delay)
|
|
3113
|
-
|
|
3114
|
-
if stream:
|
|
3115
|
-
return generator_wrapper( # type: ignore
|
|
3116
|
-
create_run_cancelled_event(run_response, "Operation cancelled by user")
|
|
3117
|
-
)
|
|
3132
|
+
continue
|
|
3118
3133
|
else:
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3134
|
+
# Final attempt failed - re-raise the exception
|
|
3135
|
+
log_error(f"All {num_attempts} attempts failed. Final error: {str(e)}")
|
|
3136
|
+
raise
|
|
3122
3137
|
|
|
3123
3138
|
# If we get here, all retries failed
|
|
3124
|
-
|
|
3125
|
-
log_error(
|
|
3126
|
-
f"Failed after {num_attempts} attempts. Last error using {last_exception.model_name}({last_exception.model_id})"
|
|
3127
|
-
)
|
|
3128
|
-
|
|
3129
|
-
if stream:
|
|
3130
|
-
return generator_wrapper(create_run_error_event(run_response, error=str(last_exception))) # type: ignore
|
|
3131
|
-
raise last_exception
|
|
3132
|
-
else:
|
|
3133
|
-
if stream:
|
|
3134
|
-
return generator_wrapper(create_run_error_event(run_response, error=str(last_exception))) # type: ignore
|
|
3135
|
-
raise Exception(f"Failed after {num_attempts} attempts.")
|
|
3139
|
+
raise Exception(f"Failed after {num_attempts} attempts.")
|
|
3136
3140
|
|
|
3137
3141
|
def _continue_run(
|
|
3138
3142
|
self,
|
|
@@ -3217,7 +3221,7 @@ class Agent:
|
|
|
3217
3221
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
3218
3222
|
|
|
3219
3223
|
# 7. Create session summary
|
|
3220
|
-
if self.session_summary_manager is not None:
|
|
3224
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
3221
3225
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
3222
3226
|
session.upsert_run(run=run_response)
|
|
3223
3227
|
|
|
@@ -3353,7 +3357,7 @@ class Agent:
|
|
|
3353
3357
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
3354
3358
|
|
|
3355
3359
|
# 4. Create session summary
|
|
3356
|
-
if self.session_summary_manager is not None:
|
|
3360
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
3357
3361
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
3358
3362
|
session.upsert_run(run=run_response)
|
|
3359
3363
|
|
|
@@ -3448,7 +3452,6 @@ class Agent:
|
|
|
3448
3452
|
requirements: Optional[List[RunRequirement]] = None,
|
|
3449
3453
|
user_id: Optional[str] = None,
|
|
3450
3454
|
session_id: Optional[str] = None,
|
|
3451
|
-
retries: Optional[int] = None,
|
|
3452
3455
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
3453
3456
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
3454
3457
|
metadata: Optional[Dict[str, Any]] = None,
|
|
@@ -3469,7 +3472,6 @@ class Agent:
|
|
|
3469
3472
|
requirements: Optional[List[RunRequirement]] = None,
|
|
3470
3473
|
user_id: Optional[str] = None,
|
|
3471
3474
|
session_id: Optional[str] = None,
|
|
3472
|
-
retries: Optional[int] = None,
|
|
3473
3475
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
3474
3476
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
3475
3477
|
metadata: Optional[Dict[str, Any]] = None,
|
|
@@ -3490,7 +3492,6 @@ class Agent:
|
|
|
3490
3492
|
user_id: Optional[str] = None,
|
|
3491
3493
|
session_id: Optional[str] = None,
|
|
3492
3494
|
run_context: Optional[RunContext] = None,
|
|
3493
|
-
retries: Optional[int] = None,
|
|
3494
3495
|
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
3495
3496
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
3496
3497
|
metadata: Optional[Dict[str, Any]] = None,
|
|
@@ -3510,7 +3511,6 @@ class Agent:
|
|
|
3510
3511
|
user_id: The user id to continue the run for.
|
|
3511
3512
|
session_id: The session id to continue the run for.
|
|
3512
3513
|
run_context: The run context to use for the run.
|
|
3513
|
-
retries: The number of retries to continue the run for.
|
|
3514
3514
|
knowledge_filters: The knowledge filters to use for the run.
|
|
3515
3515
|
dependencies: The dependencies to use for continuing the run.
|
|
3516
3516
|
metadata: The metadata to use for continuing the run.
|
|
@@ -3548,9 +3548,6 @@ class Agent:
|
|
|
3548
3548
|
|
|
3549
3549
|
dependencies = dependencies if dependencies is not None else self.dependencies
|
|
3550
3550
|
|
|
3551
|
-
# If no retries are set, use the agent's default retries
|
|
3552
|
-
retries = retries if retries is not None else self.retries
|
|
3553
|
-
|
|
3554
3551
|
# Use stream override value when necessary
|
|
3555
3552
|
if stream is None:
|
|
3556
3553
|
stream = False if self.stream is None else self.stream
|
|
@@ -3590,6 +3587,9 @@ class Agent:
|
|
|
3590
3587
|
else:
|
|
3591
3588
|
merge_dictionaries(metadata, self.metadata)
|
|
3592
3589
|
|
|
3590
|
+
# Resolve retry parameters
|
|
3591
|
+
num_attempts = self.retries + 1
|
|
3592
|
+
|
|
3593
3593
|
# Prepare arguments for the model
|
|
3594
3594
|
response_format = self._get_response_format(run_context=run_context)
|
|
3595
3595
|
self.model = cast(Model, self.model)
|
|
@@ -3605,9 +3605,9 @@ class Agent:
|
|
|
3605
3605
|
metadata=metadata,
|
|
3606
3606
|
)
|
|
3607
3607
|
|
|
3608
|
-
last_exception = None
|
|
3609
|
-
num_attempts = retries + 1
|
|
3610
3608
|
for attempt in range(num_attempts):
|
|
3609
|
+
log_debug(f"Retrying Agent acontinue_run {run_id}. Attempt {attempt + 1} of {num_attempts}...")
|
|
3610
|
+
|
|
3611
3611
|
try:
|
|
3612
3612
|
if stream:
|
|
3613
3613
|
return self._acontinue_run_stream(
|
|
@@ -3639,19 +3639,6 @@ class Agent:
|
|
|
3639
3639
|
background_tasks=background_tasks,
|
|
3640
3640
|
**kwargs,
|
|
3641
3641
|
)
|
|
3642
|
-
except ModelProviderError as e:
|
|
3643
|
-
log_warning(f"Attempt {attempt + 1}/{num_attempts} failed: {str(e)}")
|
|
3644
|
-
if isinstance(e, StopAgentRun):
|
|
3645
|
-
raise e
|
|
3646
|
-
last_exception = e
|
|
3647
|
-
if attempt < num_attempts - 1: # Don't sleep on the last attempt
|
|
3648
|
-
if self.exponential_backoff:
|
|
3649
|
-
delay = 2**attempt * self.delay_between_retries
|
|
3650
|
-
else:
|
|
3651
|
-
delay = self.delay_between_retries
|
|
3652
|
-
import time
|
|
3653
|
-
|
|
3654
|
-
time.sleep(delay)
|
|
3655
3642
|
except KeyboardInterrupt:
|
|
3656
3643
|
run_response = cast(RunOutput, run_response)
|
|
3657
3644
|
if stream:
|
|
@@ -3662,19 +3649,25 @@ class Agent:
|
|
|
3662
3649
|
run_response.content = "Operation cancelled by user"
|
|
3663
3650
|
run_response.status = RunStatus.cancelled
|
|
3664
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
|
|
3665
3668
|
|
|
3666
3669
|
# If we get here, all retries failed
|
|
3667
|
-
|
|
3668
|
-
log_error(
|
|
3669
|
-
f"Failed after {num_attempts} attempts. Last error using {last_exception.model_name}({last_exception.model_id})"
|
|
3670
|
-
)
|
|
3671
|
-
if stream:
|
|
3672
|
-
return async_generator_wrapper(create_run_error_event(run_response, error=str(last_exception))) # type: ignore
|
|
3673
|
-
raise last_exception
|
|
3674
|
-
else:
|
|
3675
|
-
if stream:
|
|
3676
|
-
return async_generator_wrapper(create_run_error_event(run_response, error=str(last_exception))) # type: ignore
|
|
3677
|
-
raise Exception(f"Failed after {num_attempts} attempts.")
|
|
3670
|
+
raise Exception(f"Failed after {num_attempts} attempts.")
|
|
3678
3671
|
|
|
3679
3672
|
async def _acontinue_run(
|
|
3680
3673
|
self,
|
|
@@ -3853,7 +3846,7 @@ class Agent:
|
|
|
3853
3846
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
3854
3847
|
|
|
3855
3848
|
# 13. Create session summary
|
|
3856
|
-
if self.session_summary_manager is not None:
|
|
3849
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
3857
3850
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
3858
3851
|
agent_session.upsert_run(run=run_response)
|
|
3859
3852
|
|
|
@@ -4126,7 +4119,7 @@ class Agent:
|
|
|
4126
4119
|
raise_if_cancelled(run_response.run_id) # type: ignore
|
|
4127
4120
|
|
|
4128
4121
|
# 9. Create session summary
|
|
4129
|
-
if self.session_summary_manager is not None:
|
|
4122
|
+
if self.session_summary_manager is not None and self.enable_session_summaries:
|
|
4130
4123
|
# Upsert the RunOutput to Agent Session before creating the session summary
|
|
4131
4124
|
agent_session.upsert_run(run=run_response)
|
|
4132
4125
|
|
|
@@ -5667,7 +5660,12 @@ class Agent:
|
|
|
5667
5660
|
user_message_str = (
|
|
5668
5661
|
run_messages.user_message.get_content_string() if run_messages.user_message is not None else None
|
|
5669
5662
|
)
|
|
5670
|
-
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
|
+
):
|
|
5671
5669
|
log_debug("Managing user memories")
|
|
5672
5670
|
self.memory_manager.create_user_memories( # type: ignore
|
|
5673
5671
|
message=user_message_str,
|
|
@@ -5695,7 +5693,7 @@ class Agent:
|
|
|
5695
5693
|
for msg in parsed_messages
|
|
5696
5694
|
if msg.content and (not isinstance(msg.content, str) or msg.content.strip() != "")
|
|
5697
5695
|
]
|
|
5698
|
-
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:
|
|
5699
5697
|
self.memory_manager.create_user_memories(messages=non_empty_messages, user_id=user_id, agent_id=self.id) # type: ignore
|
|
5700
5698
|
else:
|
|
5701
5699
|
log_warning("Unable to add messages to memory")
|
|
@@ -5708,7 +5706,12 @@ class Agent:
|
|
|
5708
5706
|
user_message_str = (
|
|
5709
5707
|
run_messages.user_message.get_content_string() if run_messages.user_message is not None else None
|
|
5710
5708
|
)
|
|
5711
|
-
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
|
+
):
|
|
5712
5715
|
log_debug("Managing user memories")
|
|
5713
5716
|
await self.memory_manager.acreate_user_memories( # type: ignore
|
|
5714
5717
|
message=user_message_str,
|
|
@@ -5736,7 +5739,7 @@ class Agent:
|
|
|
5736
5739
|
for msg in parsed_messages
|
|
5737
5740
|
if msg.content and (not isinstance(msg.content, str) or msg.content.strip() != "")
|
|
5738
5741
|
]
|
|
5739
|
-
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:
|
|
5740
5743
|
await self.memory_manager.acreate_user_memories( # type: ignore
|
|
5741
5744
|
messages=non_empty_messages, user_id=user_id, agent_id=self.id
|
|
5742
5745
|
)
|
|
@@ -7068,12 +7071,13 @@ class Agent:
|
|
|
7068
7071
|
Optional[List[UserMemory]]: The user memories.
|
|
7069
7072
|
"""
|
|
7070
7073
|
if self.memory_manager is None:
|
|
7071
|
-
|
|
7074
|
+
self._set_memory_manager()
|
|
7075
|
+
|
|
7072
7076
|
user_id = user_id if user_id is not None else self.user_id
|
|
7073
7077
|
if user_id is None:
|
|
7074
7078
|
user_id = "default"
|
|
7075
7079
|
|
|
7076
|
-
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
|
|
7077
7081
|
|
|
7078
7082
|
async def aget_user_memories(self, user_id: Optional[str] = None) -> Optional[List[UserMemory]]:
|
|
7079
7083
|
"""Get the user memories for the given user ID.
|
|
@@ -7084,12 +7088,13 @@ class Agent:
|
|
|
7084
7088
|
Optional[List[UserMemory]]: The user memories.
|
|
7085
7089
|
"""
|
|
7086
7090
|
if self.memory_manager is None:
|
|
7087
|
-
|
|
7091
|
+
self._set_memory_manager()
|
|
7092
|
+
|
|
7088
7093
|
user_id = user_id if user_id is not None else self.user_id
|
|
7089
7094
|
if user_id is None:
|
|
7090
7095
|
user_id = "default"
|
|
7091
7096
|
|
|
7092
|
-
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
|
|
7093
7098
|
|
|
7094
7099
|
def get_culture_knowledge(self) -> Optional[List[CulturalKnowledge]]:
|
|
7095
7100
|
"""Get the cultural knowledge the agent has access to
|
|
@@ -10248,9 +10253,8 @@ class Agent:
|
|
|
10248
10253
|
"""
|
|
10249
10254
|
retrieval_timer = Timer()
|
|
10250
10255
|
retrieval_timer.start()
|
|
10251
|
-
dependencies = run_context.dependencies if run_context else None
|
|
10252
10256
|
docs_from_knowledge = await self.aget_relevant_docs_from_knowledge(
|
|
10253
|
-
query=query, filters=knowledge_filters,
|
|
10257
|
+
query=query, filters=knowledge_filters, run_context=run_context
|
|
10254
10258
|
)
|
|
10255
10259
|
if docs_from_knowledge is not None:
|
|
10256
10260
|
references = MessageReferences(
|