quraite 0.0.2__tar.gz → 0.1.1__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.
Files changed (51) hide show
  1. quraite-0.1.1/PKG-INFO +377 -0
  2. quraite-0.1.1/README.md +342 -0
  3. {quraite-0.0.2 → quraite-0.1.1}/pyproject.toml +1 -1
  4. {quraite-0.0.2 → quraite-0.1.1}/quraite/adapters/http_adapter.py +46 -34
  5. {quraite-0.0.2 → quraite-0.1.1}/quraite/logger.py +5 -8
  6. {quraite-0.0.2 → quraite-0.1.1}/quraite/schema/message.py +38 -1
  7. {quraite-0.0.2 → quraite-0.1.1}/quraite/serve/local_agent.py +3 -3
  8. {quraite-0.0.2 → quraite-0.1.1}/quraite/tracing/trace.py +80 -10
  9. quraite-0.0.2/PKG-INFO +0 -44
  10. quraite-0.0.2/README.md +0 -9
  11. {quraite-0.0.2 → quraite-0.1.1}/quraite/__init__.py +0 -0
  12. {quraite-0.0.2 → quraite-0.1.1}/quraite/adapters/__init__.py +0 -0
  13. {quraite-0.0.2 → quraite-0.1.1}/quraite/adapters/agno_adapter.py +0 -0
  14. {quraite-0.0.2 → quraite-0.1.1}/quraite/adapters/base.py +0 -0
  15. {quraite-0.0.2 → quraite-0.1.1}/quraite/adapters/bedrock_agents_adapter.py +0 -0
  16. {quraite-0.0.2 → quraite-0.1.1}/quraite/adapters/flowise_adapter.py +0 -0
  17. {quraite-0.0.2 → quraite-0.1.1}/quraite/adapters/google_adk_adapter.py +0 -0
  18. {quraite-0.0.2 → quraite-0.1.1}/quraite/adapters/langflow_adapter.py +0 -0
  19. {quraite-0.0.2 → quraite-0.1.1}/quraite/adapters/langgraph_adapter.py +0 -0
  20. {quraite-0.0.2 → quraite-0.1.1}/quraite/adapters/langgraph_server_adapter.py +0 -0
  21. {quraite-0.0.2 → quraite-0.1.1}/quraite/adapters/n8n_adapter.py +0 -0
  22. {quraite-0.0.2 → quraite-0.1.1}/quraite/adapters/openai_agents_adapter.py +0 -0
  23. {quraite-0.0.2 → quraite-0.1.1}/quraite/adapters/pydantic_ai_adapter.py +0 -0
  24. {quraite-0.0.2 → quraite-0.1.1}/quraite/adapters/smolagents_adapter.py +0 -0
  25. {quraite-0.0.2 → quraite-0.1.1}/quraite/schema/__init__.py +0 -0
  26. {quraite-0.0.2 → quraite-0.1.1}/quraite/schema/response.py +0 -0
  27. {quraite-0.0.2 → quraite-0.1.1}/quraite/serve/__init__.py +0 -0
  28. {quraite-0.0.2 → quraite-0.1.1}/quraite/serve/cloudflared.py +0 -0
  29. {quraite-0.0.2 → quraite-0.1.1}/quraite/traces/traces_adk_openinference.json +0 -0
  30. {quraite-0.0.2 → quraite-0.1.1}/quraite/traces/traces_agno_multi_agent.json +0 -0
  31. {quraite-0.0.2 → quraite-0.1.1}/quraite/traces/traces_agno_openinference.json +0 -0
  32. {quraite-0.0.2 → quraite-0.1.1}/quraite/traces/traces_crewai_openinference.json +0 -0
  33. {quraite-0.0.2 → quraite-0.1.1}/quraite/traces/traces_langgraph_openinference.json +0 -0
  34. {quraite-0.0.2 → quraite-0.1.1}/quraite/traces/traces_langgraph_openinference_multi_agent.json +0 -0
  35. {quraite-0.0.2 → quraite-0.1.1}/quraite/traces/traces_langgraph_traceloop.json +0 -0
  36. {quraite-0.0.2 → quraite-0.1.1}/quraite/traces/traces_openai_agents_multi_agent_1.json +0 -0
  37. {quraite-0.0.2 → quraite-0.1.1}/quraite/traces/traces_openai_agents_openinference.json +0 -0
  38. {quraite-0.0.2 → quraite-0.1.1}/quraite/traces/traces_pydantic_openinference.json +0 -0
  39. {quraite-0.0.2 → quraite-0.1.1}/quraite/traces/traces_pydantic_openinference_multi_agent_1.json +0 -0
  40. {quraite-0.0.2 → quraite-0.1.1}/quraite/traces/traces_pydantic_openinference_multi_agent_2.json +0 -0
  41. {quraite-0.0.2 → quraite-0.1.1}/quraite/traces/traces_smol_agents_openinference.json +0 -0
  42. {quraite-0.0.2 → quraite-0.1.1}/quraite/traces/traces_smol_agents_tool_calling_openinference.json +0 -0
  43. {quraite-0.0.2 → quraite-0.1.1}/quraite/tracing/__init__.py +0 -0
  44. {quraite-0.0.2 → quraite-0.1.1}/quraite/tracing/constants.py +0 -0
  45. {quraite-0.0.2 → quraite-0.1.1}/quraite/tracing/span_exporter.py +0 -0
  46. {quraite-0.0.2 → quraite-0.1.1}/quraite/tracing/span_processor.py +0 -0
  47. {quraite-0.0.2 → quraite-0.1.1}/quraite/tracing/tool_extractors.py +0 -0
  48. {quraite-0.0.2 → quraite-0.1.1}/quraite/tracing/types.py +0 -0
  49. {quraite-0.0.2 → quraite-0.1.1}/quraite/tracing/utils.py +0 -0
  50. {quraite-0.0.2 → quraite-0.1.1}/quraite/utils/__init__.py +0 -0
  51. {quraite-0.0.2 → quraite-0.1.1}/quraite/utils/json_utils.py +0 -0
