quraite 0.0.1__py3-none-any.whl → 0.1.0__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.
- quraite/__init__.py +3 -3
- quraite/adapters/__init__.py +134 -134
- quraite/adapters/agno_adapter.py +159 -159
- quraite/adapters/base.py +123 -123
- quraite/adapters/bedrock_agents_adapter.py +343 -343
- quraite/adapters/flowise_adapter.py +275 -275
- quraite/adapters/google_adk_adapter.py +209 -209
- quraite/adapters/http_adapter.py +239 -239
- quraite/adapters/langflow_adapter.py +192 -192
- quraite/adapters/langgraph_adapter.py +304 -304
- quraite/adapters/langgraph_server_adapter.py +252 -252
- quraite/adapters/n8n_adapter.py +220 -220
- quraite/adapters/openai_agents_adapter.py +269 -269
- quraite/adapters/pydantic_ai_adapter.py +312 -312
- quraite/adapters/smolagents_adapter.py +152 -152
- quraite/logger.py +61 -62
- quraite/schema/message.py +91 -54
- quraite/schema/response.py +16 -16
- quraite/serve/__init__.py +1 -1
- quraite/serve/cloudflared.py +210 -210
- quraite/serve/local_agent.py +360 -360
- quraite/tracing/__init__.py +24 -24
- quraite/tracing/constants.py +16 -16
- quraite/tracing/span_exporter.py +115 -115
- quraite/tracing/span_processor.py +49 -49
- quraite/tracing/tool_extractors.py +290 -290
- quraite/tracing/trace.py +564 -494
- quraite/tracing/types.py +179 -179
- quraite/tracing/utils.py +170 -170
- quraite/utils/json_utils.py +269 -269
- {quraite-0.0.1.dist-info → quraite-0.1.0.dist-info}/METADATA +9 -9
- quraite-0.1.0.dist-info/RECORD +35 -0
- {quraite-0.0.1.dist-info → quraite-0.1.0.dist-info}/WHEEL +1 -1
- quraite/traces/traces_adk_openinference.json +0 -379
- quraite/traces/traces_agno_multi_agent.json +0 -669
- quraite/traces/traces_agno_openinference.json +0 -321
- quraite/traces/traces_crewai_openinference.json +0 -155
- quraite/traces/traces_langgraph_openinference.json +0 -349
- quraite/traces/traces_langgraph_openinference_multi_agent.json +0 -2705
- quraite/traces/traces_langgraph_traceloop.json +0 -510
- quraite/traces/traces_openai_agents_multi_agent_1.json +0 -402
- quraite/traces/traces_openai_agents_openinference.json +0 -341
- quraite/traces/traces_pydantic_openinference.json +0 -286
- quraite/traces/traces_pydantic_openinference_multi_agent_1.json +0 -399
- quraite/traces/traces_pydantic_openinference_multi_agent_2.json +0 -398
- quraite/traces/traces_smol_agents_openinference.json +0 -397
- quraite/traces/traces_smol_agents_tool_calling_openinference.json +0 -704
- quraite-0.0.1.dist-info/RECORD +0 -49
|
@@ -1,209 +1,209 @@
|
|
|
1
|
-
import uuid
|
|
2
|
-
from typing import List, Union
|
|
3
|
-
|
|
4
|
-
from google.adk.agents import Agent
|
|
5
|
-
from google.adk.apps.app import App
|
|
6
|
-
from google.adk.errors.already_exists_error import AlreadyExistsError
|
|
7
|
-
from google.adk.runners import Runner
|
|
8
|
-
from google.adk.sessions import BaseSessionService, InMemorySessionService
|
|
9
|
-
from google.genai import types
|
|
10
|
-
from opentelemetry.trace import TracerProvider
|
|
11
|
-
|
|
12
|
-
from quraite.adapters.base import BaseAdapter
|
|
13
|
-
from quraite.logger import get_logger
|
|
14
|
-
from quraite.schema.message import AgentMessage
|
|
15
|
-
from quraite.schema.response import AgentInvocationResponse
|
|
16
|
-
from quraite.tracing.constants import QURAITE_ADAPTER_TRACE_PREFIX, Framework
|
|
17
|
-
from quraite.tracing.trace import AgentSpan, AgentTrace
|
|
18
|
-
|
|
19
|
-
logger = get_logger(__name__)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class GoogleADKAdapter(BaseAdapter):
|
|
23
|
-
"""
|
|
24
|
-
Google ADK adapter wrapper that converts any Google ADK agent
|
|
25
|
-
to a standardized callable interface (ainvoke) with tracing support.
|
|
26
|
-
|
|
27
|
-
This class wraps any Google ADK Agent and provides:
|
|
28
|
-
- Asynchronous invocation via ainvoke()
|
|
29
|
-
- OpenTelemetry tracing integration
|
|
30
|
-
- Session management for multi-turn conversations
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
def __init__(
|
|
34
|
-
self,
|
|
35
|
-
agent: Agent,
|
|
36
|
-
agent_name: str = "Google ADK Agent",
|
|
37
|
-
tracer_provider: TracerProvider = None,
|
|
38
|
-
app_name: str = "google_adk_agent",
|
|
39
|
-
user_id: str = str(uuid.uuid4()),
|
|
40
|
-
session_service: BaseSessionService = InMemorySessionService(),
|
|
41
|
-
):
|
|
42
|
-
"""
|
|
43
|
-
Initialize with a pre-configured Google ADK agent
|
|
44
|
-
|
|
45
|
-
Args:
|
|
46
|
-
agent: A Google ADK Agent instance
|
|
47
|
-
app_name: Application name for ADK runner
|
|
48
|
-
agent_name: Name of the agent for trajectory metadata
|
|
49
|
-
tracer_provider: TracerProvider for tracing (required)
|
|
50
|
-
"""
|
|
51
|
-
logger.debug(
|
|
52
|
-
"Initializing GoogleADKAdapter (agent_name=%s, app_name=%s)",
|
|
53
|
-
agent_name,
|
|
54
|
-
app_name,
|
|
55
|
-
)
|
|
56
|
-
self._init_tracing(tracer_provider, required=True)
|
|
57
|
-
|
|
58
|
-
self.agent: Agent = agent
|
|
59
|
-
self.app_name = app_name
|
|
60
|
-
self.agent_name = agent_name
|
|
61
|
-
self.session_service = session_service
|
|
62
|
-
self.user_id = user_id
|
|
63
|
-
self.app = App(
|
|
64
|
-
name=app_name,
|
|
65
|
-
root_agent=agent,
|
|
66
|
-
)
|
|
67
|
-
self.runner = Runner(
|
|
68
|
-
app=self.app,
|
|
69
|
-
session_service=session_service,
|
|
70
|
-
)
|
|
71
|
-
logger.info("GoogleADKAdapter initialized successfully")
|
|
72
|
-
|
|
73
|
-
def _prepare_input(self, input: List[AgentMessage]) -> str:
|
|
74
|
-
"""
|
|
75
|
-
Prepare input for Google ADK agent from List[Message].
|
|
76
|
-
|
|
77
|
-
Args:
|
|
78
|
-
input: List[Message] containing user_message
|
|
79
|
-
|
|
80
|
-
Returns:
|
|
81
|
-
str: User message text
|
|
82
|
-
"""
|
|
83
|
-
logger.debug("Preparing Google ADK input from %d messages", len(input))
|
|
84
|
-
if not input or input[-1].role != "user":
|
|
85
|
-
logger.error("Google ADK input missing user message")
|
|
86
|
-
raise ValueError("No user message found in the input")
|
|
87
|
-
|
|
88
|
-
last_user_message = input[-1]
|
|
89
|
-
# Check if content list is not empty and has text
|
|
90
|
-
if not last_user_message.content:
|
|
91
|
-
logger.error("Google ADK user message missing content")
|
|
92
|
-
raise ValueError("User message has no content")
|
|
93
|
-
|
|
94
|
-
# Find the first text content item
|
|
95
|
-
text_content = None
|
|
96
|
-
for content_item in last_user_message.content:
|
|
97
|
-
if content_item.type == "text" and content_item.text:
|
|
98
|
-
text_content = content_item.text
|
|
99
|
-
break
|
|
100
|
-
|
|
101
|
-
if not text_content:
|
|
102
|
-
logger.error("Google ADK user message missing text content")
|
|
103
|
-
raise ValueError("No text content found in user message")
|
|
104
|
-
|
|
105
|
-
logger.debug("Prepared Google ADK input (text_length=%d)", len(text_content))
|
|
106
|
-
return text_content
|
|
107
|
-
|
|
108
|
-
async def ainvoke(
|
|
109
|
-
self,
|
|
110
|
-
input: List[AgentMessage],
|
|
111
|
-
session_id: Union[str, None] = None,
|
|
112
|
-
) -> AgentInvocationResponse:
|
|
113
|
-
"""
|
|
114
|
-
Asynchronous invocation method - invokes the Google ADK agent with tracing
|
|
115
|
-
|
|
116
|
-
Args:
|
|
117
|
-
input: List[AgentMessage] containing user_message
|
|
118
|
-
session_id: Optional conversation ID for maintaining context
|
|
119
|
-
|
|
120
|
-
Returns:
|
|
121
|
-
AgentInvocationResponse - response containing agent trace, trajectory, and final response.
|
|
122
|
-
"""
|
|
123
|
-
logger.info(
|
|
124
|
-
"Google ADK ainvoke called (session_id=%s, input_messages=%d)",
|
|
125
|
-
session_id,
|
|
126
|
-
len(input),
|
|
127
|
-
)
|
|
128
|
-
agent_input = self._prepare_input(input)
|
|
129
|
-
session_id = session_id or str(uuid.uuid4())
|
|
130
|
-
|
|
131
|
-
try:
|
|
132
|
-
return await self._ainvoke_with_tracing(agent_input, session_id)
|
|
133
|
-
|
|
134
|
-
except Exception as e:
|
|
135
|
-
logger.exception("Error invoking Google ADK agent")
|
|
136
|
-
raise RuntimeError(f"Error invoking Google ADK agent: {e}") from e
|
|
137
|
-
|
|
138
|
-
async def _ainvoke_with_tracing(
|
|
139
|
-
self,
|
|
140
|
-
agent_input: str,
|
|
141
|
-
session_id: str,
|
|
142
|
-
) -> AgentInvocationResponse:
|
|
143
|
-
"""Execute ainvoke with tracing enabled."""
|
|
144
|
-
adapter_trace_id = f"{QURAITE_ADAPTER_TRACE_PREFIX}-{uuid.uuid4()}"
|
|
145
|
-
logger.debug(
|
|
146
|
-
"Starting Google ADK traced invocation (trace_id=%s, session_id=%s)",
|
|
147
|
-
adapter_trace_id,
|
|
148
|
-
session_id,
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
with self.tracer.start_as_current_span(name=adapter_trace_id):
|
|
152
|
-
# Create session if it doesn't exist
|
|
153
|
-
try:
|
|
154
|
-
await self.session_service.create_session(
|
|
155
|
-
app_name=self.app_name,
|
|
156
|
-
user_id=self.user_id,
|
|
157
|
-
session_id=session_id,
|
|
158
|
-
)
|
|
159
|
-
except AlreadyExistsError:
|
|
160
|
-
logger.info("Session already exists: %s", session_id)
|
|
161
|
-
except Exception as e:
|
|
162
|
-
logger.exception("Error creating Google ADK session")
|
|
163
|
-
raise RuntimeError(f"Error creating session: {e}") from e
|
|
164
|
-
|
|
165
|
-
# Create content for ADK
|
|
166
|
-
content = types.Content(
|
|
167
|
-
role="user",
|
|
168
|
-
parts=[types.Part(text=agent_input)],
|
|
169
|
-
)
|
|
170
|
-
|
|
171
|
-
# Run async and consume events
|
|
172
|
-
events = self.runner.run_async(
|
|
173
|
-
new_message=content,
|
|
174
|
-
user_id=self.user_id,
|
|
175
|
-
session_id=session_id,
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
# Consume all events (tracing captures everything)
|
|
179
|
-
async for event in events:
|
|
180
|
-
pass # Just consume events, tracing handles capture
|
|
181
|
-
|
|
182
|
-
# Get trace spans
|
|
183
|
-
trace_readable_spans = self.quraite_span_exporter.get_trace_by_testcase(
|
|
184
|
-
adapter_trace_id
|
|
185
|
-
)
|
|
186
|
-
|
|
187
|
-
if trace_readable_spans:
|
|
188
|
-
agent_trace = AgentTrace(
|
|
189
|
-
spans=[
|
|
190
|
-
AgentSpan.from_readable_oi_span(span)
|
|
191
|
-
for span in trace_readable_spans
|
|
192
|
-
],
|
|
193
|
-
)
|
|
194
|
-
logger.info(
|
|
195
|
-
"Google ADK trace collected %d spans for trace_id=%s",
|
|
196
|
-
len(trace_readable_spans),
|
|
197
|
-
adapter_trace_id,
|
|
198
|
-
)
|
|
199
|
-
else:
|
|
200
|
-
logger.warning(
|
|
201
|
-
"No spans exported for Google ADK trace_id=%s", adapter_trace_id
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
return AgentInvocationResponse(
|
|
205
|
-
agent_trace=agent_trace,
|
|
206
|
-
agent_trajectory=agent_trace.to_agent_trajectory(
|
|
207
|
-
framework=Framework.GOOGLE_ADK
|
|
208
|
-
),
|
|
209
|
-
)
|
|
1
|
+
import uuid
|
|
2
|
+
from typing import List, Union
|
|
3
|
+
|
|
4
|
+
from google.adk.agents import Agent
|
|
5
|
+
from google.adk.apps.app import App
|
|
6
|
+
from google.adk.errors.already_exists_error import AlreadyExistsError
|
|
7
|
+
from google.adk.runners import Runner
|
|
8
|
+
from google.adk.sessions import BaseSessionService, InMemorySessionService
|
|
9
|
+
from google.genai import types
|
|
10
|
+
from opentelemetry.trace import TracerProvider
|
|
11
|
+
|
|
12
|
+
from quraite.adapters.base import BaseAdapter
|
|
13
|
+
from quraite.logger import get_logger
|
|
14
|
+
from quraite.schema.message import AgentMessage
|
|
15
|
+
from quraite.schema.response import AgentInvocationResponse
|
|
16
|
+
from quraite.tracing.constants import QURAITE_ADAPTER_TRACE_PREFIX, Framework
|
|
17
|
+
from quraite.tracing.trace import AgentSpan, AgentTrace
|
|
18
|
+
|
|
19
|
+
logger = get_logger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class GoogleADKAdapter(BaseAdapter):
|
|
23
|
+
"""
|
|
24
|
+
Google ADK adapter wrapper that converts any Google ADK agent
|
|
25
|
+
to a standardized callable interface (ainvoke) with tracing support.
|
|
26
|
+
|
|
27
|
+
This class wraps any Google ADK Agent and provides:
|
|
28
|
+
- Asynchronous invocation via ainvoke()
|
|
29
|
+
- OpenTelemetry tracing integration
|
|
30
|
+
- Session management for multi-turn conversations
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
agent: Agent,
|
|
36
|
+
agent_name: str = "Google ADK Agent",
|
|
37
|
+
tracer_provider: TracerProvider = None,
|
|
38
|
+
app_name: str = "google_adk_agent",
|
|
39
|
+
user_id: str = str(uuid.uuid4()),
|
|
40
|
+
session_service: BaseSessionService = InMemorySessionService(),
|
|
41
|
+
):
|
|
42
|
+
"""
|
|
43
|
+
Initialize with a pre-configured Google ADK agent
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
agent: A Google ADK Agent instance
|
|
47
|
+
app_name: Application name for ADK runner
|
|
48
|
+
agent_name: Name of the agent for trajectory metadata
|
|
49
|
+
tracer_provider: TracerProvider for tracing (required)
|
|
50
|
+
"""
|
|
51
|
+
logger.debug(
|
|
52
|
+
"Initializing GoogleADKAdapter (agent_name=%s, app_name=%s)",
|
|
53
|
+
agent_name,
|
|
54
|
+
app_name,
|
|
55
|
+
)
|
|
56
|
+
self._init_tracing(tracer_provider, required=True)
|
|
57
|
+
|
|
58
|
+
self.agent: Agent = agent
|
|
59
|
+
self.app_name = app_name
|
|
60
|
+
self.agent_name = agent_name
|
|
61
|
+
self.session_service = session_service
|
|
62
|
+
self.user_id = user_id
|
|
63
|
+
self.app = App(
|
|
64
|
+
name=app_name,
|
|
65
|
+
root_agent=agent,
|
|
66
|
+
)
|
|
67
|
+
self.runner = Runner(
|
|
68
|
+
app=self.app,
|
|
69
|
+
session_service=session_service,
|
|
70
|
+
)
|
|
71
|
+
logger.info("GoogleADKAdapter initialized successfully")
|
|
72
|
+
|
|
73
|
+
def _prepare_input(self, input: List[AgentMessage]) -> str:
|
|
74
|
+
"""
|
|
75
|
+
Prepare input for Google ADK agent from List[Message].
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
input: List[Message] containing user_message
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
str: User message text
|
|
82
|
+
"""
|
|
83
|
+
logger.debug("Preparing Google ADK input from %d messages", len(input))
|
|
84
|
+
if not input or input[-1].role != "user":
|
|
85
|
+
logger.error("Google ADK input missing user message")
|
|
86
|
+
raise ValueError("No user message found in the input")
|
|
87
|
+
|
|
88
|
+
last_user_message = input[-1]
|
|
89
|
+
# Check if content list is not empty and has text
|
|
90
|
+
if not last_user_message.content:
|
|
91
|
+
logger.error("Google ADK user message missing content")
|
|
92
|
+
raise ValueError("User message has no content")
|
|
93
|
+
|
|
94
|
+
# Find the first text content item
|
|
95
|
+
text_content = None
|
|
96
|
+
for content_item in last_user_message.content:
|
|
97
|
+
if content_item.type == "text" and content_item.text:
|
|
98
|
+
text_content = content_item.text
|
|
99
|
+
break
|
|
100
|
+
|
|
101
|
+
if not text_content:
|
|
102
|
+
logger.error("Google ADK user message missing text content")
|
|
103
|
+
raise ValueError("No text content found in user message")
|
|
104
|
+
|
|
105
|
+
logger.debug("Prepared Google ADK input (text_length=%d)", len(text_content))
|
|
106
|
+
return text_content
|
|
107
|
+
|
|
108
|
+
async def ainvoke(
|
|
109
|
+
self,
|
|
110
|
+
input: List[AgentMessage],
|
|
111
|
+
session_id: Union[str, None] = None,
|
|
112
|
+
) -> AgentInvocationResponse:
|
|
113
|
+
"""
|
|
114
|
+
Asynchronous invocation method - invokes the Google ADK agent with tracing
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
input: List[AgentMessage] containing user_message
|
|
118
|
+
session_id: Optional conversation ID for maintaining context
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
AgentInvocationResponse - response containing agent trace, trajectory, and final response.
|
|
122
|
+
"""
|
|
123
|
+
logger.info(
|
|
124
|
+
"Google ADK ainvoke called (session_id=%s, input_messages=%d)",
|
|
125
|
+
session_id,
|
|
126
|
+
len(input),
|
|
127
|
+
)
|
|
128
|
+
agent_input = self._prepare_input(input)
|
|
129
|
+
session_id = session_id or str(uuid.uuid4())
|
|
130
|
+
|
|
131
|
+
try:
|
|
132
|
+
return await self._ainvoke_with_tracing(agent_input, session_id)
|
|
133
|
+
|
|
134
|
+
except Exception as e:
|
|
135
|
+
logger.exception("Error invoking Google ADK agent")
|
|
136
|
+
raise RuntimeError(f"Error invoking Google ADK agent: {e}") from e
|
|
137
|
+
|
|
138
|
+
async def _ainvoke_with_tracing(
|
|
139
|
+
self,
|
|
140
|
+
agent_input: str,
|
|
141
|
+
session_id: str,
|
|
142
|
+
) -> AgentInvocationResponse:
|
|
143
|
+
"""Execute ainvoke with tracing enabled."""
|
|
144
|
+
adapter_trace_id = f"{QURAITE_ADAPTER_TRACE_PREFIX}-{uuid.uuid4()}"
|
|
145
|
+
logger.debug(
|
|
146
|
+
"Starting Google ADK traced invocation (trace_id=%s, session_id=%s)",
|
|
147
|
+
adapter_trace_id,
|
|
148
|
+
session_id,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
with self.tracer.start_as_current_span(name=adapter_trace_id):
|
|
152
|
+
# Create session if it doesn't exist
|
|
153
|
+
try:
|
|
154
|
+
await self.session_service.create_session(
|
|
155
|
+
app_name=self.app_name,
|
|
156
|
+
user_id=self.user_id,
|
|
157
|
+
session_id=session_id,
|
|
158
|
+
)
|
|
159
|
+
except AlreadyExistsError:
|
|
160
|
+
logger.info("Session already exists: %s", session_id)
|
|
161
|
+
except Exception as e:
|
|
162
|
+
logger.exception("Error creating Google ADK session")
|
|
163
|
+
raise RuntimeError(f"Error creating session: {e}") from e
|
|
164
|
+
|
|
165
|
+
# Create content for ADK
|
|
166
|
+
content = types.Content(
|
|
167
|
+
role="user",
|
|
168
|
+
parts=[types.Part(text=agent_input)],
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
# Run async and consume events
|
|
172
|
+
events = self.runner.run_async(
|
|
173
|
+
new_message=content,
|
|
174
|
+
user_id=self.user_id,
|
|
175
|
+
session_id=session_id,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
# Consume all events (tracing captures everything)
|
|
179
|
+
async for event in events:
|
|
180
|
+
pass # Just consume events, tracing handles capture
|
|
181
|
+
|
|
182
|
+
# Get trace spans
|
|
183
|
+
trace_readable_spans = self.quraite_span_exporter.get_trace_by_testcase(
|
|
184
|
+
adapter_trace_id
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
if trace_readable_spans:
|
|
188
|
+
agent_trace = AgentTrace(
|
|
189
|
+
spans=[
|
|
190
|
+
AgentSpan.from_readable_oi_span(span)
|
|
191
|
+
for span in trace_readable_spans
|
|
192
|
+
],
|
|
193
|
+
)
|
|
194
|
+
logger.info(
|
|
195
|
+
"Google ADK trace collected %d spans for trace_id=%s",
|
|
196
|
+
len(trace_readable_spans),
|
|
197
|
+
adapter_trace_id,
|
|
198
|
+
)
|
|
199
|
+
else:
|
|
200
|
+
logger.warning(
|
|
201
|
+
"No spans exported for Google ADK trace_id=%s", adapter_trace_id
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
return AgentInvocationResponse(
|
|
205
|
+
agent_trace=agent_trace,
|
|
206
|
+
agent_trajectory=agent_trace.to_agent_trajectory(
|
|
207
|
+
framework=Framework.GOOGLE_ADK
|
|
208
|
+
),
|
|
209
|
+
)
|