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/remote/base.py
ADDED
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from abc import abstractmethod
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from datetime import date
|
|
5
|
+
from typing import TYPE_CHECKING, Any, AsyncIterator, Dict, List, Literal, Optional, Sequence, Tuple, Union
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
|
|
9
|
+
from agno.db.base import SessionType
|
|
10
|
+
from agno.media import Audio, File, Image, Video
|
|
11
|
+
from agno.models.message import Message
|
|
12
|
+
from agno.models.response import ToolExecution
|
|
13
|
+
from agno.run.agent import RunOutput, RunOutputEvent
|
|
14
|
+
from agno.run.team import TeamRunOutput, TeamRunOutputEvent
|
|
15
|
+
from agno.run.workflow import WorkflowRunOutput, WorkflowRunOutputEvent
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from fastapi import UploadFile
|
|
19
|
+
|
|
20
|
+
from agno.client import AgentOSClient
|
|
21
|
+
from agno.client.a2a import A2AClient
|
|
22
|
+
from agno.client.a2a.schemas import AgentCard
|
|
23
|
+
from agno.os.routers.evals.schemas import EvalSchema
|
|
24
|
+
from agno.os.routers.knowledge.schemas import (
|
|
25
|
+
ConfigResponseSchema,
|
|
26
|
+
ContentResponseSchema,
|
|
27
|
+
ContentStatusResponse,
|
|
28
|
+
VectorSearchResult,
|
|
29
|
+
)
|
|
30
|
+
from agno.os.routers.memory.schemas import OptimizeMemoriesResponse, UserMemorySchema, UserStatsSchema
|
|
31
|
+
from agno.os.routers.metrics.schemas import DayAggregatedMetrics, MetricsResponse
|
|
32
|
+
from agno.os.routers.traces.schemas import TraceDetail, TraceNode, TraceSessionStats, TraceSummary
|
|
33
|
+
from agno.os.schema import (
|
|
34
|
+
AgentSessionDetailSchema,
|
|
35
|
+
ConfigResponse,
|
|
36
|
+
PaginatedResponse,
|
|
37
|
+
RunSchema,
|
|
38
|
+
SessionSchema,
|
|
39
|
+
TeamRunSchema,
|
|
40
|
+
TeamSessionDetailSchema,
|
|
41
|
+
WorkflowRunSchema,
|
|
42
|
+
WorkflowSessionDetailSchema,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class RemoteDb:
|
|
48
|
+
id: str
|
|
49
|
+
client: "AgentOSClient"
|
|
50
|
+
session_table_name: Optional[str] = None
|
|
51
|
+
knowledge_table_name: Optional[str] = None
|
|
52
|
+
memory_table_name: Optional[str] = None
|
|
53
|
+
metrics_table_name: Optional[str] = None
|
|
54
|
+
eval_table_name: Optional[str] = None
|
|
55
|
+
traces_table_name: Optional[str] = None
|
|
56
|
+
spans_table_name: Optional[str] = None
|
|
57
|
+
culture_table_name: Optional[str] = None
|
|
58
|
+
|
|
59
|
+
@classmethod
|
|
60
|
+
def from_config(
|
|
61
|
+
cls,
|
|
62
|
+
db_id: str,
|
|
63
|
+
client: "AgentOSClient",
|
|
64
|
+
config: "ConfigResponse",
|
|
65
|
+
) -> Optional["RemoteDb"]:
|
|
66
|
+
"""Create a RemoteDb instance from an AgentResponse/TeamResponse/WorkflowResponse and ConfigResponse.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
db_id (str): The id of the remote database
|
|
70
|
+
client: The AgentOSClient for remote operations.
|
|
71
|
+
config: The ConfigResponse containing database table information.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
RemoteDb instance if db_id is present, None otherwise.
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
session_table_name = None
|
|
78
|
+
knowledge_table_name = None
|
|
79
|
+
memory_table_name = None
|
|
80
|
+
metrics_table_name = None
|
|
81
|
+
eval_table_name = None
|
|
82
|
+
traces_table_name = None
|
|
83
|
+
|
|
84
|
+
if config and config.session and config.session.dbs is not None:
|
|
85
|
+
session_dbs = [db for db in config.session.dbs if db.db_id == db_id]
|
|
86
|
+
session_table_name = session_dbs[0].tables[0] if session_dbs and session_dbs[0].tables else None
|
|
87
|
+
|
|
88
|
+
if config and config.knowledge and config.knowledge.dbs is not None:
|
|
89
|
+
knowledge_dbs = [db for db in config.knowledge.dbs if db.db_id == db_id]
|
|
90
|
+
knowledge_table_name = knowledge_dbs[0].tables[0] if knowledge_dbs and knowledge_dbs[0].tables else None
|
|
91
|
+
|
|
92
|
+
if config and config.memory and config.memory.dbs is not None:
|
|
93
|
+
memory_dbs = [db for db in config.memory.dbs if db.db_id == db_id]
|
|
94
|
+
memory_table_name = memory_dbs[0].tables[0] if memory_dbs and memory_dbs[0].tables else None
|
|
95
|
+
|
|
96
|
+
if config and config.metrics and config.metrics.dbs is not None:
|
|
97
|
+
metrics_dbs = [db for db in config.metrics.dbs if db.db_id == db_id]
|
|
98
|
+
metrics_table_name = metrics_dbs[0].tables[0] if metrics_dbs and metrics_dbs[0].tables else None
|
|
99
|
+
|
|
100
|
+
if config and config.evals and config.evals.dbs is not None:
|
|
101
|
+
eval_dbs = [db for db in config.evals.dbs if db.db_id == db_id]
|
|
102
|
+
eval_table_name = eval_dbs[0].tables[0] if eval_dbs and eval_dbs[0].tables else None
|
|
103
|
+
|
|
104
|
+
if config and config.traces and config.traces.dbs is not None:
|
|
105
|
+
traces_dbs = [db for db in config.traces.dbs if db.db_id == db_id]
|
|
106
|
+
traces_table_name = traces_dbs[0].tables[0] if traces_dbs and traces_dbs[0].tables else None
|
|
107
|
+
|
|
108
|
+
return cls(
|
|
109
|
+
id=db_id,
|
|
110
|
+
client=client,
|
|
111
|
+
session_table_name=session_table_name,
|
|
112
|
+
knowledge_table_name=knowledge_table_name,
|
|
113
|
+
memory_table_name=memory_table_name,
|
|
114
|
+
metrics_table_name=metrics_table_name,
|
|
115
|
+
eval_table_name=eval_table_name,
|
|
116
|
+
traces_table_name=traces_table_name,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
# SESSIONS
|
|
120
|
+
async def get_sessions(self, **kwargs: Any) -> "PaginatedResponse[SessionSchema]":
|
|
121
|
+
return await self.client.get_sessions(**kwargs)
|
|
122
|
+
|
|
123
|
+
async def get_session(
|
|
124
|
+
self, session_id: str, **kwargs: Any
|
|
125
|
+
) -> Union["AgentSessionDetailSchema", "TeamSessionDetailSchema", "WorkflowSessionDetailSchema"]:
|
|
126
|
+
return await self.client.get_session(session_id, **kwargs)
|
|
127
|
+
|
|
128
|
+
async def get_session_runs(
|
|
129
|
+
self, session_id: str, **kwargs: Any
|
|
130
|
+
) -> List[Union["RunSchema", "TeamRunSchema", "WorkflowRunSchema"]]:
|
|
131
|
+
return await self.client.get_session_runs(session_id, **kwargs)
|
|
132
|
+
|
|
133
|
+
async def create_session(
|
|
134
|
+
self,
|
|
135
|
+
session_id: Optional[str] = None,
|
|
136
|
+
session_name: Optional[str] = None,
|
|
137
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
138
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
139
|
+
user_id: Optional[str] = None,
|
|
140
|
+
agent_id: Optional[str] = None,
|
|
141
|
+
team_id: Optional[str] = None,
|
|
142
|
+
workflow_id: Optional[str] = None,
|
|
143
|
+
**kwargs: Any,
|
|
144
|
+
) -> Union["AgentSessionDetailSchema", "TeamSessionDetailSchema", "WorkflowSessionDetailSchema"]:
|
|
145
|
+
return await self.client.create_session(
|
|
146
|
+
session_id=session_id,
|
|
147
|
+
session_name=session_name,
|
|
148
|
+
session_state=session_state,
|
|
149
|
+
metadata=metadata,
|
|
150
|
+
user_id=user_id,
|
|
151
|
+
agent_id=agent_id,
|
|
152
|
+
team_id=team_id,
|
|
153
|
+
workflow_id=workflow_id,
|
|
154
|
+
**kwargs,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
async def get_session_run(
|
|
158
|
+
self, session_id: str, run_id: str, **kwargs: Any
|
|
159
|
+
) -> Union["RunSchema", "TeamRunSchema", "WorkflowRunSchema"]:
|
|
160
|
+
return await self.client.get_session_run(session_id, run_id, **kwargs)
|
|
161
|
+
|
|
162
|
+
async def rename_session(
|
|
163
|
+
self, session_id: str, session_name: str, **kwargs: Any
|
|
164
|
+
) -> Union["AgentSessionDetailSchema", "TeamSessionDetailSchema", "WorkflowSessionDetailSchema"]:
|
|
165
|
+
return await self.client.rename_session(session_id, session_name, **kwargs)
|
|
166
|
+
|
|
167
|
+
async def update_session(
|
|
168
|
+
self, session_id: str, session_type: SessionType, **kwargs: Any
|
|
169
|
+
) -> Union["AgentSessionDetailSchema", "TeamSessionDetailSchema", "WorkflowSessionDetailSchema"]:
|
|
170
|
+
return await self.client.update_session(session_id=session_id, session_type=session_type, **kwargs)
|
|
171
|
+
|
|
172
|
+
async def delete_session(self, session_id: str, **kwargs: Any) -> None:
|
|
173
|
+
return await self.client.delete_session(session_id, **kwargs)
|
|
174
|
+
|
|
175
|
+
async def delete_sessions(self, session_ids: List[str], session_types: List[SessionType], **kwargs: Any) -> None:
|
|
176
|
+
return await self.client.delete_sessions(session_ids, session_types, **kwargs)
|
|
177
|
+
|
|
178
|
+
# MEMORIES
|
|
179
|
+
async def create_memory(self, memory: str, topics: List[str], user_id: str, **kwargs: Any) -> "UserMemorySchema":
|
|
180
|
+
return await self.client.create_memory(memory=memory, topics=topics, user_id=user_id, **kwargs)
|
|
181
|
+
|
|
182
|
+
async def delete_memory(self, memory_id: str, **kwargs: Any) -> None:
|
|
183
|
+
return await self.client.delete_memory(memory_id, **kwargs)
|
|
184
|
+
|
|
185
|
+
async def delete_memories(self, memory_ids: List[str], **kwargs: Any) -> None:
|
|
186
|
+
return await self.client.delete_memories(memory_ids, **kwargs)
|
|
187
|
+
|
|
188
|
+
async def get_memory(self, memory_id: str, **kwargs: Any) -> "UserMemorySchema":
|
|
189
|
+
return await self.client.get_memory(memory_id, **kwargs)
|
|
190
|
+
|
|
191
|
+
async def get_memories(self, user_id: Optional[str] = None, **kwargs: Any) -> "PaginatedResponse[UserMemorySchema]":
|
|
192
|
+
return await self.client.list_memories(user_id, **kwargs)
|
|
193
|
+
|
|
194
|
+
async def update_memory(self, memory_id: str, **kwargs: Any) -> "UserMemorySchema":
|
|
195
|
+
return await self.client.update_memory(memory_id, **kwargs)
|
|
196
|
+
|
|
197
|
+
async def get_user_memory_stats(self, **kwargs: Any) -> "PaginatedResponse[UserStatsSchema]":
|
|
198
|
+
return await self.client.get_user_memory_stats(**kwargs)
|
|
199
|
+
|
|
200
|
+
async def optimize_memories(self, **kwargs: Any) -> "OptimizeMemoriesResponse":
|
|
201
|
+
return await self.client.optimize_memories(**kwargs)
|
|
202
|
+
|
|
203
|
+
async def get_memory_topics(self, **kwargs: Any) -> List[str]:
|
|
204
|
+
return await self.client.get_memory_topics(**kwargs)
|
|
205
|
+
|
|
206
|
+
# TRACES
|
|
207
|
+
async def get_traces(self, **kwargs: Any) -> "PaginatedResponse[TraceSummary]":
|
|
208
|
+
return await self.client.get_traces(**kwargs)
|
|
209
|
+
|
|
210
|
+
async def get_trace(self, trace_id: str, **kwargs: Any) -> Union["TraceDetail", "TraceNode"]:
|
|
211
|
+
return await self.client.get_trace(trace_id, **kwargs)
|
|
212
|
+
|
|
213
|
+
async def get_trace_session_stats(self, **kwargs: Any) -> "PaginatedResponse[TraceSessionStats]":
|
|
214
|
+
return await self.client.get_trace_session_stats(**kwargs)
|
|
215
|
+
|
|
216
|
+
# EVALS
|
|
217
|
+
async def get_eval_runs(self, **kwargs: Any) -> "PaginatedResponse[EvalSchema]":
|
|
218
|
+
return await self.client.list_eval_runs(**kwargs)
|
|
219
|
+
|
|
220
|
+
async def get_eval_run(self, eval_run_id: str, **kwargs: Any) -> "EvalSchema":
|
|
221
|
+
return await self.client.get_eval_run(eval_run_id, **kwargs)
|
|
222
|
+
|
|
223
|
+
async def delete_eval_runs(self, eval_run_ids: List[str], **kwargs: Any) -> None:
|
|
224
|
+
return await self.client.delete_eval_runs(eval_run_ids, **kwargs)
|
|
225
|
+
|
|
226
|
+
async def update_eval_run(self, eval_run_id: str, **kwargs: Any) -> "EvalSchema":
|
|
227
|
+
return await self.client.update_eval_run(eval_run_id, **kwargs)
|
|
228
|
+
|
|
229
|
+
async def create_eval_run(self, **kwargs: Any) -> Optional["EvalSchema"]:
|
|
230
|
+
return await self.client.run_eval(**kwargs)
|
|
231
|
+
|
|
232
|
+
# METRICS
|
|
233
|
+
async def get_metrics(
|
|
234
|
+
self, starting_date: Optional[date] = None, ending_date: Optional[date] = None, **kwargs: Any
|
|
235
|
+
) -> "MetricsResponse":
|
|
236
|
+
return await self.client.get_metrics(starting_date=starting_date, ending_date=ending_date, **kwargs)
|
|
237
|
+
|
|
238
|
+
async def refresh_metrics(self, **kwargs: Any) -> List["DayAggregatedMetrics"]:
|
|
239
|
+
return await self.client.refresh_metrics(**kwargs)
|
|
240
|
+
|
|
241
|
+
# OTHER
|
|
242
|
+
async def migrate_database(self, target_version: Optional[str] = None) -> None:
|
|
243
|
+
"""Migrate the database to a target version.
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
target_version: Target version to migrate to
|
|
247
|
+
"""
|
|
248
|
+
|
|
249
|
+
return await self.client.migrate_database(self.id, target_version)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
@dataclass
|
|
253
|
+
class RemoteKnowledge:
|
|
254
|
+
client: "AgentOSClient"
|
|
255
|
+
contents_db: Optional[RemoteDb] = None
|
|
256
|
+
|
|
257
|
+
async def get_config(self, headers: Optional[Dict[str, str]] = None) -> "ConfigResponseSchema":
|
|
258
|
+
return await self.client.get_knowledge_config(
|
|
259
|
+
db_id=self.contents_db.id if self.contents_db else None, headers=headers
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
async def search_knowledge(self, query: str, **kwargs: Any) -> "PaginatedResponse[VectorSearchResult]":
|
|
263
|
+
return await self.client.search_knowledge(query, **kwargs)
|
|
264
|
+
|
|
265
|
+
async def upload_content(
|
|
266
|
+
self,
|
|
267
|
+
name: Optional[str] = None,
|
|
268
|
+
description: Optional[str] = None,
|
|
269
|
+
url: Optional[str] = None,
|
|
270
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
271
|
+
file: Optional[Union[File, "UploadFile"]] = None,
|
|
272
|
+
text_content: Optional[str] = None,
|
|
273
|
+
reader_id: Optional[str] = None,
|
|
274
|
+
chunker: Optional[str] = None,
|
|
275
|
+
chunk_size: Optional[int] = None,
|
|
276
|
+
chunk_overlap: Optional[int] = None,
|
|
277
|
+
db_id: Optional[str] = None,
|
|
278
|
+
**kwargs: Any,
|
|
279
|
+
) -> "ContentResponseSchema":
|
|
280
|
+
return await self.client.upload_knowledge_content(
|
|
281
|
+
name=name,
|
|
282
|
+
description=description,
|
|
283
|
+
url=url,
|
|
284
|
+
metadata=metadata,
|
|
285
|
+
file=file,
|
|
286
|
+
text_content=text_content,
|
|
287
|
+
reader_id=reader_id,
|
|
288
|
+
chunker=chunker,
|
|
289
|
+
chunk_size=chunk_size,
|
|
290
|
+
chunk_overlap=chunk_overlap,
|
|
291
|
+
db_id=db_id,
|
|
292
|
+
**kwargs,
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
async def update_content(
|
|
296
|
+
self,
|
|
297
|
+
content_id: str,
|
|
298
|
+
name: Optional[str] = None,
|
|
299
|
+
description: Optional[str] = None,
|
|
300
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
301
|
+
reader_id: Optional[str] = None,
|
|
302
|
+
db_id: Optional[str] = None,
|
|
303
|
+
**kwargs: Any,
|
|
304
|
+
) -> "ContentResponseSchema":
|
|
305
|
+
return await self.client.update_knowledge_content(
|
|
306
|
+
content_id=content_id,
|
|
307
|
+
name=name,
|
|
308
|
+
description=description,
|
|
309
|
+
metadata=metadata,
|
|
310
|
+
reader_id=reader_id,
|
|
311
|
+
db_id=db_id,
|
|
312
|
+
**kwargs,
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
async def get_content(
|
|
316
|
+
self,
|
|
317
|
+
limit: Optional[int] = None,
|
|
318
|
+
page: Optional[int] = None,
|
|
319
|
+
sort_by: Optional[str] = None,
|
|
320
|
+
sort_order: Optional[str] = None,
|
|
321
|
+
db_id: Optional[str] = None,
|
|
322
|
+
**kwargs: Any,
|
|
323
|
+
) -> "PaginatedResponse[ContentResponseSchema]":
|
|
324
|
+
return await self.client.list_knowledge_content(
|
|
325
|
+
limit=limit, page=page, sort_by=sort_by, sort_order=sort_order, db_id=db_id, **kwargs
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
async def get_content_by_id(
|
|
329
|
+
self, content_id: str, db_id: Optional[str] = None, **kwargs: Any
|
|
330
|
+
) -> "ContentResponseSchema":
|
|
331
|
+
return await self.client.get_knowledge_content(content_id=content_id, db_id=db_id, **kwargs)
|
|
332
|
+
|
|
333
|
+
async def delete_content_by_id(self, content_id: str, db_id: Optional[str] = None, **kwargs: Any) -> None:
|
|
334
|
+
await self.client.delete_knowledge_content(content_id=content_id, db_id=db_id, **kwargs)
|
|
335
|
+
|
|
336
|
+
async def delete_all_content(self, db_id: Optional[str] = None, **kwargs: Any) -> None:
|
|
337
|
+
await self.client.delete_all_knowledge_content(db_id=db_id, **kwargs)
|
|
338
|
+
|
|
339
|
+
async def get_content_status(
|
|
340
|
+
self, content_id: str, db_id: Optional[str] = None, **kwargs: Any
|
|
341
|
+
) -> "ContentStatusResponse":
|
|
342
|
+
return await self.client.get_knowledge_content_status(content_id=content_id, db_id=db_id, **kwargs)
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
@dataclass
|
|
346
|
+
class BaseRemote:
|
|
347
|
+
# Private cache for OS config with TTL: (config, timestamp)
|
|
348
|
+
_cached_config: Optional[Tuple["ConfigResponse", float]] = field(default=None, init=False, repr=False)
|
|
349
|
+
# Private cache for agent card with TTL: (agent_card, timestamp)
|
|
350
|
+
_cached_agent_card: Optional[Tuple[Optional["AgentCard"], float]] = field(default=None, init=False, repr=False)
|
|
351
|
+
|
|
352
|
+
def __init__(
|
|
353
|
+
self,
|
|
354
|
+
base_url: str,
|
|
355
|
+
timeout: float = 60.0,
|
|
356
|
+
protocol: Literal["agentos", "a2a"] = "agentos",
|
|
357
|
+
a2a_protocol: Literal["json-rpc", "rest"] = "rest",
|
|
358
|
+
config_ttl: float = 300.0,
|
|
359
|
+
):
|
|
360
|
+
"""Initialize BaseRemote for remote execution.
|
|
361
|
+
|
|
362
|
+
Supports two protocols:
|
|
363
|
+
- "agentos": Agno's proprietary AgentOS REST API (default)
|
|
364
|
+
- "a2a": A2A (Agent-to-Agent) protocol for cross-framework communication
|
|
365
|
+
|
|
366
|
+
For local execution, provide agent/team/workflow instances.
|
|
367
|
+
For remote execution, provide base_url.
|
|
368
|
+
|
|
369
|
+
Args:
|
|
370
|
+
base_url: Base URL for remote instance (e.g., "http://localhost:7777")
|
|
371
|
+
timeout: Request timeout in seconds (default: 60)
|
|
372
|
+
protocol: Communication protocol - "agentos" (default) or "a2a"
|
|
373
|
+
a2a_protocol: For A2A protocol only - Whether to use JSON-RPC or REST protocol.
|
|
374
|
+
config_ttl: Time-to-live for cached config in seconds (default: 300)
|
|
375
|
+
"""
|
|
376
|
+
self.base_url = base_url.rstrip("/")
|
|
377
|
+
self.timeout: float = timeout
|
|
378
|
+
self.protocol = protocol
|
|
379
|
+
self.a2a_protocol = a2a_protocol
|
|
380
|
+
self.config_ttl: float = config_ttl
|
|
381
|
+
self._cached_config = None
|
|
382
|
+
self._cached_agent_card = None
|
|
383
|
+
|
|
384
|
+
self.agentos_client = None
|
|
385
|
+
self.a2a_client = None
|
|
386
|
+
|
|
387
|
+
if protocol == "agentos":
|
|
388
|
+
self.agentos_client = self.get_os_client()
|
|
389
|
+
elif protocol == "a2a":
|
|
390
|
+
self.a2a_client = self.get_a2a_client()
|
|
391
|
+
else:
|
|
392
|
+
raise ValueError(f"Invalid protocol: {protocol}")
|
|
393
|
+
|
|
394
|
+
def get_os_client(self) -> "AgentOSClient":
|
|
395
|
+
"""Get an AgentOSClient for fetching remote configuration.
|
|
396
|
+
|
|
397
|
+
This is used internally by AgentOS to fetch configuration from remote
|
|
398
|
+
AgentOS instances when this runner represents a remote resource.
|
|
399
|
+
|
|
400
|
+
Returns:
|
|
401
|
+
AgentOSClient: Client configured for this remote resource's base URL
|
|
402
|
+
"""
|
|
403
|
+
from agno.client import AgentOSClient
|
|
404
|
+
|
|
405
|
+
return AgentOSClient(
|
|
406
|
+
base_url=self.base_url,
|
|
407
|
+
timeout=self.timeout,
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
def get_a2a_client(self) -> "A2AClient":
|
|
411
|
+
"""Get an A2AClient for A2A protocol communication.
|
|
412
|
+
|
|
413
|
+
Returns cached client if available, otherwise creates a new one.
|
|
414
|
+
This method provides lazy initialization of the A2A client.
|
|
415
|
+
|
|
416
|
+
Returns:
|
|
417
|
+
A2AClient: Client configured for A2A protocol communication
|
|
418
|
+
"""
|
|
419
|
+
from agno.client.a2a import A2AClient
|
|
420
|
+
|
|
421
|
+
return A2AClient(
|
|
422
|
+
base_url=self.base_url,
|
|
423
|
+
timeout=int(self.timeout),
|
|
424
|
+
protocol=self.a2a_protocol,
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
@property
|
|
428
|
+
def _config(self) -> Optional["ConfigResponse"]:
|
|
429
|
+
"""Get the OS config from remote, cached with TTL."""
|
|
430
|
+
from agno.os.schema import ConfigResponse
|
|
431
|
+
|
|
432
|
+
if self.protocol == "a2a":
|
|
433
|
+
return None
|
|
434
|
+
|
|
435
|
+
current_time = time.time()
|
|
436
|
+
|
|
437
|
+
# Check if cache is valid
|
|
438
|
+
if self._cached_config is not None:
|
|
439
|
+
config, cached_at = self._cached_config
|
|
440
|
+
if current_time - cached_at < self.config_ttl:
|
|
441
|
+
return config
|
|
442
|
+
|
|
443
|
+
# Fetch fresh config
|
|
444
|
+
config: ConfigResponse = self.agentos_client.get_config() # type: ignore
|
|
445
|
+
self._cached_config = (config, current_time)
|
|
446
|
+
return config
|
|
447
|
+
|
|
448
|
+
async def refresh_os_config(self) -> "ConfigResponse":
|
|
449
|
+
"""Force refresh the cached OS config."""
|
|
450
|
+
from agno.os.schema import ConfigResponse
|
|
451
|
+
|
|
452
|
+
config: ConfigResponse = await self.agentos_client.aget_config() # type: ignore
|
|
453
|
+
self._cached_config = (config, time.time())
|
|
454
|
+
return config
|
|
455
|
+
|
|
456
|
+
def _get_headers(self, auth_token: Optional[str] = None) -> Dict[str, str]:
|
|
457
|
+
"""Get headers for HTTP requests.
|
|
458
|
+
|
|
459
|
+
Args:
|
|
460
|
+
auth_token: Optional JWT token for authentication
|
|
461
|
+
|
|
462
|
+
Returns:
|
|
463
|
+
Dict[str, str]: Headers including Content-Type and optional Authorization
|
|
464
|
+
"""
|
|
465
|
+
headers = {"Content-Type": "application/x-www-form-urlencoded"}
|
|
466
|
+
if auth_token:
|
|
467
|
+
headers["Authorization"] = f"Bearer {auth_token}"
|
|
468
|
+
return headers
|
|
469
|
+
|
|
470
|
+
def _get_auth_headers(self, auth_token: Optional[str] = None) -> Optional[Dict[str, str]]:
|
|
471
|
+
"""Get Authorization headers for HTTP requests.
|
|
472
|
+
|
|
473
|
+
Args:
|
|
474
|
+
auth_token: Optional JWT token for authentication
|
|
475
|
+
|
|
476
|
+
Returns:
|
|
477
|
+
Dict[str, str] with Authorization header if auth_token is provided, None otherwise
|
|
478
|
+
"""
|
|
479
|
+
if auth_token:
|
|
480
|
+
return {"Authorization": f"Bearer {auth_token}"}
|
|
481
|
+
return None
|
|
482
|
+
|
|
483
|
+
def get_agent_card(self) -> Optional["AgentCard"]:
|
|
484
|
+
"""Get agent card for A2A protocol agents, cached with TTL.
|
|
485
|
+
|
|
486
|
+
Fetches the agent card from the standard /.well-known/agent.json endpoint
|
|
487
|
+
to populate agent metadata (name, description, etc.) for A2A agents.
|
|
488
|
+
|
|
489
|
+
Returns None for non-A2A protocols or if the server doesn't support agent cards.
|
|
490
|
+
"""
|
|
491
|
+
if self.protocol != "a2a":
|
|
492
|
+
return None
|
|
493
|
+
|
|
494
|
+
current_time = time.time()
|
|
495
|
+
|
|
496
|
+
# Check if cache is valid
|
|
497
|
+
if self._cached_agent_card is not None:
|
|
498
|
+
agent_card, cached_at = self._cached_agent_card
|
|
499
|
+
if current_time - cached_at < self.config_ttl:
|
|
500
|
+
return agent_card
|
|
501
|
+
|
|
502
|
+
try:
|
|
503
|
+
agent_card = self.a2a_client.get_agent_card() # type: ignore
|
|
504
|
+
self._cached_agent_card = (agent_card, current_time)
|
|
505
|
+
return agent_card
|
|
506
|
+
except Exception:
|
|
507
|
+
self._cached_agent_card = (None, current_time)
|
|
508
|
+
return None
|
|
509
|
+
|
|
510
|
+
async def aget_agent_card(self) -> Optional["AgentCard"]:
|
|
511
|
+
"""Get agent card for A2A protocol agents, cached with TTL.
|
|
512
|
+
|
|
513
|
+
Fetches the agent card from the standard /.well-known/agent.json endpoint
|
|
514
|
+
to populate agent metadata (name, description, etc.) for A2A agents.
|
|
515
|
+
|
|
516
|
+
Returns None for non-A2A protocols or if the server doesn't support agent cards.
|
|
517
|
+
"""
|
|
518
|
+
if self.protocol != "a2a":
|
|
519
|
+
return None
|
|
520
|
+
|
|
521
|
+
current_time = time.time()
|
|
522
|
+
|
|
523
|
+
# Check if cache is valid
|
|
524
|
+
if self._cached_agent_card is not None:
|
|
525
|
+
agent_card, cached_at = self._cached_agent_card
|
|
526
|
+
if current_time - cached_at < self.config_ttl:
|
|
527
|
+
return agent_card
|
|
528
|
+
|
|
529
|
+
try:
|
|
530
|
+
agent_card = await self.a2a_client.aget_agent_card() # type: ignore
|
|
531
|
+
self._cached_agent_card = (agent_card, current_time)
|
|
532
|
+
return agent_card
|
|
533
|
+
except Exception:
|
|
534
|
+
self._cached_agent_card = (None, current_time)
|
|
535
|
+
return None
|
|
536
|
+
|
|
537
|
+
@abstractmethod
|
|
538
|
+
def arun( # type: ignore
|
|
539
|
+
self,
|
|
540
|
+
input: Union[str, List, Dict, Message, BaseModel, List[Message]],
|
|
541
|
+
*,
|
|
542
|
+
stream: Optional[bool] = None,
|
|
543
|
+
user_id: Optional[str] = None,
|
|
544
|
+
session_id: Optional[str] = None,
|
|
545
|
+
session_state: Optional[Dict[str, Any]] = None,
|
|
546
|
+
audio: Optional[Sequence[Audio]] = None,
|
|
547
|
+
images: Optional[Sequence[Image]] = None,
|
|
548
|
+
videos: Optional[Sequence[Video]] = None,
|
|
549
|
+
files: Optional[Sequence[File]] = None,
|
|
550
|
+
stream_events: Optional[bool] = None,
|
|
551
|
+
retries: Optional[int] = None,
|
|
552
|
+
knowledge_filters: Optional[Dict[str, Any]] = None,
|
|
553
|
+
add_history_to_context: Optional[bool] = None,
|
|
554
|
+
add_dependencies_to_context: Optional[bool] = None,
|
|
555
|
+
add_session_state_to_context: Optional[bool] = None,
|
|
556
|
+
dependencies: Optional[Dict[str, Any]] = None,
|
|
557
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
558
|
+
auth_token: Optional[str] = None,
|
|
559
|
+
**kwargs: Any,
|
|
560
|
+
) -> Union[
|
|
561
|
+
RunOutput,
|
|
562
|
+
TeamRunOutput,
|
|
563
|
+
WorkflowRunOutput,
|
|
564
|
+
AsyncIterator[Union[RunOutputEvent, TeamRunOutputEvent, WorkflowRunOutputEvent]],
|
|
565
|
+
]:
|
|
566
|
+
raise NotImplementedError("arun method must be implemented by the subclass")
|
|
567
|
+
|
|
568
|
+
@abstractmethod
|
|
569
|
+
async def acontinue_run( # type: ignore
|
|
570
|
+
self,
|
|
571
|
+
run_id: str,
|
|
572
|
+
stream: Optional[bool] = None,
|
|
573
|
+
updated_tools: Optional[List[ToolExecution]] = None,
|
|
574
|
+
user_id: Optional[str] = None,
|
|
575
|
+
session_id: Optional[str] = None,
|
|
576
|
+
) -> Union[RunOutput, TeamRunOutput, WorkflowRunOutput]:
|
|
577
|
+
raise NotImplementedError("acontinue_run method must be implemented by the subclass")
|
|
578
|
+
|
|
579
|
+
@abstractmethod
|
|
580
|
+
async def acancel_run(self, run_id: str) -> bool:
|
|
581
|
+
raise NotImplementedError("cancel_run method must be implemented by the subclass")
|
agno/run/__init__.py
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
from agno.run.base import RunContext, RunStatus
|
|
2
|
+
from agno.run.cancel import get_cancellation_manager, set_cancellation_manager
|
|
2
3
|
|
|
3
|
-
__all__ = [
|
|
4
|
-
"RunContext",
|
|
5
|
-
"RunStatus",
|
|
6
|
-
]
|
|
4
|
+
__all__ = ["RunContext", "RunStatus", "get_cancellation_manager", "set_cancellation_manager"]
|