agno 2.3.26__py3-none-any.whl → 2.4.1__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 +4 -0
- agno/agent/agent.py +1368 -541
- agno/agent/remote.py +13 -0
- agno/db/base.py +339 -0
- agno/db/postgres/async_postgres.py +116 -12
- agno/db/postgres/postgres.py +1242 -25
- agno/db/postgres/schemas.py +48 -1
- agno/db/sqlite/async_sqlite.py +119 -4
- agno/db/sqlite/schemas.py +51 -0
- agno/db/sqlite/sqlite.py +1186 -13
- agno/db/utils.py +37 -1
- agno/integrations/discord/client.py +12 -1
- agno/knowledge/__init__.py +4 -0
- agno/knowledge/chunking/code.py +1 -1
- agno/knowledge/chunking/semantic.py +1 -1
- agno/knowledge/chunking/strategy.py +4 -0
- agno/knowledge/filesystem.py +412 -0
- agno/knowledge/knowledge.py +3722 -2182
- agno/knowledge/protocol.py +134 -0
- agno/knowledge/reader/arxiv_reader.py +2 -2
- agno/knowledge/reader/base.py +9 -7
- agno/knowledge/reader/csv_reader.py +236 -13
- agno/knowledge/reader/docx_reader.py +2 -2
- agno/knowledge/reader/field_labeled_csv_reader.py +169 -5
- agno/knowledge/reader/firecrawl_reader.py +2 -2
- agno/knowledge/reader/json_reader.py +2 -2
- agno/knowledge/reader/markdown_reader.py +2 -2
- agno/knowledge/reader/pdf_reader.py +5 -4
- agno/knowledge/reader/pptx_reader.py +2 -2
- agno/knowledge/reader/reader_factory.py +118 -1
- agno/knowledge/reader/s3_reader.py +2 -2
- agno/knowledge/reader/tavily_reader.py +2 -2
- agno/knowledge/reader/text_reader.py +2 -2
- agno/knowledge/reader/web_search_reader.py +2 -2
- agno/knowledge/reader/website_reader.py +5 -3
- agno/knowledge/reader/wikipedia_reader.py +2 -2
- agno/knowledge/reader/youtube_reader.py +2 -2
- agno/knowledge/remote_content/__init__.py +29 -0
- agno/knowledge/remote_content/config.py +204 -0
- agno/knowledge/remote_content/remote_content.py +74 -17
- agno/knowledge/utils.py +37 -29
- agno/learn/__init__.py +6 -0
- agno/learn/machine.py +35 -0
- agno/learn/schemas.py +82 -11
- agno/learn/stores/__init__.py +3 -0
- agno/learn/stores/decision_log.py +1156 -0
- agno/learn/stores/learned_knowledge.py +6 -6
- agno/models/anthropic/claude.py +24 -0
- agno/models/aws/bedrock.py +20 -0
- agno/models/base.py +60 -6
- agno/models/cerebras/cerebras.py +34 -2
- agno/models/cohere/chat.py +25 -0
- agno/models/google/gemini.py +50 -5
- agno/models/litellm/chat.py +38 -0
- agno/models/n1n/__init__.py +3 -0
- agno/models/n1n/n1n.py +57 -0
- agno/models/openai/chat.py +25 -1
- agno/models/openrouter/openrouter.py +46 -0
- agno/models/perplexity/perplexity.py +2 -0
- agno/models/response.py +16 -0
- agno/os/app.py +83 -44
- agno/os/interfaces/slack/router.py +10 -1
- agno/os/interfaces/whatsapp/router.py +6 -0
- agno/os/middleware/__init__.py +2 -0
- agno/os/middleware/trailing_slash.py +27 -0
- agno/os/router.py +1 -0
- agno/os/routers/agents/router.py +29 -16
- agno/os/routers/agents/schema.py +6 -4
- agno/os/routers/components/__init__.py +3 -0
- agno/os/routers/components/components.py +475 -0
- agno/os/routers/evals/schemas.py +4 -3
- agno/os/routers/health.py +3 -3
- agno/os/routers/knowledge/knowledge.py +128 -3
- agno/os/routers/knowledge/schemas.py +12 -0
- agno/os/routers/memory/schemas.py +4 -2
- agno/os/routers/metrics/metrics.py +9 -11
- 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/teams/router.py +20 -8
- agno/os/routers/teams/schema.py +6 -4
- agno/os/routers/traces/traces.py +5 -5
- agno/os/routers/workflows/router.py +38 -11
- agno/os/routers/workflows/schema.py +1 -1
- agno/os/schema.py +92 -26
- agno/os/utils.py +84 -19
- agno/reasoning/anthropic.py +2 -2
- agno/reasoning/azure_ai_foundry.py +2 -2
- agno/reasoning/deepseek.py +2 -2
- agno/reasoning/default.py +6 -7
- agno/reasoning/gemini.py +2 -2
- agno/reasoning/helpers.py +6 -7
- agno/reasoning/manager.py +4 -10
- agno/reasoning/ollama.py +2 -2
- agno/reasoning/openai.py +2 -2
- agno/reasoning/vertexai.py +2 -2
- agno/registry/__init__.py +3 -0
- agno/registry/registry.py +68 -0
- agno/run/agent.py +59 -0
- agno/run/base.py +7 -0
- agno/run/team.py +57 -0
- agno/skills/agent_skills.py +10 -3
- agno/team/__init__.py +3 -1
- agno/team/team.py +1165 -330
- agno/tools/duckduckgo.py +25 -71
- agno/tools/exa.py +0 -21
- agno/tools/function.py +35 -83
- agno/tools/knowledge.py +9 -4
- agno/tools/mem0.py +11 -10
- agno/tools/memory.py +47 -46
- agno/tools/parallel.py +0 -7
- agno/tools/reasoning.py +30 -23
- agno/tools/tavily.py +4 -1
- agno/tools/websearch.py +93 -0
- agno/tools/website.py +1 -1
- agno/tools/wikipedia.py +1 -1
- agno/tools/workflow.py +48 -47
- agno/utils/agent.py +42 -5
- agno/utils/events.py +160 -2
- agno/utils/print_response/agent.py +0 -31
- agno/utils/print_response/team.py +0 -2
- agno/utils/print_response/workflow.py +0 -2
- agno/utils/team.py +61 -11
- agno/vectordb/lancedb/lance_db.py +4 -1
- agno/vectordb/mongodb/mongodb.py +1 -1
- agno/vectordb/pgvector/pgvector.py +3 -3
- agno/vectordb/qdrant/qdrant.py +4 -4
- agno/workflow/__init__.py +3 -1
- agno/workflow/condition.py +0 -21
- agno/workflow/loop.py +0 -21
- agno/workflow/parallel.py +0 -21
- agno/workflow/router.py +0 -21
- agno/workflow/step.py +117 -24
- agno/workflow/steps.py +0 -21
- agno/workflow/workflow.py +427 -63
- {agno-2.3.26.dist-info → agno-2.4.1.dist-info}/METADATA +49 -76
- {agno-2.3.26.dist-info → agno-2.4.1.dist-info}/RECORD +140 -126
- {agno-2.3.26.dist-info → agno-2.4.1.dist-info}/WHEEL +1 -1
- {agno-2.3.26.dist-info → agno-2.4.1.dist-info}/licenses/LICENSE +0 -0
- {agno-2.3.26.dist-info → agno-2.4.1.dist-info}/top_level.txt +0 -0
agno/agent/remote.py
CHANGED
|
@@ -23,6 +23,19 @@ class RemoteAgent(BaseRemote):
|
|
|
23
23
|
# Private cache for agent config with TTL: (config, timestamp)
|
|
24
24
|
_cached_agent_config: Optional[Tuple["AgentResponse", float]] = field(default=None, init=False, repr=False)
|
|
25
25
|
|
|
26
|
+
knowledge_filters: Optional[Dict[str, Any]] = None
|
|
27
|
+
enable_agentic_knowledge_filters: Optional[bool] = False
|
|
28
|
+
output_schema: Optional[Any] = None
|
|
29
|
+
store_media: bool = True
|
|
30
|
+
store_tool_messages: bool = True
|
|
31
|
+
store_history_messages: bool = True
|
|
32
|
+
send_media_to_model: bool = True
|
|
33
|
+
add_history_to_context: bool = False
|
|
34
|
+
num_history_runs: Optional[int] = None
|
|
35
|
+
num_history_messages: Optional[int] = None
|
|
36
|
+
debug_mode: bool = False
|
|
37
|
+
debug_level: Literal[1, 2] = 1
|
|
38
|
+
|
|
26
39
|
def __init__(
|
|
27
40
|
self,
|
|
28
41
|
base_url: str,
|
agno/db/base.py
CHANGED
|
@@ -20,6 +20,12 @@ class SessionType(str, Enum):
|
|
|
20
20
|
WORKFLOW = "workflow"
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
class ComponentType(str, Enum):
|
|
24
|
+
AGENT = "agent"
|
|
25
|
+
TEAM = "team"
|
|
26
|
+
WORKFLOW = "workflow"
|
|
27
|
+
|
|
28
|
+
|
|
23
29
|
class BaseDb(ABC):
|
|
24
30
|
"""Base abstract class for all our Database implementations."""
|
|
25
31
|
|
|
@@ -37,6 +43,9 @@ class BaseDb(ABC):
|
|
|
37
43
|
traces_table: Optional[str] = None,
|
|
38
44
|
spans_table: Optional[str] = None,
|
|
39
45
|
versions_table: Optional[str] = None,
|
|
46
|
+
components_table: Optional[str] = None,
|
|
47
|
+
component_configs_table: Optional[str] = None,
|
|
48
|
+
component_links_table: Optional[str] = None,
|
|
40
49
|
learnings_table: Optional[str] = None,
|
|
41
50
|
id: Optional[str] = None,
|
|
42
51
|
):
|
|
@@ -50,8 +59,52 @@ class BaseDb(ABC):
|
|
|
50
59
|
self.trace_table_name = traces_table or "agno_traces"
|
|
51
60
|
self.span_table_name = spans_table or "agno_spans"
|
|
52
61
|
self.versions_table_name = versions_table or "agno_schema_versions"
|
|
62
|
+
self.components_table_name = components_table or "agno_components"
|
|
63
|
+
self.component_configs_table_name = component_configs_table or "agno_component_configs"
|
|
64
|
+
self.component_links_table_name = component_links_table or "agno_component_links"
|
|
53
65
|
self.learnings_table_name = learnings_table or "agno_learnings"
|
|
54
66
|
|
|
67
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
68
|
+
"""
|
|
69
|
+
Serialize common DB fields (table names + id). Subclasses may extend this.
|
|
70
|
+
"""
|
|
71
|
+
return {
|
|
72
|
+
"id": self.id,
|
|
73
|
+
"session_table": self.session_table_name,
|
|
74
|
+
"culture_table": self.culture_table_name,
|
|
75
|
+
"memory_table": self.memory_table_name,
|
|
76
|
+
"metrics_table": self.metrics_table_name,
|
|
77
|
+
"eval_table": self.eval_table_name,
|
|
78
|
+
"knowledge_table": self.knowledge_table_name,
|
|
79
|
+
"traces_table": self.trace_table_name,
|
|
80
|
+
"spans_table": self.span_table_name,
|
|
81
|
+
"versions_table": self.versions_table_name,
|
|
82
|
+
"components_table": self.components_table_name,
|
|
83
|
+
"component_configs_table": self.component_configs_table_name,
|
|
84
|
+
"component_links_table": self.component_links_table_name,
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@classmethod
|
|
88
|
+
def from_dict(cls, data: Dict[str, Any]) -> "BaseDb":
|
|
89
|
+
"""
|
|
90
|
+
Reconstruct using only fields defined in BaseDb. Subclasses should override this.
|
|
91
|
+
"""
|
|
92
|
+
return cls(
|
|
93
|
+
session_table=data.get("session_table"),
|
|
94
|
+
culture_table=data.get("culture_table"),
|
|
95
|
+
memory_table=data.get("memory_table"),
|
|
96
|
+
metrics_table=data.get("metrics_table"),
|
|
97
|
+
eval_table=data.get("eval_table"),
|
|
98
|
+
knowledge_table=data.get("knowledge_table"),
|
|
99
|
+
traces_table=data.get("traces_table"),
|
|
100
|
+
spans_table=data.get("spans_table"),
|
|
101
|
+
versions_table=data.get("versions_table"),
|
|
102
|
+
components_table=data.get("components_table"),
|
|
103
|
+
component_configs_table=data.get("component_configs_table"),
|
|
104
|
+
component_links_table=data.get("component_links_table"),
|
|
105
|
+
id=data.get("id"),
|
|
106
|
+
)
|
|
107
|
+
|
|
55
108
|
@abstractmethod
|
|
56
109
|
def table_exists(self, table_name: str) -> bool:
|
|
57
110
|
raise NotImplementedError
|
|
@@ -499,6 +552,292 @@ class BaseDb(ABC):
|
|
|
499
552
|
def upsert_cultural_knowledge(self, cultural_knowledge: CulturalKnowledge) -> Optional[CulturalKnowledge]:
|
|
500
553
|
raise NotImplementedError
|
|
501
554
|
|
|
555
|
+
# --- Components (Optional) ---
|
|
556
|
+
# These methods are optional. Override in subclasses to enable component persistence.
|
|
557
|
+
def get_component(
|
|
558
|
+
self,
|
|
559
|
+
component_id: str,
|
|
560
|
+
component_type: Optional[ComponentType] = None,
|
|
561
|
+
) -> Optional[Dict[str, Any]]:
|
|
562
|
+
"""Get a component by ID.
|
|
563
|
+
|
|
564
|
+
Args:
|
|
565
|
+
component_id: The component ID.
|
|
566
|
+
component_type: Optional filter by type (agent|team|workflow).
|
|
567
|
+
|
|
568
|
+
Returns:
|
|
569
|
+
Component dictionary or None if not found.
|
|
570
|
+
"""
|
|
571
|
+
raise NotImplementedError
|
|
572
|
+
|
|
573
|
+
def upsert_component(
|
|
574
|
+
self,
|
|
575
|
+
component_id: str,
|
|
576
|
+
component_type: Optional[ComponentType] = None,
|
|
577
|
+
name: Optional[str] = None,
|
|
578
|
+
description: Optional[str] = None,
|
|
579
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
580
|
+
) -> Dict[str, Any]:
|
|
581
|
+
"""Create or update a component.
|
|
582
|
+
|
|
583
|
+
Args:
|
|
584
|
+
component_id: Unique identifier.
|
|
585
|
+
component_type: Type (agent|team|workflow). Required for create, optional for update.
|
|
586
|
+
name: Display name.
|
|
587
|
+
description: Optional description.
|
|
588
|
+
metadata: Optional metadata dict.
|
|
589
|
+
|
|
590
|
+
Returns:
|
|
591
|
+
Created/updated component dictionary.
|
|
592
|
+
|
|
593
|
+
Raises:
|
|
594
|
+
ValueError: If creating and component_type is not provided.
|
|
595
|
+
"""
|
|
596
|
+
raise NotImplementedError
|
|
597
|
+
|
|
598
|
+
def delete_component(
|
|
599
|
+
self,
|
|
600
|
+
component_id: str,
|
|
601
|
+
hard_delete: bool = False,
|
|
602
|
+
) -> bool:
|
|
603
|
+
"""Delete a component and all its configs/links.
|
|
604
|
+
|
|
605
|
+
Args:
|
|
606
|
+
component_id: The component ID.
|
|
607
|
+
hard_delete: If True, permanently delete. Otherwise soft-delete.
|
|
608
|
+
|
|
609
|
+
Returns:
|
|
610
|
+
True if deleted, False if not found or already deleted.
|
|
611
|
+
"""
|
|
612
|
+
raise NotImplementedError
|
|
613
|
+
|
|
614
|
+
def list_components(
|
|
615
|
+
self,
|
|
616
|
+
component_type: Optional[ComponentType] = None,
|
|
617
|
+
include_deleted: bool = False,
|
|
618
|
+
limit: int = 20,
|
|
619
|
+
offset: int = 0,
|
|
620
|
+
) -> Tuple[List[Dict[str, Any]], int]:
|
|
621
|
+
"""List components with pagination.
|
|
622
|
+
|
|
623
|
+
Args:
|
|
624
|
+
component_type: Filter by type (agent|team|workflow).
|
|
625
|
+
include_deleted: Include soft-deleted components.
|
|
626
|
+
limit: Maximum number of items to return.
|
|
627
|
+
offset: Number of items to skip.
|
|
628
|
+
|
|
629
|
+
Returns:
|
|
630
|
+
Tuple of (list of component dicts, total count).
|
|
631
|
+
"""
|
|
632
|
+
raise NotImplementedError
|
|
633
|
+
|
|
634
|
+
def create_component_with_config(
|
|
635
|
+
self,
|
|
636
|
+
component_id: str,
|
|
637
|
+
component_type: ComponentType,
|
|
638
|
+
name: Optional[str],
|
|
639
|
+
config: Dict[str, Any],
|
|
640
|
+
description: Optional[str] = None,
|
|
641
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
642
|
+
label: Optional[str] = None,
|
|
643
|
+
stage: str = "draft",
|
|
644
|
+
notes: Optional[str] = None,
|
|
645
|
+
links: Optional[List[Dict[str, Any]]] = None,
|
|
646
|
+
) -> Tuple[Dict[str, Any], Dict[str, Any]]:
|
|
647
|
+
"""Create a component with its initial config atomically.
|
|
648
|
+
|
|
649
|
+
Args:
|
|
650
|
+
component_id: Unique identifier.
|
|
651
|
+
component_type: Type (agent|team|workflow).
|
|
652
|
+
name: Display name.
|
|
653
|
+
config: The config data.
|
|
654
|
+
description: Optional description.
|
|
655
|
+
metadata: Optional metadata dict.
|
|
656
|
+
label: Optional config label.
|
|
657
|
+
stage: "draft" or "published".
|
|
658
|
+
notes: Optional notes.
|
|
659
|
+
links: Optional list of links. Each must have child_version set.
|
|
660
|
+
|
|
661
|
+
Returns:
|
|
662
|
+
Tuple of (component dict, config dict).
|
|
663
|
+
|
|
664
|
+
Raises:
|
|
665
|
+
ValueError: If component already exists, invalid stage, or link missing child_version.
|
|
666
|
+
"""
|
|
667
|
+
raise NotImplementedError
|
|
668
|
+
|
|
669
|
+
# --- Component Configs (Optional) ---
|
|
670
|
+
def get_config(
|
|
671
|
+
self,
|
|
672
|
+
component_id: str,
|
|
673
|
+
version: Optional[int] = None,
|
|
674
|
+
label: Optional[str] = None,
|
|
675
|
+
) -> Optional[Dict[str, Any]]:
|
|
676
|
+
"""Get a config by component ID and version or label.
|
|
677
|
+
|
|
678
|
+
Args:
|
|
679
|
+
component_id: The component ID.
|
|
680
|
+
version: Specific version number. If None, uses current.
|
|
681
|
+
label: Config label to lookup. Ignored if version is provided.
|
|
682
|
+
|
|
683
|
+
Returns:
|
|
684
|
+
Config dictionary or None if not found.
|
|
685
|
+
"""
|
|
686
|
+
raise NotImplementedError
|
|
687
|
+
|
|
688
|
+
def upsert_config(
|
|
689
|
+
self,
|
|
690
|
+
component_id: str,
|
|
691
|
+
config: Optional[Dict[str, Any]] = None,
|
|
692
|
+
version: Optional[int] = None,
|
|
693
|
+
label: Optional[str] = None,
|
|
694
|
+
stage: Optional[str] = None,
|
|
695
|
+
notes: Optional[str] = None,
|
|
696
|
+
links: Optional[List[Dict[str, Any]]] = None,
|
|
697
|
+
) -> Dict[str, Any]:
|
|
698
|
+
"""Create or update a config version for a component.
|
|
699
|
+
|
|
700
|
+
Rules:
|
|
701
|
+
- Draft configs can be edited freely
|
|
702
|
+
- Published configs are immutable
|
|
703
|
+
- Publishing a config automatically sets it as current_version
|
|
704
|
+
|
|
705
|
+
Args:
|
|
706
|
+
component_id: The component ID.
|
|
707
|
+
config: The config data. Required for create, optional for update.
|
|
708
|
+
version: If None, creates new version. If provided, updates that version.
|
|
709
|
+
label: Optional human-readable label.
|
|
710
|
+
stage: "draft" or "published". Defaults to "draft" for new configs.
|
|
711
|
+
notes: Optional notes.
|
|
712
|
+
links: Optional list of links. Each link must have child_version set.
|
|
713
|
+
|
|
714
|
+
Returns:
|
|
715
|
+
Created/updated config dictionary.
|
|
716
|
+
|
|
717
|
+
Raises:
|
|
718
|
+
ValueError: If component doesn't exist, version not found, label conflict,
|
|
719
|
+
or attempting to update a published config.
|
|
720
|
+
"""
|
|
721
|
+
raise NotImplementedError
|
|
722
|
+
|
|
723
|
+
def delete_config(
|
|
724
|
+
self,
|
|
725
|
+
component_id: str,
|
|
726
|
+
version: int,
|
|
727
|
+
) -> bool:
|
|
728
|
+
"""Delete a specific config version.
|
|
729
|
+
|
|
730
|
+
Only draft configs can be deleted. Published configs are immutable.
|
|
731
|
+
Cannot delete the current version.
|
|
732
|
+
|
|
733
|
+
Args:
|
|
734
|
+
component_id: The component ID.
|
|
735
|
+
version: The version to delete.
|
|
736
|
+
|
|
737
|
+
Returns:
|
|
738
|
+
True if deleted, False if not found.
|
|
739
|
+
|
|
740
|
+
Raises:
|
|
741
|
+
ValueError: If attempting to delete a published or current config.
|
|
742
|
+
"""
|
|
743
|
+
raise NotImplementedError
|
|
744
|
+
|
|
745
|
+
def list_configs(
|
|
746
|
+
self,
|
|
747
|
+
component_id: str,
|
|
748
|
+
include_config: bool = False,
|
|
749
|
+
) -> List[Dict[str, Any]]:
|
|
750
|
+
"""List all config versions for a component.
|
|
751
|
+
|
|
752
|
+
Args:
|
|
753
|
+
component_id: The component ID.
|
|
754
|
+
include_config: If True, include full config blob. Otherwise just metadata.
|
|
755
|
+
|
|
756
|
+
Returns:
|
|
757
|
+
List of config dictionaries, newest first.
|
|
758
|
+
Returns empty list if component not found or deleted.
|
|
759
|
+
"""
|
|
760
|
+
raise NotImplementedError
|
|
761
|
+
|
|
762
|
+
def set_current_version(
|
|
763
|
+
self,
|
|
764
|
+
component_id: str,
|
|
765
|
+
version: int,
|
|
766
|
+
) -> bool:
|
|
767
|
+
"""Set a specific published version as current.
|
|
768
|
+
|
|
769
|
+
Only published configs can be set as current. This is used for
|
|
770
|
+
rollback scenarios where you want to switch to a previous
|
|
771
|
+
published version.
|
|
772
|
+
|
|
773
|
+
Args:
|
|
774
|
+
component_id: The component ID.
|
|
775
|
+
version: The version to set as current (must be published).
|
|
776
|
+
|
|
777
|
+
Returns:
|
|
778
|
+
True if successful, False if component or version not found.
|
|
779
|
+
|
|
780
|
+
Raises:
|
|
781
|
+
ValueError: If attempting to set a draft config as current.
|
|
782
|
+
"""
|
|
783
|
+
raise NotImplementedError
|
|
784
|
+
|
|
785
|
+
# --- Component Links (Optional) ---
|
|
786
|
+
def get_links(
|
|
787
|
+
self,
|
|
788
|
+
component_id: str,
|
|
789
|
+
version: int,
|
|
790
|
+
link_kind: Optional[str] = None,
|
|
791
|
+
) -> List[Dict[str, Any]]:
|
|
792
|
+
"""Get links for a config version.
|
|
793
|
+
|
|
794
|
+
Args:
|
|
795
|
+
component_id: The component ID.
|
|
796
|
+
version: The config version.
|
|
797
|
+
link_kind: Optional filter by link kind (member|step).
|
|
798
|
+
|
|
799
|
+
Returns:
|
|
800
|
+
List of link dictionaries, ordered by position.
|
|
801
|
+
"""
|
|
802
|
+
raise NotImplementedError
|
|
803
|
+
|
|
804
|
+
def get_dependents(
|
|
805
|
+
self,
|
|
806
|
+
component_id: str,
|
|
807
|
+
version: Optional[int] = None,
|
|
808
|
+
) -> List[Dict[str, Any]]:
|
|
809
|
+
"""Find all components that reference this component.
|
|
810
|
+
|
|
811
|
+
Args:
|
|
812
|
+
component_id: The component ID to find dependents of.
|
|
813
|
+
version: Optional specific version. If None, finds links to any version.
|
|
814
|
+
|
|
815
|
+
Returns:
|
|
816
|
+
List of link dictionaries showing what depends on this component.
|
|
817
|
+
"""
|
|
818
|
+
raise NotImplementedError
|
|
819
|
+
|
|
820
|
+
def load_component_graph(
|
|
821
|
+
self,
|
|
822
|
+
component_id: str,
|
|
823
|
+
version: Optional[int] = None,
|
|
824
|
+
label: Optional[str] = None,
|
|
825
|
+
) -> Optional[Dict[str, Any]]:
|
|
826
|
+
"""Load a component with its full resolved graph.
|
|
827
|
+
|
|
828
|
+
Handles cycles by returning a stub with cycle_detected=True.
|
|
829
|
+
|
|
830
|
+
Args:
|
|
831
|
+
component_id: The component ID.
|
|
832
|
+
version: Specific version or None for current.
|
|
833
|
+
label: Optional label of the component.
|
|
834
|
+
|
|
835
|
+
Returns:
|
|
836
|
+
Dictionary with component, config, children, and resolved_versions.
|
|
837
|
+
Returns None if component not found.
|
|
838
|
+
"""
|
|
839
|
+
raise NotImplementedError
|
|
840
|
+
|
|
502
841
|
# --- Learnings ---
|
|
503
842
|
@abstractmethod
|
|
504
843
|
def get_learning(
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import time
|
|
2
|
-
import warnings
|
|
3
2
|
from datetime import date, datetime, timedelta, timezone
|
|
4
3
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Sequence, Tuple, Union, cast
|
|
5
4
|
from uuid import uuid4
|
|
@@ -7,7 +6,7 @@ from uuid import uuid4
|
|
|
7
6
|
if TYPE_CHECKING:
|
|
8
7
|
from agno.tracing.schemas import Span, Trace
|
|
9
8
|
|
|
10
|
-
from agno.db.base import AsyncBaseDb, SessionType
|
|
9
|
+
from agno.db.base import AsyncBaseDb, ComponentType, SessionType
|
|
11
10
|
from agno.db.migrations.manager import MigrationManager
|
|
12
11
|
from agno.db.postgres.schemas import get_table_schema_definition
|
|
13
12
|
from agno.db.postgres.utils import (
|
|
@@ -60,7 +59,6 @@ class AsyncPostgresDb(AsyncBaseDb):
|
|
|
60
59
|
versions_table: Optional[str] = None,
|
|
61
60
|
learnings_table: Optional[str] = None,
|
|
62
61
|
create_schema: bool = True,
|
|
63
|
-
db_id: Optional[str] = None, # Deprecated, use id instead.
|
|
64
62
|
):
|
|
65
63
|
"""
|
|
66
64
|
Async interface for interacting with a PostgreSQL database.
|
|
@@ -96,21 +94,14 @@ class AsyncPostgresDb(AsyncBaseDb):
|
|
|
96
94
|
learnings_table (Optional[str]): Name of the table to store learnings.
|
|
97
95
|
create_schema (bool): Whether to automatically create the database schema if it doesn't exist.
|
|
98
96
|
Set to False if schema is managed externally (e.g., via migrations). Defaults to True.
|
|
99
|
-
db_id: Deprecated, use id instead.
|
|
100
97
|
|
|
101
98
|
Raises:
|
|
102
99
|
ValueError: If neither db_url nor db_engine is provided.
|
|
103
100
|
ValueError: If none of the tables are provided.
|
|
104
101
|
"""
|
|
105
|
-
if db_id is not None:
|
|
106
|
-
warnings.warn(
|
|
107
|
-
"The 'db_id' parameter is deprecated and will be removed in future versions. Use 'id' instead.",
|
|
108
|
-
DeprecationWarning,
|
|
109
|
-
stacklevel=2,
|
|
110
|
-
)
|
|
111
102
|
|
|
112
103
|
super().__init__(
|
|
113
|
-
id=id
|
|
104
|
+
id=id,
|
|
114
105
|
session_table=session_table,
|
|
115
106
|
memory_table=memory_table,
|
|
116
107
|
metrics_table=metrics_table,
|
|
@@ -2876,7 +2867,7 @@ class AsyncPostgresDb(AsyncBaseDb):
|
|
|
2876
2867
|
async with self.async_session_factory() as sess, sess.begin():
|
|
2877
2868
|
stmt = table.delete().where(table.c.learning_id == id)
|
|
2878
2869
|
result = await sess.execute(stmt)
|
|
2879
|
-
return result
|
|
2870
|
+
return getattr(result, "rowcount", 0) > 0
|
|
2880
2871
|
|
|
2881
2872
|
except Exception as e:
|
|
2882
2873
|
log_debug(f"Error deleting learning: {e}")
|
|
@@ -2947,3 +2938,116 @@ class AsyncPostgresDb(AsyncBaseDb):
|
|
|
2947
2938
|
except Exception as e:
|
|
2948
2939
|
log_debug(f"Error getting learnings: {e}")
|
|
2949
2940
|
return []
|
|
2941
|
+
|
|
2942
|
+
# --- Components (Not yet supported for async) ---
|
|
2943
|
+
def get_component(
|
|
2944
|
+
self,
|
|
2945
|
+
component_id: str,
|
|
2946
|
+
component_type: Optional[ComponentType] = None,
|
|
2947
|
+
) -> Optional[Dict[str, Any]]:
|
|
2948
|
+
raise NotImplementedError("Component methods not yet supported for async databases")
|
|
2949
|
+
|
|
2950
|
+
def upsert_component(
|
|
2951
|
+
self,
|
|
2952
|
+
component_id: str,
|
|
2953
|
+
component_type: Optional[ComponentType] = None,
|
|
2954
|
+
name: Optional[str] = None,
|
|
2955
|
+
description: Optional[str] = None,
|
|
2956
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
2957
|
+
) -> Dict[str, Any]:
|
|
2958
|
+
raise NotImplementedError("Component methods not yet supported for async databases")
|
|
2959
|
+
|
|
2960
|
+
def delete_component(
|
|
2961
|
+
self,
|
|
2962
|
+
component_id: str,
|
|
2963
|
+
hard_delete: bool = False,
|
|
2964
|
+
) -> bool:
|
|
2965
|
+
raise NotImplementedError("Component methods not yet supported for async databases")
|
|
2966
|
+
|
|
2967
|
+
def list_components(
|
|
2968
|
+
self,
|
|
2969
|
+
component_type: Optional[ComponentType] = None,
|
|
2970
|
+
include_deleted: bool = False,
|
|
2971
|
+
limit: int = 20,
|
|
2972
|
+
offset: int = 0,
|
|
2973
|
+
) -> Tuple[List[Dict[str, Any]], int]:
|
|
2974
|
+
raise NotImplementedError("Component methods not yet supported for async databases")
|
|
2975
|
+
|
|
2976
|
+
def create_component_with_config(
|
|
2977
|
+
self,
|
|
2978
|
+
component_id: str,
|
|
2979
|
+
component_type: ComponentType,
|
|
2980
|
+
name: Optional[str],
|
|
2981
|
+
config: Dict[str, Any],
|
|
2982
|
+
description: Optional[str] = None,
|
|
2983
|
+
metadata: Optional[Dict[str, Any]] = None,
|
|
2984
|
+
label: Optional[str] = None,
|
|
2985
|
+
stage: str = "draft",
|
|
2986
|
+
notes: Optional[str] = None,
|
|
2987
|
+
links: Optional[List[Dict[str, Any]]] = None,
|
|
2988
|
+
) -> Tuple[Dict[str, Any], Dict[str, Any]]:
|
|
2989
|
+
raise NotImplementedError("Component methods not yet supported for async databases")
|
|
2990
|
+
|
|
2991
|
+
def get_config(
|
|
2992
|
+
self,
|
|
2993
|
+
component_id: str,
|
|
2994
|
+
version: Optional[int] = None,
|
|
2995
|
+
label: Optional[str] = None,
|
|
2996
|
+
) -> Optional[Dict[str, Any]]:
|
|
2997
|
+
raise NotImplementedError("Component methods not yet supported for async databases")
|
|
2998
|
+
|
|
2999
|
+
def upsert_config(
|
|
3000
|
+
self,
|
|
3001
|
+
component_id: str,
|
|
3002
|
+
config: Optional[Dict[str, Any]] = None,
|
|
3003
|
+
version: Optional[int] = None,
|
|
3004
|
+
label: Optional[str] = None,
|
|
3005
|
+
stage: Optional[str] = None,
|
|
3006
|
+
notes: Optional[str] = None,
|
|
3007
|
+
links: Optional[List[Dict[str, Any]]] = None,
|
|
3008
|
+
) -> Dict[str, Any]:
|
|
3009
|
+
raise NotImplementedError("Component methods not yet supported for async databases")
|
|
3010
|
+
|
|
3011
|
+
def delete_config(
|
|
3012
|
+
self,
|
|
3013
|
+
component_id: str,
|
|
3014
|
+
version: int,
|
|
3015
|
+
) -> bool:
|
|
3016
|
+
raise NotImplementedError("Component methods not yet supported for async databases")
|
|
3017
|
+
|
|
3018
|
+
def list_configs(
|
|
3019
|
+
self,
|
|
3020
|
+
component_id: str,
|
|
3021
|
+
include_config: bool = False,
|
|
3022
|
+
) -> List[Dict[str, Any]]:
|
|
3023
|
+
raise NotImplementedError("Component methods not yet supported for async databases")
|
|
3024
|
+
|
|
3025
|
+
def set_current_version(
|
|
3026
|
+
self,
|
|
3027
|
+
component_id: str,
|
|
3028
|
+
version: int,
|
|
3029
|
+
) -> bool:
|
|
3030
|
+
raise NotImplementedError("Component methods not yet supported for async databases")
|
|
3031
|
+
|
|
3032
|
+
def get_links(
|
|
3033
|
+
self,
|
|
3034
|
+
component_id: str,
|
|
3035
|
+
version: int,
|
|
3036
|
+
link_kind: Optional[str] = None,
|
|
3037
|
+
) -> List[Dict[str, Any]]:
|
|
3038
|
+
raise NotImplementedError("Component methods not yet supported for async databases")
|
|
3039
|
+
|
|
3040
|
+
def get_dependents(
|
|
3041
|
+
self,
|
|
3042
|
+
component_id: str,
|
|
3043
|
+
version: Optional[int] = None,
|
|
3044
|
+
) -> List[Dict[str, Any]]:
|
|
3045
|
+
raise NotImplementedError("Component methods not yet supported for async databases")
|
|
3046
|
+
|
|
3047
|
+
def load_component_graph(
|
|
3048
|
+
self,
|
|
3049
|
+
component_id: str,
|
|
3050
|
+
version: Optional[int] = None,
|
|
3051
|
+
label: Optional[str] = None,
|
|
3052
|
+
) -> Optional[Dict[str, Any]]:
|
|
3053
|
+
raise NotImplementedError("Component methods not yet supported for async databases")
|