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.
Files changed (48) hide show
  1. quraite/__init__.py +3 -3
  2. quraite/adapters/__init__.py +134 -134
  3. quraite/adapters/agno_adapter.py +159 -159
  4. quraite/adapters/base.py +123 -123
  5. quraite/adapters/bedrock_agents_adapter.py +343 -343
  6. quraite/adapters/flowise_adapter.py +275 -275
  7. quraite/adapters/google_adk_adapter.py +209 -209
  8. quraite/adapters/http_adapter.py +239 -239
  9. quraite/adapters/langflow_adapter.py +192 -192
  10. quraite/adapters/langgraph_adapter.py +304 -304
  11. quraite/adapters/langgraph_server_adapter.py +252 -252
  12. quraite/adapters/n8n_adapter.py +220 -220
  13. quraite/adapters/openai_agents_adapter.py +269 -269
  14. quraite/adapters/pydantic_ai_adapter.py +312 -312
  15. quraite/adapters/smolagents_adapter.py +152 -152
  16. quraite/logger.py +61 -62
  17. quraite/schema/message.py +91 -54
  18. quraite/schema/response.py +16 -16
  19. quraite/serve/__init__.py +1 -1
  20. quraite/serve/cloudflared.py +210 -210
  21. quraite/serve/local_agent.py +360 -360
  22. quraite/tracing/__init__.py +24 -24
  23. quraite/tracing/constants.py +16 -16
  24. quraite/tracing/span_exporter.py +115 -115
  25. quraite/tracing/span_processor.py +49 -49
  26. quraite/tracing/tool_extractors.py +290 -290
  27. quraite/tracing/trace.py +564 -494
  28. quraite/tracing/types.py +179 -179
  29. quraite/tracing/utils.py +170 -170
  30. quraite/utils/json_utils.py +269 -269
  31. {quraite-0.0.1.dist-info → quraite-0.1.0.dist-info}/METADATA +9 -9
  32. quraite-0.1.0.dist-info/RECORD +35 -0
  33. {quraite-0.0.1.dist-info → quraite-0.1.0.dist-info}/WHEEL +1 -1
  34. quraite/traces/traces_adk_openinference.json +0 -379
  35. quraite/traces/traces_agno_multi_agent.json +0 -669
  36. quraite/traces/traces_agno_openinference.json +0 -321
  37. quraite/traces/traces_crewai_openinference.json +0 -155
  38. quraite/traces/traces_langgraph_openinference.json +0 -349
  39. quraite/traces/traces_langgraph_openinference_multi_agent.json +0 -2705
  40. quraite/traces/traces_langgraph_traceloop.json +0 -510
  41. quraite/traces/traces_openai_agents_multi_agent_1.json +0 -402
  42. quraite/traces/traces_openai_agents_openinference.json +0 -341
  43. quraite/traces/traces_pydantic_openinference.json +0 -286
  44. quraite/traces/traces_pydantic_openinference_multi_agent_1.json +0 -399
  45. quraite/traces/traces_pydantic_openinference_multi_agent_2.json +0 -398
  46. quraite/traces/traces_smol_agents_openinference.json +0 -397
  47. quraite/traces/traces_smol_agents_tool_calling_openinference.json +0 -704
  48. 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
+ )