agno 2.1.2__py3-none-any.whl → 2.3.13__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 +5540 -2273
- agno/api/api.py +2 -0
- agno/api/os.py +1 -1
- agno/compression/__init__.py +3 -0
- agno/compression/manager.py +247 -0
- agno/culture/__init__.py +3 -0
- agno/culture/manager.py +956 -0
- agno/db/async_postgres/__init__.py +3 -0
- agno/db/base.py +689 -6
- agno/db/dynamo/dynamo.py +933 -37
- agno/db/dynamo/schemas.py +174 -10
- agno/db/dynamo/utils.py +63 -4
- agno/db/firestore/firestore.py +831 -9
- agno/db/firestore/schemas.py +51 -0
- agno/db/firestore/utils.py +102 -4
- agno/db/gcs_json/gcs_json_db.py +660 -12
- agno/db/gcs_json/utils.py +60 -26
- agno/db/in_memory/in_memory_db.py +287 -14
- agno/db/in_memory/utils.py +60 -2
- agno/db/json/json_db.py +590 -14
- agno/db/json/utils.py +60 -26
- agno/db/migrations/manager.py +199 -0
- agno/db/migrations/v1_to_v2.py +43 -13
- agno/db/migrations/versions/__init__.py +0 -0
- agno/db/migrations/versions/v2_3_0.py +938 -0
- agno/db/mongo/__init__.py +15 -1
- agno/db/mongo/async_mongo.py +2760 -0
- agno/db/mongo/mongo.py +879 -11
- agno/db/mongo/schemas.py +42 -0
- agno/db/mongo/utils.py +80 -8
- agno/db/mysql/__init__.py +2 -1
- agno/db/mysql/async_mysql.py +2912 -0
- agno/db/mysql/mysql.py +946 -68
- agno/db/mysql/schemas.py +72 -10
- agno/db/mysql/utils.py +198 -7
- agno/db/postgres/__init__.py +2 -1
- agno/db/postgres/async_postgres.py +2579 -0
- agno/db/postgres/postgres.py +942 -57
- agno/db/postgres/schemas.py +81 -18
- agno/db/postgres/utils.py +164 -2
- agno/db/redis/redis.py +671 -7
- agno/db/redis/schemas.py +50 -0
- agno/db/redis/utils.py +65 -7
- agno/db/schemas/__init__.py +2 -1
- agno/db/schemas/culture.py +120 -0
- agno/db/schemas/evals.py +1 -0
- agno/db/schemas/memory.py +17 -2
- agno/db/singlestore/schemas.py +63 -0
- agno/db/singlestore/singlestore.py +949 -83
- agno/db/singlestore/utils.py +60 -2
- agno/db/sqlite/__init__.py +2 -1
- agno/db/sqlite/async_sqlite.py +2911 -0
- agno/db/sqlite/schemas.py +62 -0
- agno/db/sqlite/sqlite.py +965 -46
- agno/db/sqlite/utils.py +169 -8
- agno/db/surrealdb/__init__.py +3 -0
- agno/db/surrealdb/metrics.py +292 -0
- agno/db/surrealdb/models.py +334 -0
- agno/db/surrealdb/queries.py +71 -0
- agno/db/surrealdb/surrealdb.py +1908 -0
- agno/db/surrealdb/utils.py +147 -0
- agno/db/utils.py +2 -0
- agno/eval/__init__.py +10 -0
- agno/eval/accuracy.py +75 -55
- agno/eval/agent_as_judge.py +861 -0
- agno/eval/base.py +29 -0
- agno/eval/performance.py +16 -7
- agno/eval/reliability.py +28 -16
- agno/eval/utils.py +35 -17
- agno/exceptions.py +27 -2
- agno/filters.py +354 -0
- agno/guardrails/prompt_injection.py +1 -0
- agno/hooks/__init__.py +3 -0
- agno/hooks/decorator.py +164 -0
- agno/integrations/discord/client.py +1 -1
- agno/knowledge/chunking/agentic.py +13 -10
- agno/knowledge/chunking/fixed.py +4 -1
- agno/knowledge/chunking/semantic.py +9 -4
- agno/knowledge/chunking/strategy.py +59 -15
- agno/knowledge/embedder/fastembed.py +1 -1
- agno/knowledge/embedder/nebius.py +1 -1
- agno/knowledge/embedder/ollama.py +8 -0
- agno/knowledge/embedder/openai.py +8 -8
- agno/knowledge/embedder/sentence_transformer.py +6 -2
- agno/knowledge/embedder/vllm.py +262 -0
- agno/knowledge/knowledge.py +1618 -318
- agno/knowledge/reader/base.py +6 -2
- agno/knowledge/reader/csv_reader.py +8 -10
- agno/knowledge/reader/docx_reader.py +5 -6
- agno/knowledge/reader/field_labeled_csv_reader.py +16 -20
- agno/knowledge/reader/json_reader.py +5 -4
- agno/knowledge/reader/markdown_reader.py +8 -8
- agno/knowledge/reader/pdf_reader.py +17 -19
- agno/knowledge/reader/pptx_reader.py +101 -0
- agno/knowledge/reader/reader_factory.py +32 -3
- agno/knowledge/reader/s3_reader.py +3 -3
- agno/knowledge/reader/tavily_reader.py +193 -0
- agno/knowledge/reader/text_reader.py +22 -10
- agno/knowledge/reader/web_search_reader.py +1 -48
- agno/knowledge/reader/website_reader.py +10 -10
- agno/knowledge/reader/wikipedia_reader.py +33 -1
- agno/knowledge/types.py +1 -0
- agno/knowledge/utils.py +72 -7
- agno/media.py +22 -6
- agno/memory/__init__.py +14 -1
- agno/memory/manager.py +544 -83
- agno/memory/strategies/__init__.py +15 -0
- agno/memory/strategies/base.py +66 -0
- agno/memory/strategies/summarize.py +196 -0
- agno/memory/strategies/types.py +37 -0
- agno/models/aimlapi/aimlapi.py +17 -0
- agno/models/anthropic/claude.py +515 -40
- agno/models/aws/bedrock.py +102 -21
- agno/models/aws/claude.py +131 -274
- agno/models/azure/ai_foundry.py +41 -19
- agno/models/azure/openai_chat.py +39 -8
- agno/models/base.py +1249 -525
- agno/models/cerebras/cerebras.py +91 -21
- agno/models/cerebras/cerebras_openai.py +21 -2
- agno/models/cohere/chat.py +40 -6
- agno/models/cometapi/cometapi.py +18 -1
- agno/models/dashscope/dashscope.py +2 -3
- agno/models/deepinfra/deepinfra.py +18 -1
- agno/models/deepseek/deepseek.py +69 -3
- agno/models/fireworks/fireworks.py +18 -1
- agno/models/google/gemini.py +877 -80
- agno/models/google/utils.py +22 -0
- agno/models/groq/groq.py +51 -18
- agno/models/huggingface/huggingface.py +17 -6
- agno/models/ibm/watsonx.py +16 -6
- agno/models/internlm/internlm.py +18 -1
- agno/models/langdb/langdb.py +13 -1
- agno/models/litellm/chat.py +44 -9
- agno/models/litellm/litellm_openai.py +18 -1
- agno/models/message.py +28 -5
- agno/models/meta/llama.py +47 -14
- agno/models/meta/llama_openai.py +22 -17
- agno/models/mistral/mistral.py +8 -4
- agno/models/nebius/nebius.py +6 -7
- agno/models/nvidia/nvidia.py +20 -3
- agno/models/ollama/chat.py +24 -8
- agno/models/openai/chat.py +104 -29
- agno/models/openai/responses.py +101 -81
- agno/models/openrouter/openrouter.py +60 -3
- agno/models/perplexity/perplexity.py +17 -1
- agno/models/portkey/portkey.py +7 -6
- agno/models/requesty/requesty.py +24 -4
- agno/models/response.py +73 -2
- agno/models/sambanova/sambanova.py +20 -3
- agno/models/siliconflow/siliconflow.py +19 -2
- agno/models/together/together.py +20 -3
- agno/models/utils.py +254 -8
- agno/models/vercel/v0.py +20 -3
- agno/models/vertexai/__init__.py +0 -0
- agno/models/vertexai/claude.py +190 -0
- agno/models/vllm/vllm.py +19 -14
- agno/models/xai/xai.py +19 -2
- agno/os/app.py +549 -152
- agno/os/auth.py +190 -3
- agno/os/config.py +23 -0
- agno/os/interfaces/a2a/router.py +8 -11
- agno/os/interfaces/a2a/utils.py +1 -1
- agno/os/interfaces/agui/router.py +18 -3
- agno/os/interfaces/agui/utils.py +152 -39
- agno/os/interfaces/slack/router.py +55 -37
- agno/os/interfaces/slack/slack.py +9 -1
- agno/os/interfaces/whatsapp/router.py +0 -1
- agno/os/interfaces/whatsapp/security.py +3 -1
- agno/os/mcp.py +110 -52
- agno/os/middleware/__init__.py +2 -0
- agno/os/middleware/jwt.py +676 -112
- agno/os/router.py +40 -1478
- agno/os/routers/agents/__init__.py +3 -0
- agno/os/routers/agents/router.py +599 -0
- agno/os/routers/agents/schema.py +261 -0
- agno/os/routers/evals/evals.py +96 -39
- agno/os/routers/evals/schemas.py +65 -33
- agno/os/routers/evals/utils.py +80 -10
- agno/os/routers/health.py +10 -4
- agno/os/routers/knowledge/knowledge.py +196 -38
- agno/os/routers/knowledge/schemas.py +82 -22
- agno/os/routers/memory/memory.py +279 -52
- agno/os/routers/memory/schemas.py +46 -17
- agno/os/routers/metrics/metrics.py +20 -8
- agno/os/routers/metrics/schemas.py +16 -16
- agno/os/routers/session/session.py +462 -34
- agno/os/routers/teams/__init__.py +3 -0
- agno/os/routers/teams/router.py +512 -0
- agno/os/routers/teams/schema.py +257 -0
- agno/os/routers/traces/__init__.py +3 -0
- agno/os/routers/traces/schemas.py +414 -0
- agno/os/routers/traces/traces.py +499 -0
- agno/os/routers/workflows/__init__.py +3 -0
- agno/os/routers/workflows/router.py +624 -0
- agno/os/routers/workflows/schema.py +75 -0
- agno/os/schema.py +256 -693
- agno/os/scopes.py +469 -0
- agno/os/utils.py +514 -36
- agno/reasoning/anthropic.py +80 -0
- agno/reasoning/gemini.py +73 -0
- agno/reasoning/openai.py +5 -0
- agno/reasoning/vertexai.py +76 -0
- agno/run/__init__.py +6 -0
- agno/run/agent.py +155 -32
- agno/run/base.py +55 -3
- agno/run/requirement.py +181 -0
- agno/run/team.py +125 -38
- agno/run/workflow.py +72 -18
- agno/session/agent.py +102 -89
- agno/session/summary.py +56 -15
- agno/session/team.py +164 -90
- agno/session/workflow.py +405 -40
- agno/table.py +10 -0
- agno/team/team.py +3974 -1903
- agno/tools/dalle.py +2 -4
- agno/tools/eleven_labs.py +23 -25
- agno/tools/exa.py +21 -16
- agno/tools/file.py +153 -23
- agno/tools/file_generation.py +16 -10
- agno/tools/firecrawl.py +15 -7
- agno/tools/function.py +193 -38
- agno/tools/gmail.py +238 -14
- agno/tools/google_drive.py +271 -0
- agno/tools/googlecalendar.py +36 -8
- agno/tools/googlesheets.py +20 -5
- agno/tools/jira.py +20 -0
- agno/tools/mcp/__init__.py +10 -0
- agno/tools/mcp/mcp.py +331 -0
- agno/tools/mcp/multi_mcp.py +347 -0
- agno/tools/mcp/params.py +24 -0
- agno/tools/mcp_toolbox.py +3 -3
- agno/tools/models/nebius.py +5 -5
- agno/tools/models_labs.py +20 -10
- agno/tools/nano_banana.py +151 -0
- agno/tools/notion.py +204 -0
- agno/tools/parallel.py +314 -0
- agno/tools/postgres.py +76 -36
- agno/tools/redshift.py +406 -0
- agno/tools/scrapegraph.py +1 -1
- agno/tools/shopify.py +1519 -0
- agno/tools/slack.py +18 -3
- agno/tools/spotify.py +919 -0
- agno/tools/tavily.py +146 -0
- agno/tools/toolkit.py +25 -0
- agno/tools/workflow.py +8 -1
- agno/tools/yfinance.py +12 -11
- agno/tracing/__init__.py +12 -0
- agno/tracing/exporter.py +157 -0
- agno/tracing/schemas.py +276 -0
- agno/tracing/setup.py +111 -0
- agno/utils/agent.py +938 -0
- agno/utils/cryptography.py +22 -0
- agno/utils/dttm.py +33 -0
- agno/utils/events.py +151 -3
- agno/utils/gemini.py +15 -5
- agno/utils/hooks.py +118 -4
- agno/utils/http.py +113 -2
- agno/utils/knowledge.py +12 -5
- agno/utils/log.py +1 -0
- agno/utils/mcp.py +92 -2
- agno/utils/media.py +187 -1
- agno/utils/merge_dict.py +3 -3
- agno/utils/message.py +60 -0
- agno/utils/models/ai_foundry.py +9 -2
- agno/utils/models/claude.py +49 -14
- agno/utils/models/cohere.py +9 -2
- agno/utils/models/llama.py +9 -2
- agno/utils/models/mistral.py +4 -2
- agno/utils/print_response/agent.py +109 -16
- agno/utils/print_response/team.py +223 -30
- agno/utils/print_response/workflow.py +251 -34
- agno/utils/streamlit.py +1 -1
- agno/utils/team.py +98 -9
- agno/utils/tokens.py +657 -0
- agno/vectordb/base.py +39 -7
- agno/vectordb/cassandra/cassandra.py +21 -5
- agno/vectordb/chroma/chromadb.py +43 -12
- agno/vectordb/clickhouse/clickhousedb.py +21 -5
- agno/vectordb/couchbase/couchbase.py +29 -5
- agno/vectordb/lancedb/lance_db.py +92 -181
- agno/vectordb/langchaindb/langchaindb.py +24 -4
- agno/vectordb/lightrag/lightrag.py +17 -3
- agno/vectordb/llamaindex/llamaindexdb.py +25 -5
- agno/vectordb/milvus/milvus.py +50 -37
- agno/vectordb/mongodb/__init__.py +7 -1
- agno/vectordb/mongodb/mongodb.py +36 -30
- agno/vectordb/pgvector/pgvector.py +201 -77
- agno/vectordb/pineconedb/pineconedb.py +41 -23
- agno/vectordb/qdrant/qdrant.py +67 -54
- agno/vectordb/redis/__init__.py +9 -0
- agno/vectordb/redis/redisdb.py +682 -0
- agno/vectordb/singlestore/singlestore.py +50 -29
- agno/vectordb/surrealdb/surrealdb.py +31 -41
- agno/vectordb/upstashdb/upstashdb.py +34 -6
- agno/vectordb/weaviate/weaviate.py +53 -14
- agno/workflow/__init__.py +2 -0
- agno/workflow/agent.py +299 -0
- agno/workflow/condition.py +120 -18
- agno/workflow/loop.py +77 -10
- agno/workflow/parallel.py +231 -143
- agno/workflow/router.py +118 -17
- agno/workflow/step.py +609 -170
- agno/workflow/steps.py +73 -6
- agno/workflow/types.py +96 -21
- agno/workflow/workflow.py +2039 -262
- {agno-2.1.2.dist-info → agno-2.3.13.dist-info}/METADATA +201 -66
- agno-2.3.13.dist-info/RECORD +613 -0
- agno/tools/googlesearch.py +0 -98
- agno/tools/mcp.py +0 -679
- agno/tools/memori.py +0 -339
- agno-2.1.2.dist-info/RECORD +0 -543
- {agno-2.1.2.dist-info → agno-2.3.13.dist-info}/WHEEL +0 -0
- {agno-2.1.2.dist-info → agno-2.3.13.dist-info}/licenses/LICENSE +0 -0
- {agno-2.1.2.dist-info → agno-2.3.13.dist-info}/top_level.txt +0 -0
agno/session/team.py
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import asdict, dataclass
|
|
4
|
-
from typing import Any, Dict, List, Mapping, Optional, Union
|
|
4
|
+
from typing import Any, Dict, List, Mapping, Optional, Tuple, Union
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
5
7
|
|
|
6
8
|
from agno.models.message import Message
|
|
7
9
|
from agno.run.agent import RunOutput, RunStatus
|
|
@@ -111,77 +113,136 @@ class TeamSession:
|
|
|
111
113
|
|
|
112
114
|
log_debug("Added RunOutput to Team Session")
|
|
113
115
|
|
|
114
|
-
def
|
|
116
|
+
def get_messages(
|
|
115
117
|
self,
|
|
116
|
-
agent_id: Optional[str] = None,
|
|
117
118
|
team_id: Optional[str] = None,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
member_ids: Optional[List[str]] = None,
|
|
120
|
+
last_n_runs: Optional[int] = None,
|
|
121
|
+
limit: Optional[int] = None,
|
|
122
|
+
skip_roles: Optional[List[str]] = None,
|
|
123
|
+
skip_statuses: Optional[List[RunStatus]] = None,
|
|
121
124
|
skip_history_messages: bool = True,
|
|
122
|
-
|
|
125
|
+
skip_member_messages: bool = True,
|
|
123
126
|
) -> List[Message]:
|
|
124
|
-
"""Returns the messages
|
|
125
|
-
Args:
|
|
127
|
+
"""Returns the messages belonging to the session that fit the given criteria.
|
|
126
128
|
|
|
127
|
-
|
|
129
|
+
Args:
|
|
128
130
|
team_id: The id of the team to get the messages from.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
131
|
+
member_ids: The ids of the members to get the messages from.
|
|
132
|
+
last_n_runs: The number of runs to return messages from, counting from the latest. Defaults to all runs.
|
|
133
|
+
limit: The number of messages to return, counting from the latest. Defaults to all messages.
|
|
134
|
+
skip_roles: Skip messages with these roles.
|
|
135
|
+
skip_statuses: Skip messages with these statuses.
|
|
132
136
|
skip_history_messages: Skip messages that were tagged as history in previous runs.
|
|
137
|
+
skip_member_messages: Skip messages created by members of the team.
|
|
138
|
+
|
|
133
139
|
Returns:
|
|
134
|
-
A list of Messages
|
|
140
|
+
A list of Messages belonging to the session.
|
|
135
141
|
"""
|
|
142
|
+
|
|
143
|
+
def _should_skip_message(
|
|
144
|
+
message: Message, skip_roles: Optional[List[str]] = None, skip_history_messages: bool = True
|
|
145
|
+
) -> bool:
|
|
146
|
+
"""Processes a message for history"""
|
|
147
|
+
# Skip messages that were tagged as history in previous runs
|
|
148
|
+
if hasattr(message, "from_history") and message.from_history and skip_history_messages:
|
|
149
|
+
return True
|
|
150
|
+
|
|
151
|
+
# Skip messages with specified role
|
|
152
|
+
if skip_roles and message.role in skip_roles:
|
|
153
|
+
return True
|
|
154
|
+
return False
|
|
155
|
+
|
|
156
|
+
if member_ids is not None and skip_member_messages:
|
|
157
|
+
log_debug("Member IDs to filter by were provided. The skip_member_messages flag will be ignored.")
|
|
158
|
+
skip_member_messages = False
|
|
159
|
+
|
|
136
160
|
if not self.runs:
|
|
137
161
|
return []
|
|
138
162
|
|
|
139
|
-
if
|
|
140
|
-
|
|
163
|
+
if skip_statuses is None:
|
|
164
|
+
skip_statuses = [RunStatus.paused, RunStatus.cancelled, RunStatus.error]
|
|
141
165
|
|
|
142
166
|
session_runs = self.runs
|
|
143
167
|
|
|
144
|
-
# Filter by
|
|
145
|
-
if agent_id:
|
|
146
|
-
session_runs = [run for run in session_runs if hasattr(run, "agent_id") and run.agent_id == agent_id] # type: ignore
|
|
168
|
+
# Filter by team_id and member_ids
|
|
147
169
|
if team_id:
|
|
148
170
|
session_runs = [run for run in session_runs if hasattr(run, "team_id") and run.team_id == team_id] # type: ignore
|
|
171
|
+
if member_ids:
|
|
172
|
+
session_runs = [run for run in session_runs if hasattr(run, "agent_id") and run.agent_id in member_ids] # type: ignore
|
|
149
173
|
|
|
150
|
-
if
|
|
151
|
-
# Filter for the main team runs
|
|
174
|
+
if skip_member_messages:
|
|
175
|
+
# Filter for the top-level runs (main team runs or agent runs when sharing session)
|
|
152
176
|
session_runs = [run for run in session_runs if run.parent_run_id is None] # type: ignore
|
|
177
|
+
|
|
153
178
|
# Filter by status
|
|
154
|
-
session_runs = [run for run in session_runs if hasattr(run, "status") and run.status not in
|
|
179
|
+
session_runs = [run for run in session_runs if hasattr(run, "status") and run.status not in skip_statuses] # type: ignore
|
|
155
180
|
|
|
156
|
-
# Filter by last_n
|
|
157
|
-
runs_to_process = session_runs[-last_n:] if last_n is not None else session_runs
|
|
158
181
|
messages_from_history = []
|
|
159
182
|
system_message = None
|
|
160
183
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
for message in run_response.messages or []:
|
|
166
|
-
# Skip messages that were tagged as history in previous runs
|
|
167
|
-
if hasattr(message, "from_history") and message.from_history and skip_history_messages:
|
|
184
|
+
# Limit the number of messages returned if limit is set
|
|
185
|
+
if limit is not None:
|
|
186
|
+
for run_response in session_runs:
|
|
187
|
+
if not run_response or not run_response.messages:
|
|
168
188
|
continue
|
|
169
189
|
|
|
170
|
-
|
|
171
|
-
|
|
190
|
+
for message in run_response.messages or []:
|
|
191
|
+
if _should_skip_message(message, skip_roles, skip_history_messages):
|
|
192
|
+
continue
|
|
193
|
+
|
|
194
|
+
if message.role == "system":
|
|
195
|
+
# Only add the system message once
|
|
196
|
+
if system_message is None:
|
|
197
|
+
system_message = message
|
|
198
|
+
else:
|
|
199
|
+
messages_from_history.append(message)
|
|
200
|
+
|
|
201
|
+
if system_message:
|
|
202
|
+
messages_from_history = [system_message] + messages_from_history[
|
|
203
|
+
-(limit - 1) :
|
|
204
|
+
] # Grab one less message then add the system message
|
|
205
|
+
else:
|
|
206
|
+
messages_from_history = messages_from_history[-limit:]
|
|
207
|
+
|
|
208
|
+
# Remove tool result messages that don't have an associated assistant message with tool calls
|
|
209
|
+
while len(messages_from_history) > 0 and messages_from_history[0].role == "tool":
|
|
210
|
+
messages_from_history.pop(0)
|
|
211
|
+
else:
|
|
212
|
+
# Filter by last_n runs
|
|
213
|
+
runs_to_process = session_runs[-last_n_runs:] if last_n_runs is not None else session_runs
|
|
214
|
+
|
|
215
|
+
for run_response in runs_to_process:
|
|
216
|
+
if not (run_response and run_response.messages):
|
|
172
217
|
continue
|
|
173
218
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
219
|
+
for message in run_response.messages or []:
|
|
220
|
+
if _should_skip_message(message, skip_roles, skip_history_messages):
|
|
221
|
+
continue
|
|
222
|
+
|
|
223
|
+
if message.role == "system":
|
|
224
|
+
# Only add the system message once
|
|
225
|
+
if system_message is None:
|
|
226
|
+
system_message = message
|
|
227
|
+
messages_from_history.append(system_message)
|
|
228
|
+
else:
|
|
229
|
+
messages_from_history.append(message)
|
|
181
230
|
|
|
182
231
|
log_debug(f"Getting messages from previous runs: {len(messages_from_history)}")
|
|
183
232
|
return messages_from_history
|
|
184
233
|
|
|
234
|
+
def get_chat_history(self, last_n_runs: Optional[int] = None) -> List[Message]:
|
|
235
|
+
"""Return the chat history (user and assistant messages) for the session.
|
|
236
|
+
Use get_messages() for more filtering options.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
last_n_runs: Number of recent runs to include. If None, all runs will be considered.
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
A list of user and assistant Messages belonging to the session.
|
|
243
|
+
"""
|
|
244
|
+
return self.get_messages(skip_roles=["system", "tool"], skip_member_messages=True, last_n_runs=last_n_runs)
|
|
245
|
+
|
|
185
246
|
def get_tool_calls(self, num_calls: Optional[int] = None) -> List[Dict[str, Any]]:
|
|
186
247
|
"""Returns a list of tool calls from the messages"""
|
|
187
248
|
|
|
@@ -200,69 +261,82 @@ class TeamSession:
|
|
|
200
261
|
return tool_calls
|
|
201
262
|
return tool_calls
|
|
202
263
|
|
|
203
|
-
def
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
264
|
+
def get_team_history(self, num_runs: Optional[int] = None) -> List[Tuple[str, str]]:
|
|
265
|
+
"""Get team history as structured data (input, response pairs) -> This is the history of the team leader, not the members.
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
num_runs: Number of recent runs to include. If None, returns all available history.
|
|
269
|
+
"""
|
|
270
|
+
if not self.runs:
|
|
271
|
+
return []
|
|
210
272
|
|
|
211
|
-
|
|
212
|
-
# TODO: Check if we still need CHATBOT as a role
|
|
213
|
-
assistant_role = ["assistant", "model", "CHATBOT"]
|
|
273
|
+
from agno.run.base import RunStatus
|
|
214
274
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
275
|
+
# Get completed runs only (exclude current/pending run)
|
|
276
|
+
completed_runs = [run for run in self.runs if run.status == RunStatus.completed and run.parent_run_id is None]
|
|
277
|
+
|
|
278
|
+
if num_runs is not None and len(completed_runs) > num_runs:
|
|
279
|
+
recent_runs = completed_runs[-num_runs:]
|
|
280
|
+
else:
|
|
281
|
+
recent_runs = completed_runs
|
|
282
|
+
|
|
283
|
+
if not recent_runs:
|
|
218
284
|
return []
|
|
219
285
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
286
|
+
# Return structured data as list of (input, response) tuples
|
|
287
|
+
history_data = []
|
|
288
|
+
for run in recent_runs:
|
|
289
|
+
# Get input
|
|
290
|
+
input_str = ""
|
|
291
|
+
if run.input:
|
|
292
|
+
input_str = run.input.input_content_string()
|
|
224
293
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
294
|
+
# Get response
|
|
295
|
+
response_str = ""
|
|
296
|
+
if run.content:
|
|
297
|
+
response_str = (
|
|
298
|
+
run.content.model_dump_json(indent=2, exclude_none=True)
|
|
299
|
+
if isinstance(run.content, BaseModel)
|
|
300
|
+
else str(run.content)
|
|
301
|
+
)
|
|
232
302
|
|
|
233
|
-
|
|
234
|
-
for message in run_response.messages[::-1]:
|
|
235
|
-
if hasattr(message, "from_history") and message.from_history and skip_history_messages:
|
|
236
|
-
continue
|
|
237
|
-
if message.role in assistant_role:
|
|
238
|
-
assistant_message_from_run = message
|
|
239
|
-
break
|
|
303
|
+
history_data.append((input_str, response_str))
|
|
240
304
|
|
|
241
|
-
|
|
242
|
-
final_messages.append(user_message_from_run)
|
|
243
|
-
final_messages.append(assistant_message_from_run)
|
|
244
|
-
return final_messages
|
|
305
|
+
return history_data
|
|
245
306
|
|
|
246
|
-
def
|
|
247
|
-
"""Get
|
|
307
|
+
def get_team_history_context(self, num_runs: Optional[int] = None) -> Optional[str]:
|
|
308
|
+
"""Get formatted team history context for steps
|
|
248
309
|
|
|
249
|
-
|
|
310
|
+
Args:
|
|
311
|
+
num_runs: Number of recent runs to include. If None, returns all available history.
|
|
312
|
+
"""
|
|
313
|
+
history_data = self.get_team_history(num_runs)
|
|
314
|
+
|
|
315
|
+
if not history_data:
|
|
250
316
|
return None
|
|
251
317
|
|
|
252
|
-
|
|
318
|
+
# Format as team history context using the structured data
|
|
319
|
+
context_parts = ["<team_history_context>"]
|
|
253
320
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
"""Get the chat history for the session"""
|
|
321
|
+
for i, (input_str, response_str) in enumerate(history_data, 1):
|
|
322
|
+
context_parts.append(f"[run-{i}]")
|
|
257
323
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
324
|
+
if input_str:
|
|
325
|
+
context_parts.append(f"input: {input_str}")
|
|
326
|
+
if response_str:
|
|
327
|
+
context_parts.append(f"response: {response_str}")
|
|
261
328
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
329
|
+
context_parts.append("") # Empty line between runs
|
|
330
|
+
|
|
331
|
+
context_parts.append("</team_history_context>")
|
|
332
|
+
context_parts.append("") # Empty line before current input
|
|
265
333
|
|
|
266
|
-
|
|
334
|
+
return "\n".join(context_parts)
|
|
267
335
|
|
|
268
|
-
|
|
336
|
+
def get_session_summary(self) -> Optional[SessionSummary]:
|
|
337
|
+
"""Get the session summary for the session"""
|
|
338
|
+
|
|
339
|
+
if self.summary is None:
|
|
340
|
+
return None
|
|
341
|
+
|
|
342
|
+
return self.summary # type: ignore
|