quraite 0.0.2__tar.gz → 0.1.0__tar.gz
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.
- {quraite-0.0.2 → quraite-0.1.0}/PKG-INFO +9 -9
- {quraite-0.0.2 → quraite-0.1.0}/README.md +8 -8
- {quraite-0.0.2 → quraite-0.1.0}/pyproject.toml +1 -1
- {quraite-0.0.2 → quraite-0.1.0}/quraite/__init__.py +3 -3
- {quraite-0.0.2 → quraite-0.1.0}/quraite/adapters/__init__.py +134 -134
- {quraite-0.0.2 → quraite-0.1.0}/quraite/adapters/agno_adapter.py +159 -159
- {quraite-0.0.2 → quraite-0.1.0}/quraite/adapters/base.py +123 -123
- {quraite-0.0.2 → quraite-0.1.0}/quraite/adapters/bedrock_agents_adapter.py +343 -343
- {quraite-0.0.2 → quraite-0.1.0}/quraite/adapters/flowise_adapter.py +275 -275
- {quraite-0.0.2 → quraite-0.1.0}/quraite/adapters/google_adk_adapter.py +209 -209
- {quraite-0.0.2 → quraite-0.1.0}/quraite/adapters/http_adapter.py +239 -239
- {quraite-0.0.2 → quraite-0.1.0}/quraite/adapters/langflow_adapter.py +192 -192
- {quraite-0.0.2 → quraite-0.1.0}/quraite/adapters/langgraph_adapter.py +304 -304
- {quraite-0.0.2 → quraite-0.1.0}/quraite/adapters/langgraph_server_adapter.py +252 -252
- {quraite-0.0.2 → quraite-0.1.0}/quraite/adapters/n8n_adapter.py +220 -220
- {quraite-0.0.2 → quraite-0.1.0}/quraite/adapters/openai_agents_adapter.py +269 -269
- {quraite-0.0.2 → quraite-0.1.0}/quraite/adapters/pydantic_ai_adapter.py +312 -312
- {quraite-0.0.2 → quraite-0.1.0}/quraite/adapters/smolagents_adapter.py +152 -152
- {quraite-0.0.2 → quraite-0.1.0}/quraite/logger.py +61 -64
- {quraite-0.0.2 → quraite-0.1.0}/quraite/schema/message.py +91 -54
- {quraite-0.0.2 → quraite-0.1.0}/quraite/schema/response.py +16 -16
- {quraite-0.0.2 → quraite-0.1.0}/quraite/serve/__init__.py +1 -1
- {quraite-0.0.2 → quraite-0.1.0}/quraite/serve/cloudflared.py +210 -210
- {quraite-0.0.2 → quraite-0.1.0}/quraite/serve/local_agent.py +360 -360
- {quraite-0.0.2 → quraite-0.1.0}/quraite/tracing/__init__.py +24 -24
- {quraite-0.0.2 → quraite-0.1.0}/quraite/tracing/constants.py +16 -16
- {quraite-0.0.2 → quraite-0.1.0}/quraite/tracing/span_exporter.py +115 -115
- {quraite-0.0.2 → quraite-0.1.0}/quraite/tracing/span_processor.py +49 -49
- {quraite-0.0.2 → quraite-0.1.0}/quraite/tracing/tool_extractors.py +290 -290
- {quraite-0.0.2 → quraite-0.1.0}/quraite/tracing/trace.py +564 -494
- {quraite-0.0.2 → quraite-0.1.0}/quraite/tracing/types.py +179 -179
- {quraite-0.0.2 → quraite-0.1.0}/quraite/tracing/utils.py +170 -170
- {quraite-0.0.2 → quraite-0.1.0}/quraite/utils/json_utils.py +269 -269
- quraite-0.0.2/quraite/traces/traces_adk_openinference.json +0 -379
- quraite-0.0.2/quraite/traces/traces_agno_multi_agent.json +0 -669
- quraite-0.0.2/quraite/traces/traces_agno_openinference.json +0 -321
- quraite-0.0.2/quraite/traces/traces_crewai_openinference.json +0 -155
- quraite-0.0.2/quraite/traces/traces_langgraph_openinference.json +0 -349
- quraite-0.0.2/quraite/traces/traces_langgraph_openinference_multi_agent.json +0 -2705
- quraite-0.0.2/quraite/traces/traces_langgraph_traceloop.json +0 -510
- quraite-0.0.2/quraite/traces/traces_openai_agents_multi_agent_1.json +0 -402
- quraite-0.0.2/quraite/traces/traces_openai_agents_openinference.json +0 -341
- quraite-0.0.2/quraite/traces/traces_pydantic_openinference.json +0 -286
- quraite-0.0.2/quraite/traces/traces_pydantic_openinference_multi_agent_1.json +0 -399
- quraite-0.0.2/quraite/traces/traces_pydantic_openinference_multi_agent_2.json +0 -398
- quraite-0.0.2/quraite/traces/traces_smol_agents_openinference.json +0 -397
- quraite-0.0.2/quraite/traces/traces_smol_agents_tool_calling_openinference.json +0 -704
- {quraite-0.0.2 → quraite-0.1.0}/quraite/schema/__init__.py +0 -0
- {quraite-0.0.2 → quraite-0.1.0}/quraite/utils/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: quraite
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 0.1.0
|
|
4
4
|
Summary: This project provides adaptors and methods to integrate with the Quraite platform
|
|
5
5
|
Author: Shiv Mohith
|
|
6
6
|
Author-email: Shiv Mohith <shivmohith8@gmail.com>
|
|
@@ -33,12 +33,12 @@ Provides-Extra: pyngrok
|
|
|
33
33
|
Provides-Extra: smolagents
|
|
34
34
|
Description-Content-Type: text/markdown
|
|
35
35
|
|
|
36
|
-
## Quraite Python SDK
|
|
37
|
-
|
|
38
|
-
### Publishing to Test PyPI
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
make update-version v=0.4.0
|
|
42
|
-
make build
|
|
43
|
-
make publish-test-pypi # enter user name as "__token__" and then enter the key
|
|
36
|
+
## Quraite Python SDK
|
|
37
|
+
|
|
38
|
+
### Publishing to Test PyPI
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
make update-version v=0.4.0
|
|
42
|
+
make build
|
|
43
|
+
make publish-test-pypi # enter user name as "__token__" and then enter the key
|
|
44
44
|
```
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
## Quraite Python SDK
|
|
2
|
-
|
|
3
|
-
### Publishing to Test PyPI
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
make update-version v=0.4.0
|
|
7
|
-
make build
|
|
8
|
-
make publish-test-pypi # enter user name as "__token__" and then enter the key
|
|
1
|
+
## Quraite Python SDK
|
|
2
|
+
|
|
3
|
+
### Publishing to Test PyPI
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
make update-version v=0.4.0
|
|
7
|
+
make build
|
|
8
|
+
make publish-test-pypi # enter user name as "__token__" and then enter the key
|
|
9
9
|
```
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"""Quraite Python SDK"""
|
|
2
|
-
|
|
3
|
-
__version__ = "0.6.0"
|
|
1
|
+
"""Quraite Python SDK"""
|
|
2
|
+
|
|
3
|
+
__version__ = "0.6.0"
|
|
@@ -1,134 +1,134 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING
|
|
2
|
-
|
|
3
|
-
from quraite.adapters.base import BaseAdapter, DummyAdapter
|
|
4
|
-
from quraite.adapters.http_adapter import HttpAdapter
|
|
5
|
-
|
|
6
|
-
if TYPE_CHECKING:
|
|
7
|
-
from quraite.adapters.agno_adapter import AgnoAdapter
|
|
8
|
-
from quraite.adapters.bedrock_agents_adapter import BedrockAgentsAdapter
|
|
9
|
-
from quraite.adapters.flowise_adapter import FlowiseAdapter
|
|
10
|
-
from quraite.adapters.google_adk_adapter import GoogleADKAdapter
|
|
11
|
-
from quraite.adapters.langflow_adapter import LangflowAdapter
|
|
12
|
-
from quraite.adapters.langgraph_adapter import LanggraphAdapter
|
|
13
|
-
from quraite.adapters.langgraph_server_adapter import LanggraphServerAdapter
|
|
14
|
-
from quraite.adapters.n8n_adapter import N8nAdapter
|
|
15
|
-
from quraite.adapters.openai_agents_adapter import OpenaiAgentsAdapter
|
|
16
|
-
from quraite.adapters.pydantic_ai_adapter import PydanticAIAdapter
|
|
17
|
-
from quraite.adapters.smolagents_adapter import SmolagentsAdapter
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
__all__ = [
|
|
21
|
-
"AgnoAdapter",
|
|
22
|
-
"BaseAdapter",
|
|
23
|
-
"BedrockAgentsAdapter",
|
|
24
|
-
"DummyAdapter",
|
|
25
|
-
"FlowiseAdapter",
|
|
26
|
-
"GoogleADKAdapter",
|
|
27
|
-
"LangflowAdapter",
|
|
28
|
-
"LanggraphAdapter",
|
|
29
|
-
"LanggraphServerAdapter",
|
|
30
|
-
"N8nAdapter",
|
|
31
|
-
"OpenaiAgentsAdapter",
|
|
32
|
-
"PydanticAIAdapter",
|
|
33
|
-
"HttpAdapter",
|
|
34
|
-
"SmolagentsAdapter",
|
|
35
|
-
]
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def __getattr__(name: str):
|
|
39
|
-
if name == "AgnoAdapter":
|
|
40
|
-
try:
|
|
41
|
-
from quraite.adapters.agno_adapter import AgnoAdapter
|
|
42
|
-
|
|
43
|
-
return AgnoAdapter
|
|
44
|
-
except ImportError as e:
|
|
45
|
-
raise ImportError(
|
|
46
|
-
f"Failed to import {name}. Please install the 'agno' optional dependency: pip install 'quraite[agno]'"
|
|
47
|
-
) from e
|
|
48
|
-
|
|
49
|
-
elif name == "BedrockAgentsAdapter":
|
|
50
|
-
try:
|
|
51
|
-
from quraite.adapters.bedrock_agents_adapter import BedrockAgentsAdapter
|
|
52
|
-
|
|
53
|
-
return BedrockAgentsAdapter
|
|
54
|
-
except ImportError as e:
|
|
55
|
-
raise ImportError(
|
|
56
|
-
f"Failed to import {name}. Please install the 'bedrock-agents' optional dependency: pip install 'quraite[bedrock-agents]'"
|
|
57
|
-
) from e
|
|
58
|
-
|
|
59
|
-
elif name == "FlowiseAdapter":
|
|
60
|
-
from quraite.adapters.flowise_adapter import FlowiseAdapter
|
|
61
|
-
|
|
62
|
-
return FlowiseAdapter
|
|
63
|
-
|
|
64
|
-
elif name == "GoogleADKAdapter":
|
|
65
|
-
try:
|
|
66
|
-
from quraite.adapters.google_adk_adapter import GoogleADKAdapter
|
|
67
|
-
|
|
68
|
-
return GoogleADKAdapter
|
|
69
|
-
except ImportError as e:
|
|
70
|
-
raise ImportError(
|
|
71
|
-
f"Failed to import {name}. Please install the 'google-adk' optional dependency: pip install 'quraite[google-adk]'"
|
|
72
|
-
) from e
|
|
73
|
-
|
|
74
|
-
elif name == "LangflowAdapter":
|
|
75
|
-
from quraite.adapters.langflow_adapter import LangflowAdapter
|
|
76
|
-
|
|
77
|
-
return LangflowAdapter
|
|
78
|
-
|
|
79
|
-
elif name == "LanggraphAdapter":
|
|
80
|
-
try:
|
|
81
|
-
from quraite.adapters.langgraph_adapter import LanggraphAdapter
|
|
82
|
-
|
|
83
|
-
return LanggraphAdapter
|
|
84
|
-
except ImportError as e:
|
|
85
|
-
raise ImportError(
|
|
86
|
-
f"Failed to import {name}. Please install the 'langgraph' optional dependency: pip install 'quraite[langgraph]'"
|
|
87
|
-
) from e
|
|
88
|
-
|
|
89
|
-
elif name == "LanggraphServerAdapter":
|
|
90
|
-
try:
|
|
91
|
-
from quraite.adapters.langgraph_server_adapter import LanggraphServerAdapter
|
|
92
|
-
|
|
93
|
-
return LanggraphServerAdapter
|
|
94
|
-
except ImportError as e:
|
|
95
|
-
raise ImportError(
|
|
96
|
-
f"Failed to import {name}. Please install the 'langgraph' optional dependency: pip install 'quraite[langgraph]'"
|
|
97
|
-
) from e
|
|
98
|
-
|
|
99
|
-
elif name == "N8nAdapter":
|
|
100
|
-
from quraite.adapters.n8n_adapter import N8nAdapter
|
|
101
|
-
|
|
102
|
-
return N8nAdapter
|
|
103
|
-
|
|
104
|
-
elif name == "OpenaiAgentsAdapter":
|
|
105
|
-
try:
|
|
106
|
-
from quraite.adapters.openai_agents_adapter import OpenaiAgentsAdapter
|
|
107
|
-
|
|
108
|
-
return OpenaiAgentsAdapter
|
|
109
|
-
except ImportError as e:
|
|
110
|
-
raise ImportError(
|
|
111
|
-
f"Failed to import {name}. Please install the 'openai-agents' optional dependency: pip install 'quraite[openai-agents]'"
|
|
112
|
-
) from e
|
|
113
|
-
|
|
114
|
-
elif name == "PydanticAIAdapter":
|
|
115
|
-
try:
|
|
116
|
-
from quraite.adapters.pydantic_ai_adapter import PydanticAIAdapter
|
|
117
|
-
|
|
118
|
-
return PydanticAIAdapter
|
|
119
|
-
except ImportError as e:
|
|
120
|
-
raise ImportError(
|
|
121
|
-
f"Failed to import {name}. Please install the 'pydantic-ai' optional dependency: pip install 'quraite[pydantic-ai]'"
|
|
122
|
-
) from e
|
|
123
|
-
|
|
124
|
-
elif name == "SmolagentsAdapter":
|
|
125
|
-
try:
|
|
126
|
-
from quraite.adapters.smolagents_adapter import SmolagentsAdapter
|
|
127
|
-
|
|
128
|
-
return SmolagentsAdapter
|
|
129
|
-
except ImportError as e:
|
|
130
|
-
raise ImportError(
|
|
131
|
-
f"Failed to import {name}. Please install the 'smolagents' optional dependency: pip install 'quraite[smolagents]'"
|
|
132
|
-
) from e
|
|
133
|
-
|
|
134
|
-
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
from quraite.adapters.base import BaseAdapter, DummyAdapter
|
|
4
|
+
from quraite.adapters.http_adapter import HttpAdapter
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from quraite.adapters.agno_adapter import AgnoAdapter
|
|
8
|
+
from quraite.adapters.bedrock_agents_adapter import BedrockAgentsAdapter
|
|
9
|
+
from quraite.adapters.flowise_adapter import FlowiseAdapter
|
|
10
|
+
from quraite.adapters.google_adk_adapter import GoogleADKAdapter
|
|
11
|
+
from quraite.adapters.langflow_adapter import LangflowAdapter
|
|
12
|
+
from quraite.adapters.langgraph_adapter import LanggraphAdapter
|
|
13
|
+
from quraite.adapters.langgraph_server_adapter import LanggraphServerAdapter
|
|
14
|
+
from quraite.adapters.n8n_adapter import N8nAdapter
|
|
15
|
+
from quraite.adapters.openai_agents_adapter import OpenaiAgentsAdapter
|
|
16
|
+
from quraite.adapters.pydantic_ai_adapter import PydanticAIAdapter
|
|
17
|
+
from quraite.adapters.smolagents_adapter import SmolagentsAdapter
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"AgnoAdapter",
|
|
22
|
+
"BaseAdapter",
|
|
23
|
+
"BedrockAgentsAdapter",
|
|
24
|
+
"DummyAdapter",
|
|
25
|
+
"FlowiseAdapter",
|
|
26
|
+
"GoogleADKAdapter",
|
|
27
|
+
"LangflowAdapter",
|
|
28
|
+
"LanggraphAdapter",
|
|
29
|
+
"LanggraphServerAdapter",
|
|
30
|
+
"N8nAdapter",
|
|
31
|
+
"OpenaiAgentsAdapter",
|
|
32
|
+
"PydanticAIAdapter",
|
|
33
|
+
"HttpAdapter",
|
|
34
|
+
"SmolagentsAdapter",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def __getattr__(name: str):
|
|
39
|
+
if name == "AgnoAdapter":
|
|
40
|
+
try:
|
|
41
|
+
from quraite.adapters.agno_adapter import AgnoAdapter
|
|
42
|
+
|
|
43
|
+
return AgnoAdapter
|
|
44
|
+
except ImportError as e:
|
|
45
|
+
raise ImportError(
|
|
46
|
+
f"Failed to import {name}. Please install the 'agno' optional dependency: pip install 'quraite[agno]'"
|
|
47
|
+
) from e
|
|
48
|
+
|
|
49
|
+
elif name == "BedrockAgentsAdapter":
|
|
50
|
+
try:
|
|
51
|
+
from quraite.adapters.bedrock_agents_adapter import BedrockAgentsAdapter
|
|
52
|
+
|
|
53
|
+
return BedrockAgentsAdapter
|
|
54
|
+
except ImportError as e:
|
|
55
|
+
raise ImportError(
|
|
56
|
+
f"Failed to import {name}. Please install the 'bedrock-agents' optional dependency: pip install 'quraite[bedrock-agents]'"
|
|
57
|
+
) from e
|
|
58
|
+
|
|
59
|
+
elif name == "FlowiseAdapter":
|
|
60
|
+
from quraite.adapters.flowise_adapter import FlowiseAdapter
|
|
61
|
+
|
|
62
|
+
return FlowiseAdapter
|
|
63
|
+
|
|
64
|
+
elif name == "GoogleADKAdapter":
|
|
65
|
+
try:
|
|
66
|
+
from quraite.adapters.google_adk_adapter import GoogleADKAdapter
|
|
67
|
+
|
|
68
|
+
return GoogleADKAdapter
|
|
69
|
+
except ImportError as e:
|
|
70
|
+
raise ImportError(
|
|
71
|
+
f"Failed to import {name}. Please install the 'google-adk' optional dependency: pip install 'quraite[google-adk]'"
|
|
72
|
+
) from e
|
|
73
|
+
|
|
74
|
+
elif name == "LangflowAdapter":
|
|
75
|
+
from quraite.adapters.langflow_adapter import LangflowAdapter
|
|
76
|
+
|
|
77
|
+
return LangflowAdapter
|
|
78
|
+
|
|
79
|
+
elif name == "LanggraphAdapter":
|
|
80
|
+
try:
|
|
81
|
+
from quraite.adapters.langgraph_adapter import LanggraphAdapter
|
|
82
|
+
|
|
83
|
+
return LanggraphAdapter
|
|
84
|
+
except ImportError as e:
|
|
85
|
+
raise ImportError(
|
|
86
|
+
f"Failed to import {name}. Please install the 'langgraph' optional dependency: pip install 'quraite[langgraph]'"
|
|
87
|
+
) from e
|
|
88
|
+
|
|
89
|
+
elif name == "LanggraphServerAdapter":
|
|
90
|
+
try:
|
|
91
|
+
from quraite.adapters.langgraph_server_adapter import LanggraphServerAdapter
|
|
92
|
+
|
|
93
|
+
return LanggraphServerAdapter
|
|
94
|
+
except ImportError as e:
|
|
95
|
+
raise ImportError(
|
|
96
|
+
f"Failed to import {name}. Please install the 'langgraph' optional dependency: pip install 'quraite[langgraph]'"
|
|
97
|
+
) from e
|
|
98
|
+
|
|
99
|
+
elif name == "N8nAdapter":
|
|
100
|
+
from quraite.adapters.n8n_adapter import N8nAdapter
|
|
101
|
+
|
|
102
|
+
return N8nAdapter
|
|
103
|
+
|
|
104
|
+
elif name == "OpenaiAgentsAdapter":
|
|
105
|
+
try:
|
|
106
|
+
from quraite.adapters.openai_agents_adapter import OpenaiAgentsAdapter
|
|
107
|
+
|
|
108
|
+
return OpenaiAgentsAdapter
|
|
109
|
+
except ImportError as e:
|
|
110
|
+
raise ImportError(
|
|
111
|
+
f"Failed to import {name}. Please install the 'openai-agents' optional dependency: pip install 'quraite[openai-agents]'"
|
|
112
|
+
) from e
|
|
113
|
+
|
|
114
|
+
elif name == "PydanticAIAdapter":
|
|
115
|
+
try:
|
|
116
|
+
from quraite.adapters.pydantic_ai_adapter import PydanticAIAdapter
|
|
117
|
+
|
|
118
|
+
return PydanticAIAdapter
|
|
119
|
+
except ImportError as e:
|
|
120
|
+
raise ImportError(
|
|
121
|
+
f"Failed to import {name}. Please install the 'pydantic-ai' optional dependency: pip install 'quraite[pydantic-ai]'"
|
|
122
|
+
) from e
|
|
123
|
+
|
|
124
|
+
elif name == "SmolagentsAdapter":
|
|
125
|
+
try:
|
|
126
|
+
from quraite.adapters.smolagents_adapter import SmolagentsAdapter
|
|
127
|
+
|
|
128
|
+
return SmolagentsAdapter
|
|
129
|
+
except ImportError as e:
|
|
130
|
+
raise ImportError(
|
|
131
|
+
f"Failed to import {name}. Please install the 'smolagents' optional dependency: pip install 'quraite[smolagents]'"
|
|
132
|
+
) from e
|
|
133
|
+
|
|
134
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
@@ -1,159 +1,159 @@
|
|
|
1
|
-
import uuid
|
|
2
|
-
from typing import List, Union
|
|
3
|
-
|
|
4
|
-
from agno.agent import Agent
|
|
5
|
-
from agno.team import Team
|
|
6
|
-
from opentelemetry.trace import TracerProvider
|
|
7
|
-
|
|
8
|
-
from quraite.adapters.base import BaseAdapter
|
|
9
|
-
from quraite.logger import get_logger
|
|
10
|
-
from quraite.schema.message import AgentMessage
|
|
11
|
-
from quraite.schema.response import AgentInvocationResponse
|
|
12
|
-
from quraite.tracing.constants import QURAITE_ADAPTER_TRACE_PREFIX, Framework
|
|
13
|
-
from quraite.tracing.trace import AgentSpan, AgentTrace
|
|
14
|
-
|
|
15
|
-
logger = get_logger(__name__)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class AgnoAdapter(BaseAdapter):
|
|
19
|
-
"""
|
|
20
|
-
Agno adapter wrapper that converts any Agno agent or team
|
|
21
|
-
to a standardized callable interface (invoke) and converts the output to List[AgentMessage].
|
|
22
|
-
|
|
23
|
-
This class wraps any Agno Agent or Team and provides:
|
|
24
|
-
- Asynchronous invocation via ainvoke()
|
|
25
|
-
- Automatic conversion to List[AgentMessage] format
|
|
26
|
-
- Access to message history and traces
|
|
27
|
-
- Support for both single agents and multi-agent teams
|
|
28
|
-
"""
|
|
29
|
-
|
|
30
|
-
def __init__(
|
|
31
|
-
self,
|
|
32
|
-
agent: Union[Agent, Team],
|
|
33
|
-
agent_name: str = "Agno Agent",
|
|
34
|
-
tracer_provider: TracerProvider = None,
|
|
35
|
-
):
|
|
36
|
-
"""
|
|
37
|
-
Initialize with a pre-configured Agno agent or team
|
|
38
|
-
|
|
39
|
-
Args:
|
|
40
|
-
agent: An Agno Agent or Team instance
|
|
41
|
-
agent_name: Name of the agent for trajectory metadata
|
|
42
|
-
tracer_provider: TracerProvider for tracing (required)
|
|
43
|
-
"""
|
|
44
|
-
logger.debug("Initializing AgnoAdapter with agent_name=%s", agent_name)
|
|
45
|
-
self._init_tracing(tracer_provider, required=True)
|
|
46
|
-
|
|
47
|
-
self.agent: Union[Agent, Team] = agent
|
|
48
|
-
self.agent_name = agent_name
|
|
49
|
-
logger.info(
|
|
50
|
-
"AgnoAdapter initialized successfully (tracing_enabled=%s)",
|
|
51
|
-
bool(tracer_provider),
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
def _prepare_input(self, input: List[AgentMessage]) -> str:
|
|
55
|
-
"""
|
|
56
|
-
Prepare input for Agno agent from List[AgentMessage].
|
|
57
|
-
|
|
58
|
-
Args:
|
|
59
|
-
input: List[AgentMessage] containing user_message
|
|
60
|
-
|
|
61
|
-
Returns:
|
|
62
|
-
str: User message text
|
|
63
|
-
"""
|
|
64
|
-
logger.debug("Preparing input from %d messages", len(input))
|
|
65
|
-
if not input or input[-1].role != "user":
|
|
66
|
-
logger.error("Invalid input: no user message found")
|
|
67
|
-
raise ValueError("No user message found in the input")
|
|
68
|
-
|
|
69
|
-
last_user_message = input[-1]
|
|
70
|
-
if not last_user_message.content:
|
|
71
|
-
logger.error("User message has no content")
|
|
72
|
-
raise ValueError("User message has no content")
|
|
73
|
-
|
|
74
|
-
text_content = None
|
|
75
|
-
for content_item in last_user_message.content:
|
|
76
|
-
if content_item.type == "text" and content_item.text:
|
|
77
|
-
text_content = content_item.text
|
|
78
|
-
break
|
|
79
|
-
|
|
80
|
-
if not text_content:
|
|
81
|
-
logger.error("No text content found in user message")
|
|
82
|
-
raise ValueError("No text content found in user message")
|
|
83
|
-
|
|
84
|
-
logger.debug("Prepared input with text_content length=%d", len(text_content))
|
|
85
|
-
return text_content
|
|
86
|
-
|
|
87
|
-
async def ainvoke(
|
|
88
|
-
self,
|
|
89
|
-
input: List[AgentMessage],
|
|
90
|
-
session_id: Union[str, None] = None,
|
|
91
|
-
) -> AgentInvocationResponse:
|
|
92
|
-
"""
|
|
93
|
-
Asynchronous invocation method - invokes the Agno agent/team with tracing
|
|
94
|
-
|
|
95
|
-
Args:
|
|
96
|
-
input: List[AgentMessage] containing user_message
|
|
97
|
-
session_id: Optional conversation ID for maintaining context
|
|
98
|
-
|
|
99
|
-
Returns:
|
|
100
|
-
AgentInvocationResponse - response containing agent trace, trajectory, and final response.
|
|
101
|
-
"""
|
|
102
|
-
logger.info(
|
|
103
|
-
"ainvoke called (session_id=%s, input_messages=%d)", session_id, len(input)
|
|
104
|
-
)
|
|
105
|
-
agent_input = self._prepare_input(input)
|
|
106
|
-
session_id = session_id or "default"
|
|
107
|
-
|
|
108
|
-
try:
|
|
109
|
-
logger.debug("Invoking Agno agent with tracing (session_id=%s)", session_id)
|
|
110
|
-
return await self._ainvoke_with_tracing(agent_input, session_id)
|
|
111
|
-
|
|
112
|
-
except ValueError:
|
|
113
|
-
logger.exception("Invalid input during ainvoke")
|
|
114
|
-
raise
|
|
115
|
-
except Exception as e:
|
|
116
|
-
logger.exception("Unexpected error invoking Agno agent")
|
|
117
|
-
raise RuntimeError(f"Error invoking Agno agent: {e}") from e
|
|
118
|
-
|
|
119
|
-
async def _ainvoke_with_tracing(
|
|
120
|
-
self,
|
|
121
|
-
agent_input: str,
|
|
122
|
-
session_id: str,
|
|
123
|
-
) -> AgentInvocationResponse:
|
|
124
|
-
"""Execute ainvoke with tracing enabled."""
|
|
125
|
-
adapter_trace_id = f"{QURAITE_ADAPTER_TRACE_PREFIX}-{uuid.uuid4()}"
|
|
126
|
-
logger.debug(
|
|
127
|
-
"Starting traced invocation (trace_id=%s, session_id=%s)",
|
|
128
|
-
adapter_trace_id,
|
|
129
|
-
session_id,
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
with self.tracer.start_as_current_span(name=adapter_trace_id):
|
|
133
|
-
# Run the agent/team
|
|
134
|
-
await self.agent.arun(agent_input, session_id=session_id)
|
|
135
|
-
|
|
136
|
-
# Get trace spans
|
|
137
|
-
trace_readable_spans = self.quraite_span_exporter.get_trace_by_testcase(
|
|
138
|
-
adapter_trace_id
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
if trace_readable_spans:
|
|
142
|
-
logger.info(
|
|
143
|
-
"Retrieved %d spans for trace_id=%s",
|
|
144
|
-
len(trace_readable_spans),
|
|
145
|
-
adapter_trace_id,
|
|
146
|
-
)
|
|
147
|
-
agent_trace = AgentTrace(
|
|
148
|
-
spans=[
|
|
149
|
-
AgentSpan.from_readable_oi_span(span)
|
|
150
|
-
for span in trace_readable_spans
|
|
151
|
-
],
|
|
152
|
-
)
|
|
153
|
-
else:
|
|
154
|
-
logger.warning("No spans found for trace_id=%s", adapter_trace_id)
|
|
155
|
-
|
|
156
|
-
return AgentInvocationResponse(
|
|
157
|
-
agent_trace=agent_trace,
|
|
158
|
-
agent_trajectory=agent_trace.to_agent_trajectory(framework=Framework.AGNO),
|
|
159
|
-
)
|
|
1
|
+
import uuid
|
|
2
|
+
from typing import List, Union
|
|
3
|
+
|
|
4
|
+
from agno.agent import Agent
|
|
5
|
+
from agno.team import Team
|
|
6
|
+
from opentelemetry.trace import TracerProvider
|
|
7
|
+
|
|
8
|
+
from quraite.adapters.base import BaseAdapter
|
|
9
|
+
from quraite.logger import get_logger
|
|
10
|
+
from quraite.schema.message import AgentMessage
|
|
11
|
+
from quraite.schema.response import AgentInvocationResponse
|
|
12
|
+
from quraite.tracing.constants import QURAITE_ADAPTER_TRACE_PREFIX, Framework
|
|
13
|
+
from quraite.tracing.trace import AgentSpan, AgentTrace
|
|
14
|
+
|
|
15
|
+
logger = get_logger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AgnoAdapter(BaseAdapter):
|
|
19
|
+
"""
|
|
20
|
+
Agno adapter wrapper that converts any Agno agent or team
|
|
21
|
+
to a standardized callable interface (invoke) and converts the output to List[AgentMessage].
|
|
22
|
+
|
|
23
|
+
This class wraps any Agno Agent or Team and provides:
|
|
24
|
+
- Asynchronous invocation via ainvoke()
|
|
25
|
+
- Automatic conversion to List[AgentMessage] format
|
|
26
|
+
- Access to message history and traces
|
|
27
|
+
- Support for both single agents and multi-agent teams
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
agent: Union[Agent, Team],
|
|
33
|
+
agent_name: str = "Agno Agent",
|
|
34
|
+
tracer_provider: TracerProvider = None,
|
|
35
|
+
):
|
|
36
|
+
"""
|
|
37
|
+
Initialize with a pre-configured Agno agent or team
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
agent: An Agno Agent or Team instance
|
|
41
|
+
agent_name: Name of the agent for trajectory metadata
|
|
42
|
+
tracer_provider: TracerProvider for tracing (required)
|
|
43
|
+
"""
|
|
44
|
+
logger.debug("Initializing AgnoAdapter with agent_name=%s", agent_name)
|
|
45
|
+
self._init_tracing(tracer_provider, required=True)
|
|
46
|
+
|
|
47
|
+
self.agent: Union[Agent, Team] = agent
|
|
48
|
+
self.agent_name = agent_name
|
|
49
|
+
logger.info(
|
|
50
|
+
"AgnoAdapter initialized successfully (tracing_enabled=%s)",
|
|
51
|
+
bool(tracer_provider),
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
def _prepare_input(self, input: List[AgentMessage]) -> str:
|
|
55
|
+
"""
|
|
56
|
+
Prepare input for Agno agent from List[AgentMessage].
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
input: List[AgentMessage] containing user_message
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
str: User message text
|
|
63
|
+
"""
|
|
64
|
+
logger.debug("Preparing input from %d messages", len(input))
|
|
65
|
+
if not input or input[-1].role != "user":
|
|
66
|
+
logger.error("Invalid input: no user message found")
|
|
67
|
+
raise ValueError("No user message found in the input")
|
|
68
|
+
|
|
69
|
+
last_user_message = input[-1]
|
|
70
|
+
if not last_user_message.content:
|
|
71
|
+
logger.error("User message has no content")
|
|
72
|
+
raise ValueError("User message has no content")
|
|
73
|
+
|
|
74
|
+
text_content = None
|
|
75
|
+
for content_item in last_user_message.content:
|
|
76
|
+
if content_item.type == "text" and content_item.text:
|
|
77
|
+
text_content = content_item.text
|
|
78
|
+
break
|
|
79
|
+
|
|
80
|
+
if not text_content:
|
|
81
|
+
logger.error("No text content found in user message")
|
|
82
|
+
raise ValueError("No text content found in user message")
|
|
83
|
+
|
|
84
|
+
logger.debug("Prepared input with text_content length=%d", len(text_content))
|
|
85
|
+
return text_content
|
|
86
|
+
|
|
87
|
+
async def ainvoke(
|
|
88
|
+
self,
|
|
89
|
+
input: List[AgentMessage],
|
|
90
|
+
session_id: Union[str, None] = None,
|
|
91
|
+
) -> AgentInvocationResponse:
|
|
92
|
+
"""
|
|
93
|
+
Asynchronous invocation method - invokes the Agno agent/team with tracing
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
input: List[AgentMessage] containing user_message
|
|
97
|
+
session_id: Optional conversation ID for maintaining context
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
AgentInvocationResponse - response containing agent trace, trajectory, and final response.
|
|
101
|
+
"""
|
|
102
|
+
logger.info(
|
|
103
|
+
"ainvoke called (session_id=%s, input_messages=%d)", session_id, len(input)
|
|
104
|
+
)
|
|
105
|
+
agent_input = self._prepare_input(input)
|
|
106
|
+
session_id = session_id or "default"
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
logger.debug("Invoking Agno agent with tracing (session_id=%s)", session_id)
|
|
110
|
+
return await self._ainvoke_with_tracing(agent_input, session_id)
|
|
111
|
+
|
|
112
|
+
except ValueError:
|
|
113
|
+
logger.exception("Invalid input during ainvoke")
|
|
114
|
+
raise
|
|
115
|
+
except Exception as e:
|
|
116
|
+
logger.exception("Unexpected error invoking Agno agent")
|
|
117
|
+
raise RuntimeError(f"Error invoking Agno agent: {e}") from e
|
|
118
|
+
|
|
119
|
+
async def _ainvoke_with_tracing(
|
|
120
|
+
self,
|
|
121
|
+
agent_input: str,
|
|
122
|
+
session_id: str,
|
|
123
|
+
) -> AgentInvocationResponse:
|
|
124
|
+
"""Execute ainvoke with tracing enabled."""
|
|
125
|
+
adapter_trace_id = f"{QURAITE_ADAPTER_TRACE_PREFIX}-{uuid.uuid4()}"
|
|
126
|
+
logger.debug(
|
|
127
|
+
"Starting traced invocation (trace_id=%s, session_id=%s)",
|
|
128
|
+
adapter_trace_id,
|
|
129
|
+
session_id,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
with self.tracer.start_as_current_span(name=adapter_trace_id):
|
|
133
|
+
# Run the agent/team
|
|
134
|
+
await self.agent.arun(agent_input, session_id=session_id)
|
|
135
|
+
|
|
136
|
+
# Get trace spans
|
|
137
|
+
trace_readable_spans = self.quraite_span_exporter.get_trace_by_testcase(
|
|
138
|
+
adapter_trace_id
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
if trace_readable_spans:
|
|
142
|
+
logger.info(
|
|
143
|
+
"Retrieved %d spans for trace_id=%s",
|
|
144
|
+
len(trace_readable_spans),
|
|
145
|
+
adapter_trace_id,
|
|
146
|
+
)
|
|
147
|
+
agent_trace = AgentTrace(
|
|
148
|
+
spans=[
|
|
149
|
+
AgentSpan.from_readable_oi_span(span)
|
|
150
|
+
for span in trace_readable_spans
|
|
151
|
+
],
|
|
152
|
+
)
|
|
153
|
+
else:
|
|
154
|
+
logger.warning("No spans found for trace_id=%s", adapter_trace_id)
|
|
155
|
+
|
|
156
|
+
return AgentInvocationResponse(
|
|
157
|
+
agent_trace=agent_trace,
|
|
158
|
+
agent_trajectory=agent_trace.to_agent_trajectory(framework=Framework.AGNO),
|
|
159
|
+
)
|