quraite-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,377 @@
1
+ Metadata-Version: 2.3
2
+ Name: quraite
3
+ Version: 0.1.1
4
+ Summary: This project provides adaptors and methods to integrate with the Quraite platform
5
+ Author: Shiv Mohith
6
+ Author-email: Shiv Mohith <shivmohith8@gmail.com>
7
+ Requires-Dist: aiohttp>=3.13.2
8
+ Requires-Dist: fastapi>=0.121.1
9
+ Requires-Dist: httpx>=0.28.1
10
+ Requires-Dist: openinference-semantic-conventions>=0.1.25
11
+ Requires-Dist: opentelemetry-api>=1.37.0
12
+ Requires-Dist: opentelemetry-sdk>=1.37.0
13
+ Requires-Dist: pydantic>=2.12.4
14
+ Requires-Dist: python-dotenv>=1.2.1
15
+ Requires-Dist: uvicorn>=0.38.0
16
+ Requires-Dist: agno>=2.3.4 ; extra == 'agno'
17
+ Requires-Dist: boto3>=1.40.70 ; extra == 'bedrock'
18
+ Requires-Dist: google-adk>=1.18.0 ; extra == 'google-adk'
19
+ Requires-Dist: langchain>=1.0.5 ; extra == 'langgraph'
20
+ Requires-Dist: langgraph>=1.0.3 ; extra == 'langgraph'
21
+ Requires-Dist: openai-agents>=0.5.0 ; extra == 'openai-agents'
22
+ Requires-Dist: pydantic-ai>=1.25.0 ; extra == 'pydantic-ai'
23
+ Requires-Dist: pyngrok>=7.5.0 ; extra == 'pyngrok'
24
+ Requires-Dist: smolagents>=1.23.0 ; extra == 'smolagents'
25
+ Requires-Python: >=3.10
26
+ Provides-Extra: agno
27
+ Provides-Extra: bedrock
28
+ Provides-Extra: google-adk
29
+ Provides-Extra: langgraph
30
+ Provides-Extra: openai-agents
31
+ Provides-Extra: pydantic-ai
32
+ Provides-Extra: pyngrok
33
+ Provides-Extra: smolagents
34
+ Description-Content-Type: text/markdown
35
+
36
+ # Quraite Python SDK
37
+
38
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
39
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
40
+
41
+ The **Quraite Python SDK** provides adapters and methods to integrate AI agent frameworks with the [Quraite platform](https://quraite.ai). It offers a unified interface for different agent frameworks, automatic tracing and observability, and easy local server setup with tunneling capabilities.
42
+
43
+ ## Features
44
+
45
+ - 🔌 **Framework Adapters**: Support for multiple AI agent frameworks (LangGraph, Pydantic AI, Agno, Google ADK, OpenAI Agents, Smolagents, AWS Bedrock, Flowise, Langflow, N8n, and more)
46
+ - 📊 **Automatic Tracing**: Built-in OpenTelemetry-based tracing for agent execution, tool calls, and performance metrics
47
+ - 🚀 **Local Server**: Easy-to-use local server with optional tunneling (Cloudflare/ngrok) for public access
48
+ - 📦 **Standardized Schema**: Unified message and response formats across all frameworks
49
+ - 🔍 **Observability**: Track token usage, costs, latency, and model information for each agent invocation
50
+
51
+ ## Installation
52
+
53
+ ### Basic Installation
54
+
55
+ ```bash
56
+ pip install quraite
57
+ ```
58
+
59
+ ### Framework-Specific Installation
60
+
61
+ Install with optional dependencies for specific frameworks:
62
+
63
+ ```bash
64
+ # LangGraph
65
+ pip install 'quraite[langgraph]'
66
+
67
+ # Pydantic AI
68
+ pip install 'quraite[pydantic-ai]'
69
+
70
+ # Agno
71
+ pip install 'quraite[agno]'
72
+
73
+ # Google ADK
74
+ pip install 'quraite[google-adk]'
75
+
76
+ # OpenAI Agents
77
+ pip install 'quraite[openai-agents]'
78
+
79
+ # Smolagents
80
+ pip install 'quraite[smolagents]'
81
+
82
+ # AWS Bedrock
83
+ pip install 'quraite[bedrock]'
84
+
85
+ # Multiple frameworks
86
+ pip install 'quraite[langgraph,pydantic-ai,agno]'
87
+ ```
88
+
89
+ ## Quick Start
90
+
91
+ ### Example: LangGraph Agent with Local Server
92
+
93
+ Pass your compiled LangGraph agent to the adapter and expose it as an HTTP API:
94
+
95
+ ```python
96
+ import uvicorn
97
+ from dotenv import load_dotenv
98
+ from openinference.instrumentation import TracerProvider
99
+ from openinference.instrumentation.langchain import LangChainInstrumentor
100
+
101
+ from quraite.adapters import LanggraphAdapter
102
+ from quraite.serve.local_agent import LocalAgentServer
103
+ from quraite.tracing.span_exporter import QuraiteInMemorySpanExporter
104
+ from quraite.tracing.span_processor import QuraiteSimpleSpanProcessor
105
+
106
+ load_dotenv()
107
+
108
+ # Set up tracing (optional)
109
+ tracer_provider = TracerProvider()
110
+ quraite_span_exporter = QuraiteInMemorySpanExporter()
111
+ quraite_span_processor = QuraiteSimpleSpanProcessor(quraite_span_exporter)
112
+ tracer_provider.add_span_processor(quraite_span_processor)
113
+ LangChainInstrumentor().instrument(tracer_provider=tracer_provider)
114
+
115
+ # Your compiled LangGraph agent (created elsewhere)
116
+ # agent = create_agent(...)
117
+
118
+ # Wrap with Quraite adapter
119
+ adapter = LanggraphAdapter(
120
+ agent_graph=agent, # Pass your compiled LangGraph agent here
121
+ tracer_provider=tracer_provider, # Optional: for tracing
122
+ )
123
+
124
+ # Create and start server with Cloudflare tunnel
125
+ server = LocalAgentServer(
126
+ wrapped_agent=adapter,
127
+ agent_id="your-agent-id", # Optional: for Quraite platform integration
128
+ )
129
+
130
+ app = server.create_app(
131
+ port=8080,
132
+ host="0.0.0.0",
133
+ tunnel="cloudflare", # Options: "cloudflare", "ngrok", or "none"
134
+ )
135
+
136
+ if __name__ == "__main__":
137
+ uvicorn.run("local_server:app", host="0.0.0.0", port=8080)
138
+ ```
139
+
140
+ The server exposes:
141
+
142
+ - `GET /` - Health check endpoint
143
+ - `POST /v1/agents/completions` - Agent invocation endpoint
144
+
145
+ When using `tunnel="cloudflare"` or `tunnel="ngrok"`, your agent will be publicly accessible via the generated URL.
146
+
147
+ ## Supported Frameworks
148
+
149
+ | Framework | Adapter | Installation |
150
+ | -------------------- | ------------------------ | -------------------------------------- |
151
+ | **LangGraph** | `LanggraphAdapter` | `pip install 'quraite[langgraph]'` |
152
+ | **Pydantic AI** | `PydanticAIAdapter` | `pip install 'quraite[pydantic-ai]'` |
153
+ | **Agno** | `AgnoAdapter` | `pip install 'quraite[agno]'` |
154
+ | **Google ADK** | `GoogleADKAdapter` | `pip install 'quraite[google-adk]'` |
155
+ | **OpenAI Agents** | `OpenaiAgentsAdapter` | `pip install 'quraite[openai-agents]'` |
156
+ | **Smolagents** | `SmolagentsAdapter` | `pip install 'quraite[smolagents]'` |
157
+ | **AWS Bedrock** | `BedrockAgentsAdapter` | `pip install 'quraite[bedrock]'` |
158
+ | **Flowise** | `FlowiseAdapter` | Included in base package |
159
+ | **Langflow** | `LangflowAdapter` | Included in base package |
160
+ | **N8n** | `N8nAdapter` | Included in base package |
161
+ | **HTTP** | `HttpAdapter` | Included in base package |
162
+ | **LangGraph Server** | `LanggraphServerAdapter` | `pip install 'quraite[langgraph]'` |
163
+
164
+ ## Core Concepts
165
+
166
+ ### Adapters
167
+
168
+ Adapters provide a unified interface (`BaseAdapter`) for different agent frameworks. Each adapter:
169
+
170
+ - Converts framework-specific agents to a standard interface
171
+ - Handles message format conversion
172
+ - Supports optional tracing integration
173
+ - Provides async invocation via `ainvoke()`
174
+
175
+ ### Tracing
176
+
177
+ The SDK includes built-in OpenTelemetry-based tracing that captures:
178
+
179
+ - **Agent Trajectory**: Complete conversation flow with all messages
180
+ - **Tool Calls**: Tool invocations with inputs and outputs
181
+ - **Performance Metrics**: Token usage, costs, latency
182
+ - **Model Information**: Model name and provider details
183
+
184
+ To enable tracing:
185
+
186
+ ```python
187
+ from openinference.instrumentation import TracerProvider
188
+ from quraite.tracing.span_exporter import QuraiteInMemorySpanExporter
189
+ from quraite.tracing.span_processor import QuraiteSimpleSpanProcessor
190
+
191
+ tracer_provider = TracerProvider()
192
+ quraite_span_exporter = QuraiteInMemorySpanExporter()
193
+ quraite_span_processor = QuraiteSimpleSpanProcessor(quraite_span_exporter)
194
+ tracer_provider.add_span_processor(quraite_span_processor)
195
+
196
+ # Instrument your framework (example for LangChain)
197
+ from openinference.instrumentation.langchain import LangChainInstrumentor
198
+ LangChainInstrumentor().instrument(tracer_provider=tracer_provider)
199
+ ```
200
+
201
+ ### Message Schema
202
+
203
+ The SDK uses a standardized message format:
204
+
205
+ ```python
206
+ from quraite.schema.message import (
207
+ UserMessage,
208
+ AssistantMessage,
209
+ ToolMessage,
210
+ SystemMessage,
211
+ MessageContentText,
212
+ ToolCall,
213
+ )
214
+
215
+ # User message
216
+ user_msg = UserMessage(
217
+ content=[MessageContentText(text="Hello, world!")]
218
+ )
219
+
220
+ # Assistant message with tool calls
221
+ assistant_msg = AssistantMessage(
222
+ content=[MessageContentText(text="I'll calculate that for you.")],
223
+ tool_calls=[
224
+ ToolCall(
225
+ id="call_123",
226
+ name="add",
227
+ arguments={"a": 10, "b": 5}
228
+ )
229
+ ]
230
+ )
231
+
232
+ # Tool message
233
+ tool_msg = ToolMessage(
234
+ tool_call_id="call_123",
235
+ content=[MessageContentText(text="15")]
236
+ )
237
+ ```
238
+
239
+ ### Response Format
240
+
241
+ Agent invocations return an `AgentInvocationResponse`:
242
+
243
+ ```python
244
+ from quraite.schema.response import AgentInvocationResponse
245
+
246
+ response: AgentInvocationResponse = await adapter.ainvoke(
247
+ input=[user_msg],
248
+ session_id="session-123"
249
+ )
250
+
251
+ # Access trajectory (list of messages)
252
+ trajectory = response.agent_trajectory
253
+
254
+ # Access trace (if tracing enabled)
255
+ trace = response.agent_trace
256
+
257
+ # Access final response text
258
+ final_response = response.agent_final_response
259
+ ```
260
+
261
+ ## Examples
262
+
263
+ The repository includes comprehensive examples for each supported framework:
264
+
265
+ - [`langgraph_calculator_agent`](examples/langgraph_calculator_agent/) - LangGraph calculator agent
266
+ - [`pydantic_calculator_agent`](examples/pydantic_calculator_agent/) - Pydantic AI calculator agent
267
+ - [`agno_calculator_agent`](examples/agno_calculator_agent/) - Agno calculator agent
268
+ - [`google_adk_weather_agent`](examples/google_adk_weather_agent/) - Google ADK weather agent
269
+ - [`openai_flight_booking_agent`](examples/openai_flight_booking_agent/) - OpenAI Agents flight booking
270
+ - [`smolagents_sql_agent`](examples/smolagents_sql_agent/) - Smolagents SQL agent
271
+ - [`bedrock_restaurant_support_agent`](examples/bedrock_restaurant_support_agent/) - AWS Bedrock agent
272
+ - And more...
273
+
274
+ Each example includes:
275
+
276
+ - Agent implementation
277
+ - Adapter setup
278
+ - Local server configuration
279
+ - Environment variable examples
280
+
281
+ ## API Reference
282
+
283
+ ### BaseAdapter
284
+
285
+ All adapters inherit from `BaseAdapter`:
286
+
287
+ ```python
288
+ from quraite.adapters.base import BaseAdapter
289
+
290
+ class MyAdapter(BaseAdapter):
291
+ async def ainvoke(
292
+ self,
293
+ input: List[AgentMessage],
294
+ session_id: str | None,
295
+ ) -> AgentInvocationResponse:
296
+ # Implementation
297
+ pass
298
+ ```
299
+
300
+ ### LocalAgentServer
301
+
302
+ Create a local HTTP server for your agent:
303
+
304
+ ```python
305
+ from quraite.serve.local_agent import LocalAgentServer
306
+
307
+ server = LocalAgentServer(
308
+ wrapped_agent=adapter,
309
+ agent_id="optional-agent-id",
310
+ )
311
+
312
+ app = server.create_app(
313
+ port=8080,
314
+ host="0.0.0.0",
315
+ tunnel="cloudflare", # or "ngrok" or "none"
316
+ )
317
+ ```
318
+
319
+ ## Development
320
+
321
+ ### Setup
322
+
323
+ ```bash
324
+ # Clone the repository
325
+ git clone https://github.com/innowhyte/quraite-python.git
326
+ cd quraite-python
327
+
328
+ # Install dependencies
329
+ pip install -e ".[dev,test]"
330
+ ```
331
+
332
+ ### Running Tests
333
+
334
+ ```bash
335
+ pytest
336
+ ```
337
+
338
+ ### Building
339
+
340
+ ```bash
341
+ make build
342
+ ```
343
+
344
+ ### Publishing
345
+
346
+ ```bash
347
+ # Update version
348
+ make update-version v=0.4.0
349
+
350
+ # Build
351
+ make build
352
+
353
+ # Publish to Test PyPI
354
+ make publish
355
+ # Enter username as "__token__" and then enter your API key
356
+ ```
357
+
358
+ ## Requirements
359
+
360
+ - Python 3.10+
361
+ - See `pyproject.toml` for full dependency list
362
+
363
+ ## License
364
+
365
+ See [LICENSE](LICENSE) file for details.
366
+
367
+ ## Contributing
368
+
369
+ Contributions are welcome! Please feel free to submit a Pull Request.
370
+
371
+ ## Support
372
+
373
+ For issues, questions, or contributions, please visit the [Quraite platform](https://quraite.ai) or open an issue on GitHub.
374
+
375
+ ## Changelog
376
+
377
+ See the repository's commit history for detailed changes.
@@ -0,0 +1,342 @@
1
+ # Quraite Python SDK
2
+
3
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
4
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
5
+
6
+ The **Quraite Python SDK** provides adapters and methods to integrate AI agent frameworks with the [Quraite platform](https://quraite.ai). It offers a unified interface for different agent frameworks, automatic tracing and observability, and easy local server setup with tunneling capabilities.
7
+
8
+ ## Features
9
+
10
+ - 🔌 **Framework Adapters**: Support for multiple AI agent frameworks (LangGraph, Pydantic AI, Agno, Google ADK, OpenAI Agents, Smolagents, AWS Bedrock, Flowise, Langflow, N8n, and more)
11
+ - 📊 **Automatic Tracing**: Built-in OpenTelemetry-based tracing for agent execution, tool calls, and performance metrics
12
+ - 🚀 **Local Server**: Easy-to-use local server with optional tunneling (Cloudflare/ngrok) for public access
13
+ - 📦 **Standardized Schema**: Unified message and response formats across all frameworks
14
+ - 🔍 **Observability**: Track token usage, costs, latency, and model information for each agent invocation
15
+
16
+ ## Installation
17
+
18
+ ### Basic Installation
19
+
20
+ ```bash
21
+ pip install quraite
22
+ ```
23
+
24
+ ### Framework-Specific Installation
25
+
26
+ Install with optional dependencies for specific frameworks:
27
+
28
+ ```bash
29
+ # LangGraph
30
+ pip install 'quraite[langgraph]'
31
+
32
+ # Pydantic AI
33
+ pip install 'quraite[pydantic-ai]'
34
+
35
+ # Agno
36
+ pip install 'quraite[agno]'
37
+
38
+ # Google ADK
39
+ pip install 'quraite[google-adk]'
40
+
41
+ # OpenAI Agents
42
+ pip install 'quraite[openai-agents]'
43
+
44
+ # Smolagents
45
+ pip install 'quraite[smolagents]'
46
+
47
+ # AWS Bedrock
48
+ pip install 'quraite[bedrock]'
49
+
50
+ # Multiple frameworks
51
+ pip install 'quraite[langgraph,pydantic-ai,agno]'
52
+ ```
53
+
54
+ ## Quick Start
55
+
56
+ ### Example: LangGraph Agent with Local Server
57
+
58
+ Pass your compiled LangGraph agent to the adapter and expose it as an HTTP API:
59
+
60
+ ```python
61
+ import uvicorn
62
+ from dotenv import load_dotenv
63
+ from openinference.instrumentation import TracerProvider
64
+ from openinference.instrumentation.langchain import LangChainInstrumentor
65
+
66
+ from quraite.adapters import LanggraphAdapter
67
+ from quraite.serve.local_agent import LocalAgentServer
68
+ from quraite.tracing.span_exporter import QuraiteInMemorySpanExporter
69
+ from quraite.tracing.span_processor import QuraiteSimpleSpanProcessor
70
+
71
+ load_dotenv()
72
+
73
+ # Set up tracing (optional)
74
+ tracer_provider = TracerProvider()
75
+ quraite_span_exporter = QuraiteInMemorySpanExporter()
76
+ quraite_span_processor = QuraiteSimpleSpanProcessor(quraite_span_exporter)
77
+ tracer_provider.add_span_processor(quraite_span_processor)
78
+ LangChainInstrumentor().instrument(tracer_provider=tracer_provider)
79
+
80
+ # Your compiled LangGraph agent (created elsewhere)
81
+ # agent = create_agent(...)
82
+
83
+ # Wrap with Quraite adapter
84
+ adapter = LanggraphAdapter(
85
+ agent_graph=agent, # Pass your compiled LangGraph agent here
86
+ tracer_provider=tracer_provider, # Optional: for tracing
87
+ )
88
+
89
+ # Create and start server with Cloudflare tunnel
90
+ server = LocalAgentServer(
91
+ wrapped_agent=adapter,
92
+ agent_id="your-agent-id", # Optional: for Quraite platform integration
93
+ )
94
+
95
+ app = server.create_app(
96
+ port=8080,
97
+ host="0.0.0.0",
98
+ tunnel="cloudflare", # Options: "cloudflare", "ngrok", or "none"
99
+ )
100
+
101
+ if __name__ == "__main__":
102
+ uvicorn.run("local_server:app", host="0.0.0.0", port=8080)
103
+ ```
104
+
105
+ The server exposes:
106
+
107
+ - `GET /` - Health check endpoint
108
+ - `POST /v1/agents/completions` - Agent invocation endpoint
109
+
110
+ When using `tunnel="cloudflare"` or `tunnel="ngrok"`, your agent will be publicly accessible via the generated URL.
111
+
112
+ ## Supported Frameworks
113
+
114
+ | Framework | Adapter | Installation |
115
+ | -------------------- | ------------------------ | -------------------------------------- |
116
+ | **LangGraph** | `LanggraphAdapter` | `pip install 'quraite[langgraph]'` |
117
+ | **Pydantic AI** | `PydanticAIAdapter` | `pip install 'quraite[pydantic-ai]'` |
118
+ | **Agno** | `AgnoAdapter` | `pip install 'quraite[agno]'` |
119
+ | **Google ADK** | `GoogleADKAdapter` | `pip install 'quraite[google-adk]'` |
120
+ | **OpenAI Agents** | `OpenaiAgentsAdapter` | `pip install 'quraite[openai-agents]'` |
121
+ | **Smolagents** | `SmolagentsAdapter` | `pip install 'quraite[smolagents]'` |
122
+ | **AWS Bedrock** | `BedrockAgentsAdapter` | `pip install 'quraite[bedrock]'` |
123
+ | **Flowise** | `FlowiseAdapter` | Included in base package |
124
+ | **Langflow** | `LangflowAdapter` | Included in base package |
125
+ | **N8n** | `N8nAdapter` | Included in base package |
126
+ | **HTTP** | `HttpAdapter` | Included in base package |
127
+ | **LangGraph Server** | `LanggraphServerAdapter` | `pip install 'quraite[langgraph]'` |
128
+
129
+ ## Core Concepts
130
+
131
+ ### Adapters
132
+
133
+ Adapters provide a unified interface (`BaseAdapter`) for different agent frameworks. Each adapter:
134
+
135
+ - Converts framework-specific agents to a standard interface
136
+ - Handles message format conversion
137
+ - Supports optional tracing integration
138
+ - Provides async invocation via `ainvoke()`
139
+
140
+ ### Tracing
141
+
142
+ The SDK includes built-in OpenTelemetry-based tracing that captures:
143
+
144
+ - **Agent Trajectory**: Complete conversation flow with all messages
145
+ - **Tool Calls**: Tool invocations with inputs and outputs
146
+ - **Performance Metrics**: Token usage, costs, latency
147
+ - **Model Information**: Model name and provider details
148
+
149
+ To enable tracing:
150
+
151
+ ```python
152
+ from openinference.instrumentation import TracerProvider
153
+ from quraite.tracing.span_exporter import QuraiteInMemorySpanExporter
154
+ from quraite.tracing.span_processor import QuraiteSimpleSpanProcessor
155
+
156
+ tracer_provider = TracerProvider()
157
+ quraite_span_exporter = QuraiteInMemorySpanExporter()
158
+ quraite_span_processor = QuraiteSimpleSpanProcessor(quraite_span_exporter)
159
+ tracer_provider.add_span_processor(quraite_span_processor)
160
+
161
+ # Instrument your framework (example for LangChain)
162
+ from openinference.instrumentation.langchain import LangChainInstrumentor
163
+ LangChainInstrumentor().instrument(tracer_provider=tracer_provider)
164
+ ```
165
+
166
+ ### Message Schema
167
+
168
+ The SDK uses a standardized message format:
169
+
170
+ ```python
171
+ from quraite.schema.message import (
172
+ UserMessage,
173
+ AssistantMessage,
174
+ ToolMessage,
175
+ SystemMessage,
176
+ MessageContentText,
177
+ ToolCall,
178
+ )
179
+
180
+ # User message
181
+ user_msg = UserMessage(
182
+ content=[MessageContentText(text="Hello, world!")]
183
+ )
184
+
185
+ # Assistant message with tool calls
186
+ assistant_msg = AssistantMessage(
187
+ content=[MessageContentText(text="I'll calculate that for you.")],
188
+ tool_calls=[
189
+ ToolCall(
190
+ id="call_123",
191
+ name="add",
192
+ arguments={"a": 10, "b": 5}
193
+ )
194
+ ]
195
+ )
196
+
197
+ # Tool message
198
+ tool_msg = ToolMessage(
199
+ tool_call_id="call_123",
200
+ content=[MessageContentText(text="15")]
201
+ )
202
+ ```
203
+
204
+ ### Response Format
205
+
206
+ Agent invocations return an `AgentInvocationResponse`:
207
+
208
+ ```python
209
+ from quraite.schema.response import AgentInvocationResponse
210
+
211
+ response: AgentInvocationResponse = await adapter.ainvoke(
212
+ input=[user_msg],
213
+ session_id="session-123"
214
+ )
215
+
216
+ # Access trajectory (list of messages)
217
+ trajectory = response.agent_trajectory
218
+
219
+ # Access trace (if tracing enabled)
220
+ trace = response.agent_trace
221
+
222
+ # Access final response text
223
+ final_response = response.agent_final_response
224
+ ```
225
+
226
+ ## Examples
227
+
228
+ The repository includes comprehensive examples for each supported framework:
229
+
230
+ - [`langgraph_calculator_agent`](examples/langgraph_calculator_agent/) - LangGraph calculator agent
231
+ - [`pydantic_calculator_agent`](examples/pydantic_calculator_agent/) - Pydantic AI calculator agent
232
+ - [`agno_calculator_agent`](examples/agno_calculator_agent/) - Agno calculator agent
233
+ - [`google_adk_weather_agent`](examples/google_adk_weather_agent/) - Google ADK weather agent
234
+ - [`openai_flight_booking_agent`](examples/openai_flight_booking_agent/) - OpenAI Agents flight booking
235
+ - [`smolagents_sql_agent`](examples/smolagents_sql_agent/) - Smolagents SQL agent
236
+ - [`bedrock_restaurant_support_agent`](examples/bedrock_restaurant_support_agent/) - AWS Bedrock agent
237
+ - And more...
238
+
239
+ Each example includes:
240
+
241
+ - Agent implementation
242
+ - Adapter setup
243
+ - Local server configuration
244
+ - Environment variable examples
245
+
246
+ ## API Reference
247
+
248
+ ### BaseAdapter
249
+
250
+ All adapters inherit from `BaseAdapter`:
251
+
252
+ ```python
253
+ from quraite.adapters.base import BaseAdapter
254
+
255
+ class MyAdapter(BaseAdapter):
256
+ async def ainvoke(
257
+ self,
258
+ input: List[AgentMessage],
259
+ session_id: str | None,
260
+ ) -> AgentInvocationResponse:
261
+ # Implementation
262
+ pass
263
+ ```
264
+
265
+ ### LocalAgentServer
266
+
267
+ Create a local HTTP server for your agent:
268
+
269
+ ```python
270
+ from quraite.serve.local_agent import LocalAgentServer
271
+
272
+ server = LocalAgentServer(
273
+ wrapped_agent=adapter,
274
+ agent_id="optional-agent-id",
275
+ )
276
+
277
+ app = server.create_app(
278
+ port=8080,
279
+ host="0.0.0.0",
280
+ tunnel="cloudflare", # or "ngrok" or "none"
281
+ )
282
+ ```
283
+
284
+ ## Development
285
+
286
+ ### Setup
287
+
288
+ ```bash
289
+ # Clone the repository
290
+ git clone https://github.com/innowhyte/quraite-python.git
291
+ cd quraite-python
292
+
293
+ # Install dependencies
294
+ pip install -e ".[dev,test]"
295
+ ```
296
+
297
+ ### Running Tests
298
+
299
+ ```bash
300
+ pytest
301
+ ```
302
+
303
+ ### Building
304
+
305
+ ```bash
306
+ make build
307
+ ```
308
+
309
+ ### Publishing
310
+
311
+ ```bash
312
+ # Update version
313
+ make update-version v=0.4.0
314
+
315
+ # Build
316
+ make build
317
+
318
+ # Publish to Test PyPI
319
+ make publish
320
+ # Enter username as "__token__" and then enter your API key
321
+ ```
322
+
323
+ ## Requirements
324
+
325
+ - Python 3.10+
326
+ - See `pyproject.toml` for full dependency list
327
+
328
+ ## License
329
+
330
+ See [LICENSE](LICENSE) file for details.
331
+
332
+ ## Contributing
333
+
334
+ Contributions are welcome! Please feel free to submit a Pull Request.
335
+
336
+ ## Support
337
+
338
+ For issues, questions, or contributions, please visit the [Quraite platform](https://quraite.ai) or open an issue on GitHub.
339
+
340
+ ## Changelog
341
+
342
+ See the repository's commit history for detailed changes.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "quraite"
3
- version = "0.0.2"
3
+ version = "0.1.1"
4
4
  description = "This project provides adaptors and methods to integrate with the Quraite platform"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -118,10 +118,6 @@ class HttpAdapter(BaseAdapter):
118
118
 
119
119
  Returns:
120
120
  Response data as dictionary
121
-
122
- Raises:
123
- httpx.HTTPError: If all retries fail
124
- ValueError: If response format is invalid
125
121
  """
126
122
  last_exception = None
127
123
 
@@ -141,28 +137,15 @@ class HttpAdapter(BaseAdapter):
141
137
  return response.json()
142
138
 
143
139
  except httpx.HTTPStatusError as e:
144
- # Don't retry on 4xx errors (client errors)
145
- if 400 <= e.response.status_code < 500:
146
- error_detail = e.response.text
147
- logger.error(
148
- "HTTP adapter received 4xx response (status=%s, detail=%s)",
149
- e.response.status_code,
150
- error_detail,
151
- )
152
- raise ValueError(
153
- f"Agent server error ({e.response.status_code}): {error_detail}"
154
- ) from e
140
+ error_detail = e.response.text
141
+ logger.error(
142
+ "Failed while invoking the url '%s' with status code '%s' and detail '%s'",
143
+ url,
144
+ e.response.status_code,
145
+ error_detail,
146
+ )
155
147
 
156
- # Retry on 5xx errors
157
- last_exception = e
158
- if attempt < self.max_retries - 1:
159
- delay = self.retry_delay * (2**attempt)
160
- logger.warning(
161
- "HTTP adapter retrying after server error (status=%s, retry_in=%.2fs)",
162
- e.response.status_code,
163
- delay,
164
- )
165
- await self._async_sleep(delay)
148
+ raise e
166
149
 
167
150
  except (httpx.ConnectError, httpx.TimeoutException) as e:
168
151
  # Retry on network errors
@@ -170,21 +153,27 @@ class HttpAdapter(BaseAdapter):
170
153
  if attempt < self.max_retries - 1:
171
154
  delay = self.retry_delay * (2**attempt)
172
155
  logger.warning(
173
- "HTTP adapter retrying after network error (retry_in=%.2fs)",
156
+ "HTTP adapter retrying after network/connection error (retry_in=%.2fs)",
174
157
  delay,
175
158
  )
176
159
  await self._async_sleep(delay)
160
+ else:
161
+ logger.error(
162
+ "Failed while connecting to the url %s after %d attempts. Last error: %s",
163
+ url,
164
+ self.max_retries,
165
+ last_exception,
166
+ )
167
+ raise last_exception
177
168
 
178
- # All retries failed
179
- logger.exception(
180
- "HTTP adapter failed after %d attempts (url=%s)",
169
+ logger.error(
170
+ "HTTP adapter failed while invoking the url %s after %d attempts. Last error: %s",
171
+ url,
181
172
  self.max_retries,
182
- self.url,
173
+ last_exception,
183
174
  )
184
- raise RuntimeError(
185
- f"Failed to connect to agent server at {self.url} after "
186
- f"{self.max_retries} attempts. Last error: {last_exception}"
187
- ) from last_exception
175
+
176
+ raise last_exception
188
177
 
189
178
  @staticmethod
190
179
  async def _async_sleep(seconds: float):
@@ -237,3 +226,26 @@ class HttpAdapter(BaseAdapter):
237
226
  async def __aexit__(self, exc_type, exc_val, exc_tb):
238
227
  """Async context manager exit."""
239
228
  await self.aclose()
229
+
230
+
231
+ if __name__ == "__main__":
232
+ import asyncio
233
+ import json
234
+
235
+ from quraite.schema.message import MessageContentText, UserMessage
236
+
237
+ async def test_http_adapter():
238
+ adapter = HttpAdapter(url="http://localhost:8080/v1/agents/completions")
239
+
240
+ try:
241
+ response = await adapter.ainvoke(
242
+ input=[UserMessage(content=[MessageContentText(text="What is 1 + 1")])],
243
+ session_id="test",
244
+ )
245
+ print(response)
246
+ except httpx.HTTPStatusError as e:
247
+ print(json.loads(e.response.text)["detail"])
248
+ except Exception as e:
249
+ print(e)
250
+
251
+ asyncio.run(test_http_adapter())
@@ -54,11 +54,8 @@ def get_logger(name: str | None = None) -> logging.Logger:
54
54
 
55
55
 
56
56
  # Set level from environment variable if provided
57
- _env_level = os.getenv("LOG_LEVEL")
58
- if _env_level:
59
- try:
60
- set_log_level(_env_level)
61
- except ValueError:
62
- pass
63
- else:
64
- set_log_level("INFO")
57
+ _env_level = os.getenv("LOG_LEVEL") or "INFO"
58
+ try:
59
+ set_log_level(_env_level)
60
+ except ValueError:
61
+ pass
@@ -1,6 +1,6 @@
1
1
  from typing import Any, List, Literal, Optional, TypeAlias, Union
2
2
 
3
- from pydantic import BaseModel
3
+ from pydantic import BaseModel, Field
4
4
 
5
5
 
6
6
  class MessageContentText(BaseModel):
@@ -35,11 +35,47 @@ class ToolCall(BaseModel):
35
35
  arguments: dict[str, Any]
36
36
 
37
37
 
38
+ class ModelInfo(BaseModel):
39
+ model_name: str = Field(default="")
40
+ model_provider: str = Field(default="")
41
+
42
+
43
+ class CostInfo(BaseModel):
44
+ input_cost: float = Field(default=0.0)
45
+ output_cost: float = Field(default=0.0)
46
+
47
+
48
+ class TokenInfo(BaseModel):
49
+ input_tokens: int = Field(default=0)
50
+ output_tokens: int = Field(default=0)
51
+
52
+
53
+ class LatencyInfo(BaseModel):
54
+ start_time: float = Field(default=0.0)
55
+ end_time: float = Field(default=0.0)
56
+
57
+
58
+ class AssistantMessageMetadata(BaseModel):
59
+ """Structured metadata for assistant messages."""
60
+
61
+ tokens: TokenInfo = Field(default_factory=TokenInfo)
62
+ cost: CostInfo = Field(default_factory=CostInfo)
63
+ latency: LatencyInfo = Field(default_factory=LatencyInfo)
64
+ model_info: ModelInfo = Field(default_factory=ModelInfo)
65
+
66
+
67
+ class ToolMessageMetadata(BaseModel):
68
+ """Structured metadata for tool messages."""
69
+
70
+ latency: LatencyInfo = Field(default_factory=LatencyInfo)
71
+
72
+
38
73
  class AssistantMessage(BaseModel):
39
74
  role: Literal["assistant"] = "assistant"
40
75
  agent_name: Optional[str] = None
41
76
  content: Optional[List[Union[MessageContentText, MessageContentReasoning]]] = None
42
77
  tool_calls: Optional[List[ToolCall]] = None
78
+ metadata: AssistantMessageMetadata = Field(default_factory=AssistantMessageMetadata)
43
79
 
44
80
 
45
81
  class ToolMessage(BaseModel):
@@ -47,6 +83,7 @@ class ToolMessage(BaseModel):
47
83
  tool_name: Optional[str] = None
48
84
  tool_call_id: Optional[str] = None
49
85
  content: List[MessageContentText]
86
+ metadata: ToolMessageMetadata = Field(default_factory=ToolMessageMetadata)
50
87
 
51
88
 
52
89
  AgentMessage: TypeAlias = Union[
@@ -48,7 +48,7 @@ class LocalAgentServer:
48
48
  Usage:
49
49
  ```python
50
50
  from quraite.serve.local_agent_server import LocalAgentServer
51
- from quraite.adapters.langgraph_adapter import LangGraphAdapter
51
+ from quraite.adapters import LangGraphAdapter
52
52
 
53
53
  sdk = LocalAgentServer(wrapped_agent=LangGraphAdapter(agent_graph=agent_graph))
54
54
  sdk.start(host="0.0.0.0", port=8000, reload=False)
@@ -331,12 +331,12 @@ class LocalAgentServer:
331
331
 
332
332
  try:
333
333
  # Invoke agent (asynchronously)
334
- messages: List[AgentMessage] = await self._agent.ainvoke(
334
+ response: AgentInvocationResponse = await self._agent.ainvoke(
335
335
  input=request.input,
336
336
  session_id=request.session_id,
337
337
  )
338
338
 
339
- return InvokeResponse(agent_response=messages)
339
+ return InvokeResponse(agent_response=response)
340
340
 
341
341
  except HTTPException:
342
342
  raise
@@ -11,13 +11,14 @@ from opentelemetry.sdk.trace import Span as OTelSpan
11
11
  from pydantic import BaseModel, ConfigDict, Field
12
12
 
13
13
  from quraite.logger import get_logger
14
- from quraite.schema.message import (
15
- AssistantMessage,
16
- MessageContentText,
17
- SystemMessage,
18
- ToolCall,
19
- ToolMessage,
20
- )
14
+ from quraite.schema.message import AssistantMessage, AssistantMessageMetadata
15
+ from quraite.schema.message import CostInfo as MessageCostInfo
16
+ from quraite.schema.message import LatencyInfo as MessageLatencyInfo
17
+ from quraite.schema.message import MessageContentText
18
+ from quraite.schema.message import ModelInfo as MessageModelInfo
19
+ from quraite.schema.message import SystemMessage
20
+ from quraite.schema.message import TokenInfo as MessageTokenInfo
21
+ from quraite.schema.message import ToolCall, ToolMessage, ToolMessageMetadata
21
22
  from quraite.tracing.constants import Framework
22
23
  from quraite.tracing.types import Event, Link, Resource, SpanContext, SpanKind, Status
23
24
  from quraite.tracing.utils import unflatten_messages
@@ -254,8 +255,15 @@ class AgentTrace(BaseModel):
254
255
  self.spans.extend(spans)
255
256
  self._invalidate_tokens_and_cost_cache()
256
257
 
257
- def _convert_llm_message(self, msg: dict[str, Any]) -> AssistantMessage | None:
258
- """Convert an LLM output message dict to an AssistantMessage."""
258
+ def _convert_llm_message(
259
+ self, msg: dict[str, Any], metadata: AssistantMessageMetadata
260
+ ) -> AssistantMessage | None:
261
+ """Convert an LLM output message dict to an AssistantMessage.
262
+
263
+ Args:
264
+ msg: Raw LLM message dict from OpenInference attributes.
265
+ metadata: Per-span metadata (tokens, cost, latency) to attach.
266
+ """
259
267
 
260
268
  role = msg.get("role")
261
269
  tool_calls = msg.get("tool_calls")
@@ -322,6 +330,7 @@ class AgentTrace(BaseModel):
322
330
  return AssistantMessage(
323
331
  content=text_content if text_content else None,
324
332
  tool_calls=tool_calls_list if tool_calls_list else None,
333
+ metadata=metadata,
325
334
  )
326
335
 
327
336
  return None
@@ -336,6 +345,64 @@ class AgentTrace(BaseModel):
336
345
  content=[MessageContentText(type="text", text=str(content))],
337
346
  )
338
347
 
348
+ def _extract_assistant_metadata(self, span: AgentSpan) -> AssistantMessageMetadata:
349
+ """Extract assistant message metadata from a span.
350
+
351
+ Args:
352
+ span: The span to extract metadata from.
353
+
354
+ Returns:
355
+ AssistantMessageMetadata with tokens, cost, latency, and model info.
356
+ """
357
+ # Per-span token and cost metrics for assistant messages
358
+ span_input_tokens = span.attributes.get(
359
+ SpanAttributes.LLM_TOKEN_COUNT_PROMPT, 0
360
+ )
361
+ span_output_tokens = span.attributes.get(
362
+ SpanAttributes.LLM_TOKEN_COUNT_COMPLETION, 0
363
+ )
364
+ span_input_cost = span.attributes.get(SpanAttributes.LLM_COST_PROMPT, 0.0)
365
+ span_output_cost = span.attributes.get(SpanAttributes.LLM_COST_COMPLETION, 0.0)
366
+
367
+ # Per-span latency (nanoseconds as float)
368
+ span_start_time = float(span.start_time) if span.start_time is not None else 0.0
369
+ span_end_time = float(span.end_time) if span.end_time is not None else 0.0
370
+
371
+ # Per-span model info
372
+ span_model_name = span.attributes.get(SpanAttributes.LLM_MODEL_NAME, "")
373
+ span_model_provider = span.attributes.get(SpanAttributes.LLM_PROVIDER, "")
374
+
375
+ return AssistantMessageMetadata(
376
+ tokens=MessageTokenInfo(
377
+ input_tokens=span_input_tokens,
378
+ output_tokens=span_output_tokens,
379
+ ),
380
+ cost=MessageCostInfo(
381
+ input_cost=span_input_cost,
382
+ output_cost=span_output_cost,
383
+ ),
384
+ latency=MessageLatencyInfo(
385
+ start_time=span_start_time,
386
+ end_time=span_end_time,
387
+ ),
388
+ model_info=MessageModelInfo(
389
+ model_name=span_model_name,
390
+ model_provider=span_model_provider,
391
+ ),
392
+ )
393
+
394
+ def _extract_tool_metadata(self, span: AgentSpan) -> ToolMessageMetadata:
395
+ """Extract tool message metadata from a span."""
396
+ span_start_time = float(span.start_time) if span.start_time is not None else 0.0
397
+ span_end_time = float(span.end_time) if span.end_time is not None else 0.0
398
+
399
+ return ToolMessageMetadata(
400
+ latency=MessageLatencyInfo(
401
+ start_time=span_start_time,
402
+ end_time=span_end_time,
403
+ ),
404
+ )
405
+
339
406
  def to_agent_trajectory(
340
407
  self,
341
408
  framework: Framework = Framework.LANGGRAPH,
@@ -411,8 +478,10 @@ class AgentTrace(BaseModel):
411
478
  if only_leaf_llms and span_id and has_llm_children(span_id):
412
479
  continue
413
480
 
481
+ metadata = self._extract_assistant_metadata(span)
482
+
414
483
  for llm_msg in span.to_llm_messages():
415
- converted = self._convert_llm_message(llm_msg)
484
+ converted = self._convert_llm_message(llm_msg, metadata=metadata)
416
485
  if converted:
417
486
  messages.append(converted)
418
487
 
@@ -422,6 +491,7 @@ class AgentTrace(BaseModel):
422
491
  if tool_msg:
423
492
  converted = self._convert_tool_message(tool_msg)
424
493
  if converted:
494
+ converted.metadata = self._extract_tool_metadata(span)
425
495
  messages.append(converted)
426
496
 
427
497
  return messages
quraite-0.0.2/PKG-INFO DELETED
@@ -1,44 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: quraite
3
- Version: 0.0.2
4
- Summary: This project provides adaptors and methods to integrate with the Quraite platform
5
- Author: Shiv Mohith
6
- Author-email: Shiv Mohith <shivmohith8@gmail.com>
7
- Requires-Dist: aiohttp>=3.13.2
8
- Requires-Dist: fastapi>=0.121.1
9
- Requires-Dist: httpx>=0.28.1
10
- Requires-Dist: openinference-semantic-conventions>=0.1.25
11
- Requires-Dist: opentelemetry-api>=1.37.0
12
- Requires-Dist: opentelemetry-sdk>=1.37.0
13
- Requires-Dist: pydantic>=2.12.4
14
- Requires-Dist: python-dotenv>=1.2.1
15
- Requires-Dist: uvicorn>=0.38.0
16
- Requires-Dist: agno>=2.3.4 ; extra == 'agno'
17
- Requires-Dist: boto3>=1.40.70 ; extra == 'bedrock'
18
- Requires-Dist: google-adk>=1.18.0 ; extra == 'google-adk'
19
- Requires-Dist: langchain>=1.0.5 ; extra == 'langgraph'
20
- Requires-Dist: langgraph>=1.0.3 ; extra == 'langgraph'
21
- Requires-Dist: openai-agents>=0.5.0 ; extra == 'openai-agents'
22
- Requires-Dist: pydantic-ai>=1.25.0 ; extra == 'pydantic-ai'
23
- Requires-Dist: pyngrok>=7.5.0 ; extra == 'pyngrok'
24
- Requires-Dist: smolagents>=1.23.0 ; extra == 'smolagents'
25
- Requires-Python: >=3.10
26
- Provides-Extra: agno
27
- Provides-Extra: bedrock
28
- Provides-Extra: google-adk
29
- Provides-Extra: langgraph
30
- Provides-Extra: openai-agents
31
- Provides-Extra: pydantic-ai
32
- Provides-Extra: pyngrok
33
- Provides-Extra: smolagents
34
- Description-Content-Type: text/markdown
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
44
- ```
quraite-0.0.2/README.md DELETED
@@ -1,9 +0,0 @@
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
- ```
File without changes