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
|
@@ -2,6 +2,7 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Set, Unio
|
|
|
2
2
|
|
|
3
3
|
from pydantic import BaseModel
|
|
4
4
|
|
|
5
|
+
from agno.filters import FilterExpr
|
|
5
6
|
from agno.media import Audio, File, Image, Video
|
|
6
7
|
from agno.models.message import Message
|
|
7
8
|
from agno.models.response import ToolExecution
|
|
@@ -24,16 +25,18 @@ def print_response(
|
|
|
24
25
|
show_message: bool = True,
|
|
25
26
|
show_reasoning: bool = True,
|
|
26
27
|
show_full_reasoning: bool = False,
|
|
28
|
+
show_member_responses: Optional[bool] = None,
|
|
27
29
|
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
28
30
|
session_id: Optional[str] = None,
|
|
29
31
|
session_state: Optional[Dict[str, Any]] = None,
|
|
30
32
|
user_id: Optional[str] = None,
|
|
33
|
+
run_id: Optional[str] = None,
|
|
31
34
|
audio: Optional[Sequence[Audio]] = None,
|
|
32
35
|
images: Optional[Sequence[Image]] = None,
|
|
33
36
|
videos: Optional[Sequence[Video]] = None,
|
|
34
37
|
files: Optional[Sequence[File]] = None,
|
|
35
38
|
markdown: bool = False,
|
|
36
|
-
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
39
|
+
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
37
40
|
add_history_to_context: Optional[bool] = None,
|
|
38
41
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
39
42
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -79,11 +82,13 @@ def print_response(
|
|
|
79
82
|
# Run the agent
|
|
80
83
|
run_response: TeamRunOutput = team.run( # type: ignore
|
|
81
84
|
input=input,
|
|
85
|
+
run_id=run_id,
|
|
82
86
|
images=images,
|
|
83
87
|
audio=audio,
|
|
84
88
|
videos=videos,
|
|
85
89
|
files=files,
|
|
86
90
|
stream=False,
|
|
91
|
+
stream_events=True,
|
|
87
92
|
session_id=session_id,
|
|
88
93
|
session_state=session_state,
|
|
89
94
|
user_id=user_id,
|
|
@@ -151,7 +156,7 @@ def print_response(
|
|
|
151
156
|
|
|
152
157
|
if isinstance(run_response, TeamRunOutput):
|
|
153
158
|
# Handle member responses
|
|
154
|
-
if
|
|
159
|
+
if show_member_responses:
|
|
155
160
|
for member_response in run_response.member_responses:
|
|
156
161
|
# Handle member reasoning
|
|
157
162
|
reasoning_steps = []
|
|
@@ -224,11 +229,23 @@ def print_response(
|
|
|
224
229
|
panels.append(member_response_panel)
|
|
225
230
|
|
|
226
231
|
if member_response.citations is not None and member_response.citations.urls is not None:
|
|
227
|
-
|
|
232
|
+
md_lines = []
|
|
233
|
+
|
|
234
|
+
# Add search queries if present
|
|
235
|
+
if member_response.citations.search_queries:
|
|
236
|
+
md_lines.append("**Search Queries:**")
|
|
237
|
+
for query in member_response.citations.search_queries:
|
|
238
|
+
md_lines.append(f"- {query}")
|
|
239
|
+
md_lines.append("") # Empty line before URLs
|
|
240
|
+
|
|
241
|
+
# Add URL citations
|
|
242
|
+
md_lines.extend(
|
|
228
243
|
f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
|
|
229
244
|
for i, citation in enumerate(member_response.citations.urls)
|
|
230
245
|
if citation.url # Only include citations with valid URLs
|
|
231
246
|
)
|
|
247
|
+
|
|
248
|
+
md_content = "\n".join(md_lines)
|
|
232
249
|
if md_content: # Only create panel if there are citations
|
|
233
250
|
citations_panel = create_panel(
|
|
234
251
|
content=Markdown(md_content),
|
|
@@ -257,6 +274,15 @@ def print_response(
|
|
|
257
274
|
# Join with blank lines between items
|
|
258
275
|
tool_calls_text = "\n\n".join(lines)
|
|
259
276
|
|
|
277
|
+
# Add compression stats at end of tool calls
|
|
278
|
+
if team.compression_manager is not None and team.compression_manager.stats:
|
|
279
|
+
stats = team.compression_manager.stats
|
|
280
|
+
saved = stats.get("original_size", 0) - stats.get("compressed_size", 0)
|
|
281
|
+
orig = stats.get("original_size", 1)
|
|
282
|
+
if stats.get("tool_results_compressed", 0) > 0:
|
|
283
|
+
tool_calls_text += f"\n\ncompressed: {stats.get('tool_results_compressed', 0)} | Saved: {saved:,} chars ({saved / orig * 100:.0f}%)"
|
|
284
|
+
team.compression_manager.stats.clear()
|
|
285
|
+
|
|
260
286
|
team_tool_calls_panel = create_panel(
|
|
261
287
|
content=tool_calls_text,
|
|
262
288
|
title="Team Tool Calls",
|
|
@@ -279,11 +305,23 @@ def print_response(
|
|
|
279
305
|
|
|
280
306
|
# Add citations
|
|
281
307
|
if run_response.citations is not None and run_response.citations.urls is not None:
|
|
282
|
-
|
|
308
|
+
md_lines = []
|
|
309
|
+
|
|
310
|
+
# Add search queries if present
|
|
311
|
+
if run_response.citations.search_queries:
|
|
312
|
+
md_lines.append("**Search Queries:**")
|
|
313
|
+
for query in run_response.citations.search_queries:
|
|
314
|
+
md_lines.append(f"- {query}")
|
|
315
|
+
md_lines.append("") # Empty line before URLs
|
|
316
|
+
|
|
317
|
+
# Add URL citations
|
|
318
|
+
md_lines.extend(
|
|
283
319
|
f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
|
|
284
320
|
for i, citation in enumerate(run_response.citations.urls)
|
|
285
321
|
if citation.url # Only include citations with valid URLs
|
|
286
322
|
)
|
|
323
|
+
|
|
324
|
+
md_content = "\n".join(md_lines)
|
|
287
325
|
if md_content: # Only create panel if there are citations
|
|
288
326
|
citations_panel = create_panel(
|
|
289
327
|
content=Markdown(md_content),
|
|
@@ -322,17 +360,20 @@ def print_response_stream(
|
|
|
322
360
|
show_message: bool = True,
|
|
323
361
|
show_reasoning: bool = True,
|
|
324
362
|
show_full_reasoning: bool = False,
|
|
363
|
+
show_member_responses: Optional[bool] = None,
|
|
325
364
|
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
326
365
|
session_id: Optional[str] = None,
|
|
327
366
|
session_state: Optional[Dict[str, Any]] = None,
|
|
328
367
|
user_id: Optional[str] = None,
|
|
368
|
+
run_id: Optional[str] = None,
|
|
329
369
|
audio: Optional[Sequence[Audio]] = None,
|
|
330
370
|
images: Optional[Sequence[Image]] = None,
|
|
331
371
|
videos: Optional[Sequence[Video]] = None,
|
|
332
372
|
files: Optional[Sequence[File]] = None,
|
|
333
373
|
markdown: bool = False,
|
|
374
|
+
stream_events: bool = False,
|
|
334
375
|
stream_intermediate_steps: bool = False, # type: ignore
|
|
335
|
-
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
376
|
+
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
336
377
|
add_history_to_context: Optional[bool] = None,
|
|
337
378
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
338
379
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -355,7 +396,7 @@ def print_response_stream(
|
|
|
355
396
|
if not tags_to_include_in_markdown:
|
|
356
397
|
tags_to_include_in_markdown = {"think", "thinking"}
|
|
357
398
|
|
|
358
|
-
|
|
399
|
+
stream_events = True # With streaming print response, we need to stream intermediate steps
|
|
359
400
|
|
|
360
401
|
_response_content: str = ""
|
|
361
402
|
_response_reasoning_content: str = ""
|
|
@@ -399,10 +440,11 @@ def print_response_stream(
|
|
|
399
440
|
videos=videos,
|
|
400
441
|
files=files,
|
|
401
442
|
stream=True,
|
|
402
|
-
|
|
443
|
+
stream_events=stream_events,
|
|
403
444
|
session_id=session_id,
|
|
404
445
|
session_state=session_state,
|
|
405
446
|
user_id=user_id,
|
|
447
|
+
run_id=run_id,
|
|
406
448
|
knowledge_filters=knowledge_filters,
|
|
407
449
|
add_history_to_context=add_history_to_context,
|
|
408
450
|
dependencies=dependencies,
|
|
@@ -410,7 +452,7 @@ def print_response_stream(
|
|
|
410
452
|
add_session_state_to_context=add_session_state_to_context,
|
|
411
453
|
metadata=metadata,
|
|
412
454
|
debug_mode=debug_mode,
|
|
413
|
-
|
|
455
|
+
yield_run_output=True,
|
|
414
456
|
**kwargs,
|
|
415
457
|
)
|
|
416
458
|
|
|
@@ -468,7 +510,7 @@ def print_response_stream(
|
|
|
468
510
|
team_tool_calls.append(tool)
|
|
469
511
|
|
|
470
512
|
# Collect member tool calls, avoiding duplicates
|
|
471
|
-
if hasattr(resp, "member_responses") and resp.member_responses:
|
|
513
|
+
if show_member_responses and hasattr(resp, "member_responses") and resp.member_responses:
|
|
472
514
|
for member_response in resp.member_responses:
|
|
473
515
|
member_id = None
|
|
474
516
|
if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
|
|
@@ -530,7 +572,9 @@ def print_response_stream(
|
|
|
530
572
|
panels.append(status)
|
|
531
573
|
|
|
532
574
|
# Process member responses and their tool calls
|
|
533
|
-
for member_response in
|
|
575
|
+
for member_response in (
|
|
576
|
+
resp.member_responses if show_member_responses and hasattr(resp, "member_responses") else []
|
|
577
|
+
):
|
|
534
578
|
member_id = None
|
|
535
579
|
member_name = "Team Member"
|
|
536
580
|
if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
|
|
@@ -563,7 +607,7 @@ def print_response_stream(
|
|
|
563
607
|
panels.append(member_tool_calls_panel)
|
|
564
608
|
|
|
565
609
|
# Process member response content
|
|
566
|
-
if
|
|
610
|
+
if show_member_responses and member_id is not None:
|
|
567
611
|
show_markdown = False
|
|
568
612
|
if markdown:
|
|
569
613
|
show_markdown = True
|
|
@@ -606,6 +650,14 @@ def print_response_stream(
|
|
|
606
650
|
# Join with blank lines between items
|
|
607
651
|
tool_calls_text = "\n\n".join(lines)
|
|
608
652
|
|
|
653
|
+
# Add compression stats if available (don't clear - will be cleared in final_panels)
|
|
654
|
+
if team.compression_manager is not None and team.compression_manager.stats:
|
|
655
|
+
stats = team.compression_manager.stats
|
|
656
|
+
saved = stats.get("original_size", 0) - stats.get("compressed_size", 0)
|
|
657
|
+
orig = stats.get("original_size", 1)
|
|
658
|
+
if stats.get("tool_results_compressed", 0) > 0:
|
|
659
|
+
tool_calls_text += f"\n\ncompressed: {stats.get('tool_results_compressed', 0)} | Saved: {saved:,} chars ({saved / orig * 100:.0f}%)"
|
|
660
|
+
|
|
609
661
|
team_tool_calls_panel = create_panel(
|
|
610
662
|
content=tool_calls_text,
|
|
611
663
|
title="Team Tool Calls",
|
|
@@ -632,11 +684,23 @@ def print_response_stream(
|
|
|
632
684
|
|
|
633
685
|
# Add citations
|
|
634
686
|
if hasattr(resp, "citations") and resp.citations is not None and resp.citations.urls is not None:
|
|
635
|
-
|
|
687
|
+
md_lines = []
|
|
688
|
+
|
|
689
|
+
# Add search queries if present
|
|
690
|
+
if resp.citations.search_queries:
|
|
691
|
+
md_lines.append("**Search Queries:**")
|
|
692
|
+
for query in resp.citations.search_queries:
|
|
693
|
+
md_lines.append(f"- {query}")
|
|
694
|
+
md_lines.append("") # Empty line before URLs
|
|
695
|
+
|
|
696
|
+
# Add URL citations
|
|
697
|
+
md_lines.extend(
|
|
636
698
|
f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
|
|
637
699
|
for i, citation in enumerate(resp.citations.urls)
|
|
638
700
|
if citation.url # Only include citations with valid URLs
|
|
639
701
|
)
|
|
702
|
+
|
|
703
|
+
md_content = "\n".join(md_lines)
|
|
640
704
|
if md_content: # Only create panel if there are citations
|
|
641
705
|
citations_panel = create_panel(
|
|
642
706
|
content=Markdown(md_content),
|
|
@@ -706,7 +770,7 @@ def print_response_stream(
|
|
|
706
770
|
final_panels.append(thinking_panel)
|
|
707
771
|
|
|
708
772
|
# Add member tool calls and responses in correct order
|
|
709
|
-
if run_response is not None and hasattr(run_response, "member_responses"):
|
|
773
|
+
if show_member_responses and run_response is not None and hasattr(run_response, "member_responses"):
|
|
710
774
|
for i, member_response in enumerate(run_response.member_responses): # type: ignore
|
|
711
775
|
member_id = None
|
|
712
776
|
if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
|
|
@@ -776,11 +840,23 @@ def print_response_stream(
|
|
|
776
840
|
|
|
777
841
|
# Add citations if any
|
|
778
842
|
if member_response.citations is not None and member_response.citations.urls is not None:
|
|
779
|
-
|
|
843
|
+
md_lines = []
|
|
844
|
+
|
|
845
|
+
# Add search queries if present
|
|
846
|
+
if member_response.citations.search_queries:
|
|
847
|
+
md_lines.append("**Search Queries:**")
|
|
848
|
+
for query in member_response.citations.search_queries:
|
|
849
|
+
md_lines.append(f"- {query}")
|
|
850
|
+
md_lines.append("") # Empty line before URLs
|
|
851
|
+
|
|
852
|
+
# Add URL citations
|
|
853
|
+
md_lines.extend(
|
|
780
854
|
f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
|
|
781
855
|
for i, citation in enumerate(member_response.citations.urls)
|
|
782
856
|
if citation.url # Only include citations with valid URLs
|
|
783
857
|
)
|
|
858
|
+
|
|
859
|
+
md_content = "\n".join(md_lines)
|
|
784
860
|
if md_content: # Only create panel if there are citations
|
|
785
861
|
citations_panel = create_panel(
|
|
786
862
|
content=Markdown(md_content),
|
|
@@ -808,6 +884,15 @@ def print_response_stream(
|
|
|
808
884
|
|
|
809
885
|
tool_calls_text = "\n\n".join(lines)
|
|
810
886
|
|
|
887
|
+
# Add compression stats at end of tool calls
|
|
888
|
+
if team.compression_manager is not None and team.compression_manager.stats:
|
|
889
|
+
stats = team.compression_manager.stats
|
|
890
|
+
saved = stats.get("original_size", 0) - stats.get("compressed_size", 0)
|
|
891
|
+
orig = stats.get("original_size", 1)
|
|
892
|
+
if stats.get("tool_results_compressed", 0) > 0:
|
|
893
|
+
tool_calls_text += f"\n\ncompressed: {stats.get('tool_results_compressed', 0)} | Saved: {saved:,} chars ({saved / orig * 100:.0f}%)"
|
|
894
|
+
team.compression_manager.stats.clear()
|
|
895
|
+
|
|
811
896
|
team_tool_calls_panel = create_panel(
|
|
812
897
|
content=tool_calls_text,
|
|
813
898
|
title="Team Tool Calls",
|
|
@@ -831,11 +916,23 @@ def print_response_stream(
|
|
|
831
916
|
|
|
832
917
|
# Add team citations
|
|
833
918
|
if hasattr(resp, "citations") and resp.citations is not None and resp.citations.urls is not None:
|
|
834
|
-
|
|
919
|
+
md_lines = []
|
|
920
|
+
|
|
921
|
+
# Add search queries if present
|
|
922
|
+
if resp.citations.search_queries:
|
|
923
|
+
md_lines.append("**Search Queries:**")
|
|
924
|
+
for query in resp.citations.search_queries:
|
|
925
|
+
md_lines.append(f"- {query}")
|
|
926
|
+
md_lines.append("") # Empty line before URLs
|
|
927
|
+
|
|
928
|
+
# Add URL citations
|
|
929
|
+
md_lines.extend(
|
|
835
930
|
f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
|
|
836
931
|
for i, citation in enumerate(resp.citations.urls)
|
|
837
932
|
if citation.url # Only include citations with valid URLs
|
|
838
933
|
)
|
|
934
|
+
|
|
935
|
+
md_content = "\n".join(md_lines)
|
|
839
936
|
if md_content: # Only create panel if there are citations
|
|
840
937
|
citations_panel = create_panel(
|
|
841
938
|
content=Markdown(md_content),
|
|
@@ -855,16 +952,18 @@ async def aprint_response(
|
|
|
855
952
|
show_message: bool = True,
|
|
856
953
|
show_reasoning: bool = True,
|
|
857
954
|
show_full_reasoning: bool = False,
|
|
955
|
+
show_member_responses: Optional[bool] = None,
|
|
858
956
|
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
859
957
|
session_id: Optional[str] = None,
|
|
860
958
|
session_state: Optional[Dict[str, Any]] = None,
|
|
861
959
|
user_id: Optional[str] = None,
|
|
960
|
+
run_id: Optional[str] = None,
|
|
862
961
|
audio: Optional[Sequence[Audio]] = None,
|
|
863
962
|
images: Optional[Sequence[Image]] = None,
|
|
864
963
|
videos: Optional[Sequence[Video]] = None,
|
|
865
964
|
files: Optional[Sequence[File]] = None,
|
|
866
965
|
markdown: bool = False,
|
|
867
|
-
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
966
|
+
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
868
967
|
add_history_to_context: Optional[bool] = None,
|
|
869
968
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
870
969
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -910,11 +1009,13 @@ async def aprint_response(
|
|
|
910
1009
|
# Run the agent
|
|
911
1010
|
run_response: TeamRunOutput = await team.arun( # type: ignore
|
|
912
1011
|
input=input,
|
|
1012
|
+
run_id=run_id,
|
|
913
1013
|
images=images,
|
|
914
1014
|
audio=audio,
|
|
915
1015
|
videos=videos,
|
|
916
1016
|
files=files,
|
|
917
1017
|
stream=False,
|
|
1018
|
+
stream_events=True,
|
|
918
1019
|
session_id=session_id,
|
|
919
1020
|
session_state=session_state,
|
|
920
1021
|
user_id=user_id,
|
|
@@ -982,7 +1083,7 @@ async def aprint_response(
|
|
|
982
1083
|
|
|
983
1084
|
if isinstance(run_response, TeamRunOutput):
|
|
984
1085
|
# Handle member responses
|
|
985
|
-
if
|
|
1086
|
+
if show_member_responses:
|
|
986
1087
|
for member_response in run_response.member_responses:
|
|
987
1088
|
# Handle member reasoning
|
|
988
1089
|
reasoning_steps = []
|
|
@@ -1055,11 +1156,23 @@ async def aprint_response(
|
|
|
1055
1156
|
panels.append(member_response_panel)
|
|
1056
1157
|
|
|
1057
1158
|
if member_response.citations is not None and member_response.citations.urls is not None:
|
|
1058
|
-
|
|
1159
|
+
md_lines = []
|
|
1160
|
+
|
|
1161
|
+
# Add search queries if present
|
|
1162
|
+
if member_response.citations.search_queries:
|
|
1163
|
+
md_lines.append("**Search Queries:**")
|
|
1164
|
+
for query in member_response.citations.search_queries:
|
|
1165
|
+
md_lines.append(f"- {query}")
|
|
1166
|
+
md_lines.append("") # Empty line before URLs
|
|
1167
|
+
|
|
1168
|
+
# Add URL citations
|
|
1169
|
+
md_lines.extend(
|
|
1059
1170
|
f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
|
|
1060
1171
|
for i, citation in enumerate(member_response.citations.urls)
|
|
1061
1172
|
if citation.url # Only include citations with valid URLs
|
|
1062
1173
|
)
|
|
1174
|
+
|
|
1175
|
+
md_content = "\n".join(md_lines)
|
|
1063
1176
|
if md_content:
|
|
1064
1177
|
citations_panel = create_panel(
|
|
1065
1178
|
content=Markdown(md_content),
|
|
@@ -1086,6 +1199,15 @@ async def aprint_response(
|
|
|
1086
1199
|
|
|
1087
1200
|
tool_calls_text = "\n\n".join(lines)
|
|
1088
1201
|
|
|
1202
|
+
# Add compression stats at end of tool calls
|
|
1203
|
+
if team.compression_manager is not None and team.compression_manager.stats:
|
|
1204
|
+
stats = team.compression_manager.stats
|
|
1205
|
+
saved = stats.get("original_size", 0) - stats.get("compressed_size", 0)
|
|
1206
|
+
orig = stats.get("original_size", 1)
|
|
1207
|
+
if stats.get("tool_results_compressed", 0) > 0:
|
|
1208
|
+
tool_calls_text += f"\n\ncompressed: {stats.get('tool_results_compressed', 0)} | Saved: {saved:,} chars ({saved / orig * 100:.0f}%)"
|
|
1209
|
+
team.compression_manager.stats.clear()
|
|
1210
|
+
|
|
1089
1211
|
team_tool_calls_panel = create_panel(
|
|
1090
1212
|
content=tool_calls_text,
|
|
1091
1213
|
title="Team Tool Calls",
|
|
@@ -1108,11 +1230,23 @@ async def aprint_response(
|
|
|
1108
1230
|
|
|
1109
1231
|
# Add citations
|
|
1110
1232
|
if run_response.citations is not None and run_response.citations.urls is not None:
|
|
1111
|
-
|
|
1233
|
+
md_lines = []
|
|
1234
|
+
|
|
1235
|
+
# Add search queries if present
|
|
1236
|
+
if run_response.citations.search_queries:
|
|
1237
|
+
md_lines.append("**Search Queries:**")
|
|
1238
|
+
for query in run_response.citations.search_queries:
|
|
1239
|
+
md_lines.append(f"- {query}")
|
|
1240
|
+
md_lines.append("") # Empty line before URLs
|
|
1241
|
+
|
|
1242
|
+
# Add URL citations
|
|
1243
|
+
md_lines.extend(
|
|
1112
1244
|
f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
|
|
1113
1245
|
for i, citation in enumerate(run_response.citations.urls)
|
|
1114
1246
|
if citation.url # Only include citations with valid URLs
|
|
1115
1247
|
)
|
|
1248
|
+
|
|
1249
|
+
md_content = "\n".join(md_lines)
|
|
1116
1250
|
if md_content: # Only create panel if there are citations
|
|
1117
1251
|
citations_panel = create_panel(
|
|
1118
1252
|
content=Markdown(md_content),
|
|
@@ -1151,17 +1285,20 @@ async def aprint_response_stream(
|
|
|
1151
1285
|
show_message: bool = True,
|
|
1152
1286
|
show_reasoning: bool = True,
|
|
1153
1287
|
show_full_reasoning: bool = False,
|
|
1288
|
+
show_member_responses: Optional[bool] = None,
|
|
1154
1289
|
tags_to_include_in_markdown: Optional[Set[str]] = None,
|
|
1155
1290
|
session_id: Optional[str] = None,
|
|
1156
1291
|
session_state: Optional[Dict[str, Any]] = None,
|
|
1157
1292
|
user_id: Optional[str] = None,
|
|
1293
|
+
run_id: Optional[str] = None,
|
|
1158
1294
|
audio: Optional[Sequence[Audio]] = None,
|
|
1159
1295
|
images: Optional[Sequence[Image]] = None,
|
|
1160
1296
|
videos: Optional[Sequence[Video]] = None,
|
|
1161
1297
|
files: Optional[Sequence[File]] = None,
|
|
1162
1298
|
markdown: bool = False,
|
|
1299
|
+
stream_events: bool = False,
|
|
1163
1300
|
stream_intermediate_steps: bool = False, # type: ignore
|
|
1164
|
-
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
1301
|
+
knowledge_filters: Optional[Union[Dict[str, Any], List[FilterExpr]]] = None,
|
|
1165
1302
|
add_history_to_context: Optional[bool] = None,
|
|
1166
1303
|
dependencies: Optional[Dict[str, Any]] = None,
|
|
1167
1304
|
add_dependencies_to_context: Optional[bool] = None,
|
|
@@ -1182,7 +1319,7 @@ async def aprint_response_stream(
|
|
|
1182
1319
|
if not tags_to_include_in_markdown:
|
|
1183
1320
|
tags_to_include_in_markdown = {"think", "thinking"}
|
|
1184
1321
|
|
|
1185
|
-
|
|
1322
|
+
stream_events = True # With streaming print response, we need to stream intermediate steps
|
|
1186
1323
|
|
|
1187
1324
|
_response_content: str = ""
|
|
1188
1325
|
_response_reasoning_content: str = ""
|
|
@@ -1238,10 +1375,11 @@ async def aprint_response_stream(
|
|
|
1238
1375
|
videos=videos,
|
|
1239
1376
|
files=files,
|
|
1240
1377
|
stream=True,
|
|
1241
|
-
|
|
1378
|
+
stream_events=stream_events,
|
|
1242
1379
|
session_id=session_id,
|
|
1243
1380
|
session_state=session_state,
|
|
1244
1381
|
user_id=user_id,
|
|
1382
|
+
run_id=run_id,
|
|
1245
1383
|
knowledge_filters=knowledge_filters,
|
|
1246
1384
|
add_history_to_context=add_history_to_context,
|
|
1247
1385
|
add_dependencies_to_context=add_dependencies_to_context,
|
|
@@ -1249,7 +1387,7 @@ async def aprint_response_stream(
|
|
|
1249
1387
|
dependencies=dependencies,
|
|
1250
1388
|
metadata=metadata,
|
|
1251
1389
|
debug_mode=debug_mode,
|
|
1252
|
-
|
|
1390
|
+
yield_run_output=True,
|
|
1253
1391
|
**kwargs,
|
|
1254
1392
|
):
|
|
1255
1393
|
if team_markdown is None:
|
|
@@ -1296,7 +1434,7 @@ async def aprint_response_stream(
|
|
|
1296
1434
|
team_tool_calls.append(tool)
|
|
1297
1435
|
|
|
1298
1436
|
# Collect member tool calls, avoiding duplicates
|
|
1299
|
-
if hasattr(resp, "member_responses") and resp.member_responses:
|
|
1437
|
+
if show_member_responses and hasattr(resp, "member_responses") and resp.member_responses:
|
|
1300
1438
|
for member_response in resp.member_responses:
|
|
1301
1439
|
member_id = None
|
|
1302
1440
|
if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
|
|
@@ -1357,7 +1495,9 @@ async def aprint_response_stream(
|
|
|
1357
1495
|
panels.append(status)
|
|
1358
1496
|
|
|
1359
1497
|
# Process member responses and their tool calls
|
|
1360
|
-
for member_response in
|
|
1498
|
+
for member_response in (
|
|
1499
|
+
resp.member_responses if show_member_responses and hasattr(resp, "member_responses") else []
|
|
1500
|
+
):
|
|
1361
1501
|
member_id = None
|
|
1362
1502
|
member_name = "Team Member"
|
|
1363
1503
|
if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
|
|
@@ -1390,7 +1530,7 @@ async def aprint_response_stream(
|
|
|
1390
1530
|
panels.append(member_tool_calls_panel)
|
|
1391
1531
|
|
|
1392
1532
|
# Process member response content
|
|
1393
|
-
if
|
|
1533
|
+
if show_member_responses and member_id is not None:
|
|
1394
1534
|
show_markdown = False
|
|
1395
1535
|
if markdown:
|
|
1396
1536
|
show_markdown = True
|
|
@@ -1433,6 +1573,14 @@ async def aprint_response_stream(
|
|
|
1433
1573
|
# Join with blank lines between items
|
|
1434
1574
|
tool_calls_text = "\n\n".join(lines)
|
|
1435
1575
|
|
|
1576
|
+
# Add compression stats if available (don't clear - will be cleared in final_panels)
|
|
1577
|
+
if team.compression_manager is not None and team.compression_manager.stats:
|
|
1578
|
+
stats = team.compression_manager.stats
|
|
1579
|
+
saved = stats.get("original_size", 0) - stats.get("compressed_size", 0)
|
|
1580
|
+
orig = stats.get("original_size", 1)
|
|
1581
|
+
if stats.get("tool_results_compressed", 0) > 0:
|
|
1582
|
+
tool_calls_text += f"\n\ncompressed: {stats.get('tool_results_compressed', 0)} | Saved: {saved:,} chars ({saved / orig * 100:.0f}%)"
|
|
1583
|
+
|
|
1436
1584
|
team_tool_calls_panel = create_panel(
|
|
1437
1585
|
content=tool_calls_text,
|
|
1438
1586
|
title="Team Tool Calls",
|
|
@@ -1460,11 +1608,23 @@ async def aprint_response_stream(
|
|
|
1460
1608
|
|
|
1461
1609
|
# Add citations
|
|
1462
1610
|
if hasattr(resp, "citations") and resp.citations is not None and resp.citations.urls is not None:
|
|
1463
|
-
|
|
1611
|
+
md_lines = []
|
|
1612
|
+
|
|
1613
|
+
# Add search queries if present
|
|
1614
|
+
if resp.citations.search_queries:
|
|
1615
|
+
md_lines.append("**Search Queries:**")
|
|
1616
|
+
for query in resp.citations.search_queries:
|
|
1617
|
+
md_lines.append(f"- {query}")
|
|
1618
|
+
md_lines.append("") # Empty line before URLs
|
|
1619
|
+
|
|
1620
|
+
# Add URL citations
|
|
1621
|
+
md_lines.extend(
|
|
1464
1622
|
f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
|
|
1465
1623
|
for i, citation in enumerate(resp.citations.urls)
|
|
1466
1624
|
if citation.url # Only include citations with valid URLs
|
|
1467
1625
|
)
|
|
1626
|
+
|
|
1627
|
+
md_content = "\n".join(md_lines)
|
|
1468
1628
|
if md_content: # Only create panel if there are citations
|
|
1469
1629
|
citations_panel = create_panel(
|
|
1470
1630
|
content=Markdown(md_content),
|
|
@@ -1534,7 +1694,7 @@ async def aprint_response_stream(
|
|
|
1534
1694
|
final_panels.append(thinking_panel)
|
|
1535
1695
|
|
|
1536
1696
|
# Add member tool calls and responses in correct order
|
|
1537
|
-
if run_response is not None and hasattr(run_response, "member_responses"):
|
|
1697
|
+
if show_member_responses and run_response is not None and hasattr(run_response, "member_responses"):
|
|
1538
1698
|
for i, member_response in enumerate(run_response.member_responses):
|
|
1539
1699
|
member_id = None
|
|
1540
1700
|
if isinstance(member_response, RunOutput) and member_response.agent_id is not None:
|
|
@@ -1621,11 +1781,23 @@ async def aprint_response_stream(
|
|
|
1621
1781
|
|
|
1622
1782
|
# Add citations if any
|
|
1623
1783
|
if member_response.citations is not None and member_response.citations.urls is not None:
|
|
1624
|
-
|
|
1784
|
+
md_lines = []
|
|
1785
|
+
|
|
1786
|
+
# Add search queries if present
|
|
1787
|
+
if member_response.citations.search_queries:
|
|
1788
|
+
md_lines.append("**Search Queries:**")
|
|
1789
|
+
for query in member_response.citations.search_queries:
|
|
1790
|
+
md_lines.append(f"- {query}")
|
|
1791
|
+
md_lines.append("") # Empty line before URLs
|
|
1792
|
+
|
|
1793
|
+
# Add URL citations
|
|
1794
|
+
md_lines.extend(
|
|
1625
1795
|
f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
|
|
1626
1796
|
for i, citation in enumerate(member_response.citations.urls)
|
|
1627
1797
|
if citation.url # Only include citations with valid URLs
|
|
1628
1798
|
)
|
|
1799
|
+
|
|
1800
|
+
md_content = "\n".join(md_lines)
|
|
1629
1801
|
if md_content: # Only create panel if there are citations
|
|
1630
1802
|
citations_panel = create_panel(
|
|
1631
1803
|
content=Markdown(md_content),
|
|
@@ -1653,6 +1825,15 @@ async def aprint_response_stream(
|
|
|
1653
1825
|
|
|
1654
1826
|
tool_calls_text = "\n\n".join(lines)
|
|
1655
1827
|
|
|
1828
|
+
# Add compression stats at end of tool calls
|
|
1829
|
+
if team.compression_manager is not None and team.compression_manager.stats:
|
|
1830
|
+
stats = team.compression_manager.stats
|
|
1831
|
+
saved = stats.get("original_size", 0) - stats.get("compressed_size", 0)
|
|
1832
|
+
orig = stats.get("original_size", 1)
|
|
1833
|
+
if stats.get("tool_results_compressed", 0) > 0:
|
|
1834
|
+
tool_calls_text += f"\n\ncompressed: {stats.get('tool_results_compressed', 0)} | Saved: {saved:,} chars ({saved / orig * 100:.0f}%)"
|
|
1835
|
+
team.compression_manager.stats.clear()
|
|
1836
|
+
|
|
1656
1837
|
team_tool_calls_panel = create_panel(
|
|
1657
1838
|
content=tool_calls_text,
|
|
1658
1839
|
title="Team Tool Calls",
|
|
@@ -1676,11 +1857,23 @@ async def aprint_response_stream(
|
|
|
1676
1857
|
|
|
1677
1858
|
# Add team citations
|
|
1678
1859
|
if hasattr(resp, "citations") and resp.citations is not None and resp.citations.urls is not None:
|
|
1679
|
-
|
|
1860
|
+
md_lines = []
|
|
1861
|
+
|
|
1862
|
+
# Add search queries if present
|
|
1863
|
+
if resp.citations.search_queries:
|
|
1864
|
+
md_lines.append("**Search Queries:**")
|
|
1865
|
+
for query in resp.citations.search_queries:
|
|
1866
|
+
md_lines.append(f"- {query}")
|
|
1867
|
+
md_lines.append("") # Empty line before URLs
|
|
1868
|
+
|
|
1869
|
+
# Add URL citations
|
|
1870
|
+
md_lines.extend(
|
|
1680
1871
|
f"{i + 1}. [{citation.title or citation.url}]({citation.url})"
|
|
1681
1872
|
for i, citation in enumerate(resp.citations.urls)
|
|
1682
1873
|
if citation.url # Only include citations with valid URLs
|
|
1683
1874
|
)
|
|
1875
|
+
|
|
1876
|
+
md_content = "\n".join(md_lines)
|
|
1684
1877
|
if md_content: # Only create panel if there are citations
|
|
1685
1878
|
citations_panel = create_panel(
|
|
1686
1879
|
content=Markdown(md_content),
|