agno 2.2.13__py3-none-any.whl → 2.4.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agno/agent/__init__.py +6 -0
- agno/agent/agent.py +5252 -3145
- agno/agent/remote.py +525 -0
- agno/api/api.py +2 -0
- agno/client/__init__.py +3 -0
- agno/client/a2a/__init__.py +10 -0
- agno/client/a2a/client.py +554 -0
- agno/client/a2a/schemas.py +112 -0
- agno/client/a2a/utils.py +369 -0
- agno/client/os.py +2669 -0
- agno/compression/__init__.py +3 -0
- agno/compression/manager.py +247 -0
- agno/culture/manager.py +2 -2
- agno/db/base.py +927 -6
- agno/db/dynamo/dynamo.py +788 -2
- agno/db/dynamo/schemas.py +128 -0
- agno/db/dynamo/utils.py +26 -3
- agno/db/firestore/firestore.py +674 -50
- agno/db/firestore/schemas.py +41 -0
- agno/db/firestore/utils.py +25 -10
- agno/db/gcs_json/gcs_json_db.py +506 -3
- agno/db/gcs_json/utils.py +14 -2
- agno/db/in_memory/in_memory_db.py +203 -4
- agno/db/in_memory/utils.py +14 -2
- agno/db/json/json_db.py +498 -2
- agno/db/json/utils.py +14 -2
- agno/db/migrations/manager.py +199 -0
- agno/db/migrations/utils.py +19 -0
- agno/db/migrations/v1_to_v2.py +54 -16
- agno/db/migrations/versions/__init__.py +0 -0
- agno/db/migrations/versions/v2_3_0.py +977 -0
- agno/db/mongo/async_mongo.py +1013 -39
- agno/db/mongo/mongo.py +684 -4
- agno/db/mongo/schemas.py +48 -0
- agno/db/mongo/utils.py +17 -0
- agno/db/mysql/__init__.py +2 -1
- agno/db/mysql/async_mysql.py +2958 -0
- agno/db/mysql/mysql.py +722 -53
- agno/db/mysql/schemas.py +77 -11
- agno/db/mysql/utils.py +151 -8
- agno/db/postgres/async_postgres.py +1254 -137
- agno/db/postgres/postgres.py +2316 -93
- agno/db/postgres/schemas.py +153 -21
- agno/db/postgres/utils.py +22 -7
- agno/db/redis/redis.py +531 -3
- agno/db/redis/schemas.py +36 -0
- agno/db/redis/utils.py +31 -15
- agno/db/schemas/evals.py +1 -0
- agno/db/schemas/memory.py +20 -9
- agno/db/singlestore/schemas.py +70 -1
- agno/db/singlestore/singlestore.py +737 -74
- agno/db/singlestore/utils.py +13 -3
- agno/db/sqlite/async_sqlite.py +1069 -89
- agno/db/sqlite/schemas.py +133 -1
- agno/db/sqlite/sqlite.py +2203 -165
- agno/db/sqlite/utils.py +21 -11
- agno/db/surrealdb/models.py +25 -0
- agno/db/surrealdb/surrealdb.py +603 -1
- agno/db/utils.py +60 -0
- agno/eval/__init__.py +26 -3
- agno/eval/accuracy.py +25 -12
- agno/eval/agent_as_judge.py +871 -0
- agno/eval/base.py +29 -0
- agno/eval/performance.py +10 -4
- agno/eval/reliability.py +22 -13
- agno/eval/utils.py +2 -1
- agno/exceptions.py +42 -0
- agno/hooks/__init__.py +3 -0
- agno/hooks/decorator.py +164 -0
- agno/integrations/discord/client.py +13 -2
- agno/knowledge/__init__.py +4 -0
- agno/knowledge/chunking/code.py +90 -0
- agno/knowledge/chunking/document.py +65 -4
- agno/knowledge/chunking/fixed.py +4 -1
- agno/knowledge/chunking/markdown.py +102 -11
- agno/knowledge/chunking/recursive.py +2 -2
- agno/knowledge/chunking/semantic.py +130 -48
- agno/knowledge/chunking/strategy.py +18 -0
- agno/knowledge/embedder/azure_openai.py +0 -1
- agno/knowledge/embedder/google.py +1 -1
- agno/knowledge/embedder/mistral.py +1 -1
- agno/knowledge/embedder/nebius.py +1 -1
- agno/knowledge/embedder/openai.py +16 -12
- agno/knowledge/filesystem.py +412 -0
- agno/knowledge/knowledge.py +4261 -1199
- agno/knowledge/protocol.py +134 -0
- agno/knowledge/reader/arxiv_reader.py +3 -2
- agno/knowledge/reader/base.py +9 -7
- agno/knowledge/reader/csv_reader.py +91 -42
- agno/knowledge/reader/docx_reader.py +9 -10
- agno/knowledge/reader/excel_reader.py +225 -0
- agno/knowledge/reader/field_labeled_csv_reader.py +38 -48
- agno/knowledge/reader/firecrawl_reader.py +3 -2
- agno/knowledge/reader/json_reader.py +16 -22
- agno/knowledge/reader/markdown_reader.py +15 -14
- agno/knowledge/reader/pdf_reader.py +33 -28
- agno/knowledge/reader/pptx_reader.py +9 -10
- agno/knowledge/reader/reader_factory.py +135 -1
- agno/knowledge/reader/s3_reader.py +8 -16
- agno/knowledge/reader/tavily_reader.py +3 -3
- agno/knowledge/reader/text_reader.py +15 -14
- agno/knowledge/reader/utils/__init__.py +17 -0
- agno/knowledge/reader/utils/spreadsheet.py +114 -0
- agno/knowledge/reader/web_search_reader.py +8 -65
- agno/knowledge/reader/website_reader.py +16 -13
- agno/knowledge/reader/wikipedia_reader.py +36 -3
- agno/knowledge/reader/youtube_reader.py +3 -2
- agno/knowledge/remote_content/__init__.py +33 -0
- agno/knowledge/remote_content/config.py +266 -0
- agno/knowledge/remote_content/remote_content.py +105 -17
- agno/knowledge/utils.py +76 -22
- agno/learn/__init__.py +71 -0
- agno/learn/config.py +463 -0
- agno/learn/curate.py +185 -0
- agno/learn/machine.py +725 -0
- agno/learn/schemas.py +1114 -0
- agno/learn/stores/__init__.py +38 -0
- agno/learn/stores/decision_log.py +1156 -0
- agno/learn/stores/entity_memory.py +3275 -0
- agno/learn/stores/learned_knowledge.py +1583 -0
- agno/learn/stores/protocol.py +117 -0
- agno/learn/stores/session_context.py +1217 -0
- agno/learn/stores/user_memory.py +1495 -0
- agno/learn/stores/user_profile.py +1220 -0
- agno/learn/utils.py +209 -0
- agno/media.py +22 -6
- agno/memory/__init__.py +14 -1
- agno/memory/manager.py +223 -8
- 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 +434 -59
- agno/models/aws/bedrock.py +121 -20
- agno/models/aws/claude.py +131 -274
- agno/models/azure/ai_foundry.py +10 -6
- agno/models/azure/openai_chat.py +33 -10
- agno/models/base.py +1162 -561
- agno/models/cerebras/cerebras.py +120 -24
- agno/models/cerebras/cerebras_openai.py +21 -2
- agno/models/cohere/chat.py +65 -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 +959 -89
- agno/models/google/utils.py +22 -0
- agno/models/groq/groq.py +48 -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 +88 -9
- agno/models/litellm/litellm_openai.py +18 -1
- agno/models/message.py +24 -5
- agno/models/meta/llama.py +40 -13
- agno/models/meta/llama_openai.py +22 -21
- agno/models/metrics.py +12 -0
- agno/models/mistral/mistral.py +8 -4
- agno/models/n1n/__init__.py +3 -0
- agno/models/n1n/n1n.py +57 -0
- agno/models/nebius/nebius.py +6 -7
- agno/models/nvidia/nvidia.py +20 -3
- agno/models/ollama/__init__.py +2 -0
- agno/models/ollama/chat.py +17 -6
- agno/models/ollama/responses.py +100 -0
- agno/models/openai/__init__.py +2 -0
- agno/models/openai/chat.py +117 -26
- agno/models/openai/open_responses.py +46 -0
- agno/models/openai/responses.py +110 -32
- agno/models/openrouter/__init__.py +2 -0
- agno/models/openrouter/openrouter.py +67 -2
- agno/models/openrouter/responses.py +146 -0
- agno/models/perplexity/perplexity.py +19 -1
- agno/models/portkey/portkey.py +7 -6
- agno/models/requesty/requesty.py +19 -2
- agno/models/response.py +20 -2
- agno/models/sambanova/sambanova.py +20 -3
- agno/models/siliconflow/siliconflow.py +19 -2
- agno/models/together/together.py +20 -3
- agno/models/vercel/v0.py +20 -3
- agno/models/vertexai/claude.py +124 -4
- agno/models/vllm/vllm.py +19 -14
- agno/models/xai/xai.py +19 -2
- agno/os/app.py +467 -137
- agno/os/auth.py +253 -5
- agno/os/config.py +22 -0
- agno/os/interfaces/a2a/a2a.py +7 -6
- agno/os/interfaces/a2a/router.py +635 -26
- agno/os/interfaces/a2a/utils.py +32 -33
- agno/os/interfaces/agui/agui.py +5 -3
- agno/os/interfaces/agui/router.py +26 -16
- agno/os/interfaces/agui/utils.py +97 -57
- agno/os/interfaces/base.py +7 -7
- agno/os/interfaces/slack/router.py +16 -7
- agno/os/interfaces/slack/slack.py +7 -7
- agno/os/interfaces/whatsapp/router.py +35 -7
- agno/os/interfaces/whatsapp/security.py +3 -1
- agno/os/interfaces/whatsapp/whatsapp.py +11 -8
- agno/os/managers.py +326 -0
- agno/os/mcp.py +652 -79
- agno/os/middleware/__init__.py +4 -0
- agno/os/middleware/jwt.py +718 -115
- agno/os/middleware/trailing_slash.py +27 -0
- agno/os/router.py +105 -1558
- agno/os/routers/agents/__init__.py +3 -0
- agno/os/routers/agents/router.py +655 -0
- agno/os/routers/agents/schema.py +288 -0
- agno/os/routers/components/__init__.py +3 -0
- agno/os/routers/components/components.py +475 -0
- agno/os/routers/database.py +155 -0
- agno/os/routers/evals/evals.py +111 -18
- agno/os/routers/evals/schemas.py +38 -5
- agno/os/routers/evals/utils.py +80 -11
- agno/os/routers/health.py +3 -3
- agno/os/routers/knowledge/knowledge.py +284 -35
- agno/os/routers/knowledge/schemas.py +14 -2
- agno/os/routers/memory/memory.py +274 -11
- agno/os/routers/memory/schemas.py +44 -3
- agno/os/routers/metrics/metrics.py +30 -15
- agno/os/routers/metrics/schemas.py +10 -6
- agno/os/routers/registry/__init__.py +3 -0
- agno/os/routers/registry/registry.py +337 -0
- agno/os/routers/session/session.py +143 -14
- agno/os/routers/teams/__init__.py +3 -0
- agno/os/routers/teams/router.py +550 -0
- agno/os/routers/teams/schema.py +280 -0
- agno/os/routers/traces/__init__.py +3 -0
- agno/os/routers/traces/schemas.py +414 -0
- agno/os/routers/traces/traces.py +549 -0
- agno/os/routers/workflows/__init__.py +3 -0
- agno/os/routers/workflows/router.py +757 -0
- agno/os/routers/workflows/schema.py +139 -0
- agno/os/schema.py +157 -584
- agno/os/scopes.py +469 -0
- agno/os/settings.py +3 -0
- agno/os/utils.py +574 -185
- agno/reasoning/anthropic.py +85 -1
- agno/reasoning/azure_ai_foundry.py +93 -1
- agno/reasoning/deepseek.py +102 -2
- agno/reasoning/default.py +6 -7
- agno/reasoning/gemini.py +87 -3
- agno/reasoning/groq.py +109 -2
- agno/reasoning/helpers.py +6 -7
- agno/reasoning/manager.py +1238 -0
- agno/reasoning/ollama.py +93 -1
- agno/reasoning/openai.py +115 -1
- agno/reasoning/vertexai.py +85 -1
- agno/registry/__init__.py +3 -0
- agno/registry/registry.py +68 -0
- agno/remote/__init__.py +3 -0
- agno/remote/base.py +581 -0
- agno/run/__init__.py +2 -4
- agno/run/agent.py +134 -19
- agno/run/base.py +49 -1
- agno/run/cancel.py +65 -52
- agno/run/cancellation_management/__init__.py +9 -0
- agno/run/cancellation_management/base.py +78 -0
- agno/run/cancellation_management/in_memory_cancellation_manager.py +100 -0
- agno/run/cancellation_management/redis_cancellation_manager.py +236 -0
- agno/run/requirement.py +181 -0
- agno/run/team.py +111 -19
- agno/run/workflow.py +2 -1
- agno/session/agent.py +57 -92
- agno/session/summary.py +1 -1
- agno/session/team.py +62 -115
- agno/session/workflow.py +353 -57
- agno/skills/__init__.py +17 -0
- agno/skills/agent_skills.py +377 -0
- agno/skills/errors.py +32 -0
- agno/skills/loaders/__init__.py +4 -0
- agno/skills/loaders/base.py +27 -0
- agno/skills/loaders/local.py +216 -0
- agno/skills/skill.py +65 -0
- agno/skills/utils.py +107 -0
- agno/skills/validator.py +277 -0
- agno/table.py +10 -0
- agno/team/__init__.py +5 -1
- agno/team/remote.py +447 -0
- agno/team/team.py +3769 -2202
- agno/tools/brandfetch.py +27 -18
- agno/tools/browserbase.py +225 -16
- agno/tools/crawl4ai.py +3 -0
- agno/tools/duckduckgo.py +25 -71
- agno/tools/exa.py +0 -21
- agno/tools/file.py +14 -13
- agno/tools/file_generation.py +12 -6
- agno/tools/firecrawl.py +15 -7
- agno/tools/function.py +94 -113
- agno/tools/google_bigquery.py +11 -2
- agno/tools/google_drive.py +4 -3
- agno/tools/knowledge.py +9 -4
- agno/tools/mcp/mcp.py +301 -18
- agno/tools/mcp/multi_mcp.py +269 -14
- agno/tools/mem0.py +11 -10
- agno/tools/memory.py +47 -46
- agno/tools/mlx_transcribe.py +10 -7
- agno/tools/models/nebius.py +5 -5
- agno/tools/models_labs.py +20 -10
- agno/tools/nano_banana.py +151 -0
- agno/tools/parallel.py +0 -7
- agno/tools/postgres.py +76 -36
- agno/tools/python.py +14 -6
- agno/tools/reasoning.py +30 -23
- agno/tools/redshift.py +406 -0
- agno/tools/shopify.py +1519 -0
- agno/tools/spotify.py +919 -0
- agno/tools/tavily.py +4 -1
- agno/tools/toolkit.py +253 -18
- agno/tools/websearch.py +93 -0
- agno/tools/website.py +1 -1
- agno/tools/wikipedia.py +1 -1
- agno/tools/workflow.py +56 -48
- agno/tools/yfinance.py +12 -11
- agno/tracing/__init__.py +12 -0
- agno/tracing/exporter.py +161 -0
- agno/tracing/schemas.py +276 -0
- agno/tracing/setup.py +112 -0
- agno/utils/agent.py +251 -10
- agno/utils/cryptography.py +22 -0
- agno/utils/dttm.py +33 -0
- agno/utils/events.py +264 -7
- agno/utils/hooks.py +111 -3
- agno/utils/http.py +161 -2
- agno/utils/mcp.py +49 -8
- agno/utils/media.py +22 -1
- agno/utils/models/ai_foundry.py +9 -2
- agno/utils/models/claude.py +20 -5
- agno/utils/models/cohere.py +9 -2
- agno/utils/models/llama.py +9 -2
- agno/utils/models/mistral.py +4 -2
- agno/utils/os.py +0 -0
- agno/utils/print_response/agent.py +99 -16
- agno/utils/print_response/team.py +223 -24
- agno/utils/print_response/workflow.py +0 -2
- agno/utils/prompts.py +8 -6
- agno/utils/remote.py +23 -0
- agno/utils/response.py +1 -13
- agno/utils/string.py +91 -2
- agno/utils/team.py +62 -12
- agno/utils/tokens.py +657 -0
- agno/vectordb/base.py +15 -2
- agno/vectordb/cassandra/cassandra.py +1 -1
- agno/vectordb/chroma/__init__.py +2 -1
- agno/vectordb/chroma/chromadb.py +468 -23
- agno/vectordb/clickhouse/clickhousedb.py +1 -1
- agno/vectordb/couchbase/couchbase.py +6 -2
- agno/vectordb/lancedb/lance_db.py +7 -38
- agno/vectordb/lightrag/lightrag.py +7 -6
- agno/vectordb/milvus/milvus.py +118 -84
- agno/vectordb/mongodb/__init__.py +2 -1
- agno/vectordb/mongodb/mongodb.py +14 -31
- agno/vectordb/pgvector/pgvector.py +120 -66
- agno/vectordb/pineconedb/pineconedb.py +2 -19
- agno/vectordb/qdrant/__init__.py +2 -1
- agno/vectordb/qdrant/qdrant.py +33 -56
- agno/vectordb/redis/__init__.py +2 -1
- agno/vectordb/redis/redisdb.py +19 -31
- agno/vectordb/singlestore/singlestore.py +17 -9
- agno/vectordb/surrealdb/surrealdb.py +2 -38
- agno/vectordb/weaviate/__init__.py +2 -1
- agno/vectordb/weaviate/weaviate.py +7 -3
- agno/workflow/__init__.py +5 -1
- agno/workflow/agent.py +2 -2
- agno/workflow/condition.py +12 -10
- agno/workflow/loop.py +28 -9
- agno/workflow/parallel.py +21 -13
- agno/workflow/remote.py +362 -0
- agno/workflow/router.py +12 -9
- agno/workflow/step.py +261 -36
- agno/workflow/steps.py +12 -8
- agno/workflow/types.py +40 -77
- agno/workflow/workflow.py +939 -213
- {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/METADATA +134 -181
- agno-2.4.3.dist-info/RECORD +677 -0
- {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/WHEEL +1 -1
- agno/tools/googlesearch.py +0 -98
- agno/tools/memori.py +0 -339
- agno-2.2.13.dist-info/RECORD +0 -575
- {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/licenses/LICENSE +0 -0
- {agno-2.2.13.dist-info → agno-2.4.3.dist-info}/top_level.txt +0 -0
agno/client/a2a/utils.py
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
"""Utility functions for mapping between A2A and Agno data structures.
|
|
2
|
+
|
|
3
|
+
This module provides bidirectional mapping between:
|
|
4
|
+
- A2A TaskResult ↔ Agno RunOutput / TeamRunOutput / WorkflowRunOutput
|
|
5
|
+
- A2A StreamEvent ↔ Agno RunOutputEvent / TeamRunOutputEvent / WorkflowRunOutputEvent
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import AsyncIterator, List, Optional, Union
|
|
9
|
+
|
|
10
|
+
from agno.client.a2a.schemas import Artifact, StreamEvent, TaskResult
|
|
11
|
+
from agno.media import Audio, File, Image, Video
|
|
12
|
+
from agno.run.agent import (
|
|
13
|
+
RunCompletedEvent,
|
|
14
|
+
RunContentEvent,
|
|
15
|
+
RunOutput,
|
|
16
|
+
RunOutputEvent,
|
|
17
|
+
RunStartedEvent,
|
|
18
|
+
)
|
|
19
|
+
from agno.run.team import (
|
|
20
|
+
RunCompletedEvent as TeamRunCompletedEvent,
|
|
21
|
+
)
|
|
22
|
+
from agno.run.team import (
|
|
23
|
+
RunContentEvent as TeamRunContentEvent,
|
|
24
|
+
)
|
|
25
|
+
from agno.run.team import (
|
|
26
|
+
RunStartedEvent as TeamRunStartedEvent,
|
|
27
|
+
)
|
|
28
|
+
from agno.run.team import (
|
|
29
|
+
TeamRunOutput,
|
|
30
|
+
TeamRunOutputEvent,
|
|
31
|
+
)
|
|
32
|
+
from agno.run.workflow import (
|
|
33
|
+
WorkflowCompletedEvent,
|
|
34
|
+
WorkflowRunOutput,
|
|
35
|
+
WorkflowRunOutputEvent,
|
|
36
|
+
WorkflowStartedEvent,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def map_task_result_to_run_output(
|
|
41
|
+
task_result: TaskResult,
|
|
42
|
+
agent_id: str,
|
|
43
|
+
user_id: Optional[str] = None,
|
|
44
|
+
) -> RunOutput:
|
|
45
|
+
"""Convert A2A TaskResult to Agno RunOutput.
|
|
46
|
+
|
|
47
|
+
Maps the A2A protocol response structure to Agno's internal format,
|
|
48
|
+
enabling seamless integration with Agno's agent infrastructure.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
task_result: A2A TaskResult from send_message()
|
|
52
|
+
agent_id: Agent identifier to include in output
|
|
53
|
+
user_id: Optional user identifier to include in output
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
RunOutput: Agno-compatible run output
|
|
57
|
+
"""
|
|
58
|
+
# Extract media from artifacts
|
|
59
|
+
images: List[Image] = []
|
|
60
|
+
videos: List[Video] = []
|
|
61
|
+
audio: List[Audio] = []
|
|
62
|
+
files: List[File] = []
|
|
63
|
+
|
|
64
|
+
for artifact in task_result.artifacts:
|
|
65
|
+
_classify_artifact(artifact, images, videos, audio, files)
|
|
66
|
+
|
|
67
|
+
return RunOutput(
|
|
68
|
+
content=task_result.content,
|
|
69
|
+
run_id=task_result.task_id,
|
|
70
|
+
session_id=task_result.context_id,
|
|
71
|
+
agent_id=agent_id,
|
|
72
|
+
user_id=user_id,
|
|
73
|
+
images=images if images else None,
|
|
74
|
+
videos=videos if videos else None,
|
|
75
|
+
audio=audio if audio else None,
|
|
76
|
+
files=files if files else None,
|
|
77
|
+
metadata=task_result.metadata,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _classify_artifact(
|
|
82
|
+
artifact: Artifact,
|
|
83
|
+
images: List[Image],
|
|
84
|
+
videos: List[Video],
|
|
85
|
+
audio: List[Audio],
|
|
86
|
+
files: List[File],
|
|
87
|
+
) -> None:
|
|
88
|
+
"""Classify an A2A artifact into the appropriate media type list.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
artifact: A2A artifact to classify
|
|
92
|
+
images: List to append images to
|
|
93
|
+
videos: List to append videos to
|
|
94
|
+
audio: List to append audio to
|
|
95
|
+
files: List to append generic files to
|
|
96
|
+
"""
|
|
97
|
+
mime_type = artifact.mime_type or ""
|
|
98
|
+
uri = artifact.uri
|
|
99
|
+
|
|
100
|
+
if not uri:
|
|
101
|
+
return
|
|
102
|
+
|
|
103
|
+
if mime_type.startswith("image/"):
|
|
104
|
+
images.append(Image(url=uri, name=artifact.name))
|
|
105
|
+
elif mime_type.startswith("video/"):
|
|
106
|
+
videos.append(Video(url=uri, name=artifact.name))
|
|
107
|
+
elif mime_type.startswith("audio/"):
|
|
108
|
+
audio.append(Audio(url=uri, name=artifact.name))
|
|
109
|
+
else:
|
|
110
|
+
files.append(File(url=uri, name=artifact.name, mime_type=mime_type or None))
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
async def map_stream_events_to_run_events(
|
|
114
|
+
stream: AsyncIterator[StreamEvent],
|
|
115
|
+
agent_id: str,
|
|
116
|
+
) -> AsyncIterator[RunOutputEvent]:
|
|
117
|
+
"""Convert A2A stream events to Agno run events.
|
|
118
|
+
|
|
119
|
+
Transforms the A2A streaming protocol events into Agno's event system,
|
|
120
|
+
enabling real-time streaming from A2A servers to work with Agno consumers.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
stream: AsyncIterator of A2A StreamEvents
|
|
124
|
+
agent_id: Optional agent identifier to include in events
|
|
125
|
+
user_id: Optional user identifier to include in events
|
|
126
|
+
|
|
127
|
+
Yields:
|
|
128
|
+
RunOutputEvent: Agno-compatible run output events
|
|
129
|
+
"""
|
|
130
|
+
run_id: Optional[str] = None
|
|
131
|
+
session_id: Optional[str] = None
|
|
132
|
+
accumulated_content = ""
|
|
133
|
+
|
|
134
|
+
async for event in stream:
|
|
135
|
+
# Capture IDs from events
|
|
136
|
+
if event.task_id:
|
|
137
|
+
run_id = event.task_id
|
|
138
|
+
if event.context_id:
|
|
139
|
+
session_id = event.context_id
|
|
140
|
+
|
|
141
|
+
# Map event types
|
|
142
|
+
if event.event_type == "working":
|
|
143
|
+
yield RunStartedEvent(
|
|
144
|
+
run_id=run_id,
|
|
145
|
+
session_id=session_id,
|
|
146
|
+
agent_id=agent_id,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
elif event.is_content and event.content:
|
|
150
|
+
accumulated_content += event.content
|
|
151
|
+
yield RunContentEvent(
|
|
152
|
+
content=event.content,
|
|
153
|
+
run_id=run_id,
|
|
154
|
+
session_id=session_id,
|
|
155
|
+
agent_id=agent_id,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
elif event.is_final:
|
|
159
|
+
# Use content from final event or accumulated content
|
|
160
|
+
final_content = event.content if event.content else accumulated_content
|
|
161
|
+
yield RunCompletedEvent(
|
|
162
|
+
content=final_content,
|
|
163
|
+
run_id=run_id,
|
|
164
|
+
session_id=session_id,
|
|
165
|
+
agent_id=agent_id,
|
|
166
|
+
)
|
|
167
|
+
break # Stream complete
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
# =============================================================================
|
|
171
|
+
# Team Run Output Mapping Functions
|
|
172
|
+
# =============================================================================
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def map_task_result_to_team_run_output(
|
|
176
|
+
task_result: TaskResult,
|
|
177
|
+
team_id: str,
|
|
178
|
+
user_id: Optional[str] = None,
|
|
179
|
+
) -> TeamRunOutput:
|
|
180
|
+
"""Convert A2A TaskResult to Agno TeamRunOutput.
|
|
181
|
+
|
|
182
|
+
Maps the A2A protocol response structure to Agno's team format,
|
|
183
|
+
enabling seamless integration with Agno's team infrastructure.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
task_result: A2A TaskResult from send_message()
|
|
187
|
+
team_id: Optional team identifier to include in output
|
|
188
|
+
user_id: Optional user identifier to include in output
|
|
189
|
+
Returns:
|
|
190
|
+
TeamRunOutput: Agno-compatible team run output
|
|
191
|
+
"""
|
|
192
|
+
# Extract media from artifacts
|
|
193
|
+
images: List[Image] = []
|
|
194
|
+
videos: List[Video] = []
|
|
195
|
+
audio: List[Audio] = []
|
|
196
|
+
files: List[File] = []
|
|
197
|
+
|
|
198
|
+
for artifact in task_result.artifacts:
|
|
199
|
+
_classify_artifact(artifact, images, videos, audio, files)
|
|
200
|
+
|
|
201
|
+
return TeamRunOutput(
|
|
202
|
+
content=task_result.content,
|
|
203
|
+
run_id=task_result.task_id,
|
|
204
|
+
session_id=task_result.context_id,
|
|
205
|
+
team_id=team_id,
|
|
206
|
+
user_id=user_id,
|
|
207
|
+
images=images if images else None,
|
|
208
|
+
videos=videos if videos else None,
|
|
209
|
+
audio=audio if audio else None,
|
|
210
|
+
files=files if files else None,
|
|
211
|
+
metadata=task_result.metadata,
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
async def map_stream_events_to_team_run_events(
|
|
216
|
+
stream: AsyncIterator[StreamEvent],
|
|
217
|
+
team_id: str,
|
|
218
|
+
) -> AsyncIterator[TeamRunOutputEvent]:
|
|
219
|
+
"""Convert A2A stream events to Agno team run events.
|
|
220
|
+
|
|
221
|
+
Transforms the A2A streaming protocol events into Agno's team event system,
|
|
222
|
+
enabling real-time streaming from A2A servers to work with Agno team consumers.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
stream: AsyncIterator of A2A StreamEvents
|
|
226
|
+
team_id: Optional team identifier to include in events
|
|
227
|
+
user_id: Optional user identifier to include in events
|
|
228
|
+
Yields:
|
|
229
|
+
TeamRunOutputEvent: Agno-compatible team run output events
|
|
230
|
+
"""
|
|
231
|
+
run_id: Optional[str] = None
|
|
232
|
+
session_id: Optional[str] = None
|
|
233
|
+
accumulated_content = ""
|
|
234
|
+
|
|
235
|
+
async for event in stream:
|
|
236
|
+
# Capture IDs from events
|
|
237
|
+
if event.task_id:
|
|
238
|
+
run_id = event.task_id
|
|
239
|
+
if event.context_id:
|
|
240
|
+
session_id = event.context_id
|
|
241
|
+
|
|
242
|
+
# Map event types
|
|
243
|
+
if event.event_type == "working":
|
|
244
|
+
yield TeamRunStartedEvent(
|
|
245
|
+
run_id=run_id,
|
|
246
|
+
session_id=session_id,
|
|
247
|
+
team_id=team_id,
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
elif event.is_content and event.content:
|
|
251
|
+
accumulated_content += event.content
|
|
252
|
+
yield TeamRunContentEvent(
|
|
253
|
+
content=event.content,
|
|
254
|
+
run_id=run_id,
|
|
255
|
+
session_id=session_id,
|
|
256
|
+
team_id=team_id,
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
elif event.is_final:
|
|
260
|
+
# Use content from final event or accumulated content
|
|
261
|
+
final_content = event.content if event.content else accumulated_content
|
|
262
|
+
yield TeamRunCompletedEvent(
|
|
263
|
+
content=final_content,
|
|
264
|
+
run_id=run_id,
|
|
265
|
+
session_id=session_id,
|
|
266
|
+
team_id=team_id,
|
|
267
|
+
)
|
|
268
|
+
break # Stream complete
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
# =============================================================================
|
|
272
|
+
# Workflow Run Output Mapping Functions
|
|
273
|
+
# =============================================================================
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def map_task_result_to_workflow_run_output(
|
|
277
|
+
task_result: TaskResult,
|
|
278
|
+
workflow_id: str,
|
|
279
|
+
user_id: Optional[str] = None,
|
|
280
|
+
) -> WorkflowRunOutput:
|
|
281
|
+
"""Convert A2A TaskResult to Agno WorkflowRunOutput.
|
|
282
|
+
|
|
283
|
+
Maps the A2A protocol response structure to Agno's workflow format,
|
|
284
|
+
enabling seamless integration with Agno's workflow infrastructure.
|
|
285
|
+
|
|
286
|
+
Args:
|
|
287
|
+
task_result: A2A TaskResult from send_message()
|
|
288
|
+
workflow_id: Optional workflow identifier to include in output
|
|
289
|
+
user_id: Optional user identifier to include in output
|
|
290
|
+
Returns:
|
|
291
|
+
WorkflowRunOutput: Agno-compatible workflow run output
|
|
292
|
+
"""
|
|
293
|
+
# Extract media from artifacts
|
|
294
|
+
images: List[Image] = []
|
|
295
|
+
videos: List[Video] = []
|
|
296
|
+
audio: List[Audio] = []
|
|
297
|
+
files: List[File] = []
|
|
298
|
+
|
|
299
|
+
for artifact in task_result.artifacts:
|
|
300
|
+
_classify_artifact(artifact, images, videos, audio, files)
|
|
301
|
+
|
|
302
|
+
return WorkflowRunOutput(
|
|
303
|
+
content=task_result.content,
|
|
304
|
+
run_id=task_result.task_id,
|
|
305
|
+
session_id=task_result.context_id,
|
|
306
|
+
workflow_id=workflow_id,
|
|
307
|
+
user_id=user_id,
|
|
308
|
+
images=images if images else None,
|
|
309
|
+
videos=videos if videos else None,
|
|
310
|
+
audio=audio if audio else None,
|
|
311
|
+
metadata=task_result.metadata,
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
async def map_stream_events_to_workflow_run_events(
|
|
316
|
+
stream: AsyncIterator[StreamEvent],
|
|
317
|
+
workflow_id: str,
|
|
318
|
+
) -> AsyncIterator[Union[WorkflowRunOutputEvent, TeamRunOutputEvent, RunOutputEvent]]:
|
|
319
|
+
"""Convert A2A stream events to Agno workflow run events.
|
|
320
|
+
|
|
321
|
+
Transforms the A2A streaming protocol events into Agno's workflow event system,
|
|
322
|
+
enabling real-time streaming from A2A servers to work with Agno workflow consumers.
|
|
323
|
+
|
|
324
|
+
Args:
|
|
325
|
+
stream: AsyncIterator of A2A StreamEvents
|
|
326
|
+
workflow_id: Optional workflow identifier to include in events
|
|
327
|
+
user_id: Optional user identifier to include in events
|
|
328
|
+
Yields:
|
|
329
|
+
WorkflowRunOutputEvent: Agno-compatible workflow run output events
|
|
330
|
+
"""
|
|
331
|
+
run_id: Optional[str] = None
|
|
332
|
+
session_id: Optional[str] = None
|
|
333
|
+
accumulated_content = ""
|
|
334
|
+
|
|
335
|
+
async for event in stream:
|
|
336
|
+
# Capture IDs from events
|
|
337
|
+
if event.task_id:
|
|
338
|
+
run_id = event.task_id
|
|
339
|
+
if event.context_id:
|
|
340
|
+
session_id = event.context_id
|
|
341
|
+
|
|
342
|
+
# Map event types
|
|
343
|
+
if event.event_type == "working":
|
|
344
|
+
yield WorkflowStartedEvent(
|
|
345
|
+
run_id=run_id,
|
|
346
|
+
session_id=session_id,
|
|
347
|
+
workflow_id=workflow_id,
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
elif event.is_content and event.content:
|
|
351
|
+
accumulated_content += event.content
|
|
352
|
+
# TODO: We don't have workflow content events and we don't know which agent or team created the content, so we're using the workflow_id as the agent_id.
|
|
353
|
+
yield RunContentEvent(
|
|
354
|
+
content=event.content,
|
|
355
|
+
run_id=run_id,
|
|
356
|
+
session_id=session_id,
|
|
357
|
+
agent_id=workflow_id,
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
elif event.is_final:
|
|
361
|
+
# Use content from final event or accumulated content
|
|
362
|
+
final_content = event.content if event.content else accumulated_content
|
|
363
|
+
yield WorkflowCompletedEvent(
|
|
364
|
+
content=final_content,
|
|
365
|
+
run_id=run_id,
|
|
366
|
+
session_id=session_id,
|
|
367
|
+
workflow_id=workflow_id,
|
|
368
|
+
)
|
|
369
|
+
break # Stream complete
|