solana-agent 24.1.0__py3-none-any.whl → 24.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,14 +3,10 @@ LLM provider adapters for the Solana Agent system.
3
3
 
4
4
  These adapters implement the LLMProvider interface for different LLM services.
5
5
  """
6
- import asyncio
7
- import json
8
- from typing import Any, AsyncGenerator, Callable, Dict, Literal, Optional, Type, TypeVar
6
+ from typing import AsyncGenerator, Literal, Type, TypeVar
9
7
 
10
- import httpx
11
8
  from openai import AsyncOpenAI
12
9
  from pydantic import BaseModel
13
- import websockets
14
10
 
15
11
  from solana_agent.interfaces.providers.llm import LLMProvider
16
12
 
@@ -160,173 +156,3 @@ class OpenAIAdapter(LLMProvider):
160
156
  return completion.choices[0].message.parsed
161
157
  except Exception as e:
162
158
  print(f"Error with beta.parse method: {e}")
163
-
164
- async def create_realtime_session(
165
- self,
166
- model: str = "gpt-4o-mini-realtime-preview",
167
- modalities: list = ["audio", "text"],
168
- instructions: str = "You are a helpful assistant.",
169
- voice: str = "alloy",
170
- input_audio_format: str = "pcm16",
171
- output_audio_format: str = "pcm16",
172
- ) -> Dict[str, Any]: # pragma: no cover
173
- """Create a realtime session token for WebSocket communication."""
174
- try:
175
- # Get the API key from the AsyncOpenAI client
176
- api_key = self.client.api_key
177
-
178
- # Create an async HTTP client
179
- async with httpx.AsyncClient() as client:
180
- response = await client.post(
181
- "https://api.openai.com/v1/realtime/sessions",
182
- json={
183
- "model": model,
184
- "modalities": modalities,
185
- "instructions": instructions,
186
- "voice": voice,
187
- "input_audio_format": input_audio_format,
188
- "output_audio_format": output_audio_format,
189
- },
190
- headers={
191
- "Authorization": f"Bearer {api_key}",
192
- "Content-Type": "application/json",
193
- "OpenAI-Beta": "realtime=v1"
194
- }
195
- )
196
-
197
- if response.status_code == 200:
198
- return response.json()
199
- else:
200
- raise Exception(
201
- f"Failed to create realtime session: {response.text}")
202
- except Exception as e:
203
- print(f"Error creating realtime session: {str(e)}")
204
- raise
205
-
206
- async def realtime_audio_transcription(
207
- self,
208
- audio_generator: AsyncGenerator[bytes, None],
209
- transcription_config: Optional[Dict[str, Any]] = None,
210
- on_event: Optional[Callable[[Dict[str, Any]], Any]] = None,
211
- ) -> AsyncGenerator[str, None]: # pragma: no cover
212
- """Stream real-time audio transcription using the Realtime API.
213
-
214
- Args:
215
- audio_generator: Async generator that yields audio chunks
216
- transcription_config: Optional custom configuration for transcription
217
- on_event: Optional callback function for handling raw events
218
-
219
- Yields:
220
- Transcription text as it becomes available
221
- """
222
- # Create default transcription config if none provided
223
- if transcription_config is None:
224
- transcription_config = {
225
- "input_audio_format": "pcm16",
226
- "input_audio_transcription": {
227
- "model": "gpt-4o-mini-transcribe"
228
- },
229
- "turn_detection": {
230
- "type": "server_vad",
231
- "threshold": 0.5,
232
- "prefix_padding_ms": 300,
233
- "silence_duration_ms": 200
234
- }
235
- }
236
-
237
- try:
238
- # Get the API key from the AsyncOpenAI client
239
- api_key = self.client.api_key
240
-
241
- # Create transcription session
242
- async with httpx.AsyncClient() as client:
243
- response = await client.post(
244
- "https://api.openai.com/v1/realtime/transcription_sessions",
245
- json=transcription_config,
246
- headers={
247
- "Authorization": f"Bearer {api_key}",
248
- "Content-Type": "application/json",
249
- "OpenAI-Beta": "realtime=v1"
250
- }
251
- )
252
-
253
- if response.status_code != 200:
254
- raise Exception(
255
- f"Failed to create transcription session: {response.text}")
256
-
257
- session = response.json()
258
- client_secret = session["client_secret"]["value"]
259
-
260
- # Connect to WebSocket with proper headers as dictionary
261
- url = "wss://api.openai.com/v1/realtime?model=gpt-4o-mini-transcribe"
262
- headers = {
263
- "Authorization": f"Bearer {client_secret}",
264
- "OpenAI-Beta": "realtime=v1"
265
- }
266
-
267
- async with websockets.connect(url, additional_headers=headers) as websocket:
268
- # Handle WebSocket communication in the background
269
- audio_task = None
270
-
271
- async def send_audio():
272
- try:
273
- async for audio_chunk in audio_generator:
274
- # Base64 encode the audio
275
- import base64
276
- encoded_audio = base64.b64encode(
277
- audio_chunk).decode('utf-8')
278
-
279
- # Send audio chunk
280
- await websocket.send(json.dumps({
281
- "type": "input_audio_buffer.append",
282
- "audio": encoded_audio
283
- }))
284
-
285
- # Small delay to prevent flooding
286
- await asyncio.sleep(0.05)
287
-
288
- # Commit the audio buffer when done
289
- await websocket.send(json.dumps({
290
- "type": "input_audio_buffer.commit"
291
- }))
292
- except Exception as e:
293
- print(f"Error sending audio: {str(e)}")
294
-
295
- # Start sending audio in the background
296
- audio_task = asyncio.create_task(send_audio())
297
-
298
- # Process transcription events
299
- try:
300
- while True:
301
- message = await websocket.recv()
302
- event = json.loads(message)
303
-
304
- if on_event:
305
- # Check if on_event is a coroutine function and await it if needed
306
- if asyncio.iscoroutinefunction(on_event):
307
- await on_event(event)
308
- else:
309
- on_event(event)
310
-
311
- # Extract transcription deltas
312
- if event["type"] == "conversation.item.input_audio_transcription.delta":
313
- yield event["delta"]
314
-
315
- # Also handle completed transcriptions
316
- elif event["type"] == "conversation.item.input_audio_transcription.completed":
317
- yield event["transcript"]
318
- break
319
- finally:
320
- # Clean up audio task if it's still running
321
- if audio_task and not audio_task.done():
322
- audio_task.cancel()
323
- try:
324
- await audio_task
325
- except asyncio.CancelledError:
326
- pass
327
-
328
- except Exception as e:
329
- print(f"Error in realtime audio transcription: {str(e)}")
330
- import traceback
331
- print(traceback.format_exc())
332
- yield f"I apologize, but I encountered an error transcribing the audio: {str(e)}"
@@ -55,7 +55,6 @@ class SolanaAgent(SolanaAgentInterface):
55
55
  audio_input_format: Literal[
56
56
  "flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
57
57
  ] = "mp4",
58
- audio_transcription_real_time: bool = True,
59
58
  router: Optional[RoutingInterface] = None,
60
59
  ) -> AsyncGenerator[Union[str, bytes], None]: # pragma: no cover
61
60
  """Process a user message and return the response stream.
@@ -69,7 +68,6 @@ class SolanaAgent(SolanaAgentInterface):
69
68
  audio_instructions: Audio voice instructions
70
69
  audio_output_format: Audio output format
71
70
  audio_input_format: Audio input format
72
- audio_transcription_real_time: Flag for real-time audio transcription
73
71
  router: Optional routing service for processing
74
72
 
75
73
  Returns:
@@ -85,7 +83,6 @@ class SolanaAgent(SolanaAgentInterface):
85
83
  audio_input_format=audio_input_format,
86
84
  prompt=prompt,
87
85
  router=router,
88
- audio_transcription_real_time=audio_transcription_real_time,
89
86
  ):
90
87
  yield chunk
91
88
 
@@ -24,7 +24,6 @@ class SolanaAgent(ABC):
24
24
  "flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
25
25
  ] = "mp4",
26
26
  router: Optional[RoutingInterface] = None,
27
- audio_transcription_real_time: bool = True,
28
27
  ) -> AsyncGenerator[Union[str, bytes], None]:
29
28
  """Process a user message and return the response stream."""
30
29
  pass
@@ -34,7 +34,6 @@ class AgentService(ABC):
34
34
  "flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
35
35
  ] = "mp4",
36
36
  prompt: Optional[str] = None,
37
- audio_transcription_real_time: bool = True,
38
37
  ) -> AsyncGenerator[Union[str, bytes], None]:
39
38
  """Generate a response from an agent."""
40
39
  pass
@@ -23,7 +23,6 @@ class QueryService(ABC):
23
23
  ] = "mp4",
24
24
  prompt: Optional[str] = None,
25
25
  router: Optional[RoutingInterface] = None,
26
- audio_transcription_real_time: bool = True,
27
26
  ) -> AsyncGenerator[Union[str, bytes], None]:
28
27
  """Process the user request and generate a response."""
29
28
  pass
@@ -176,7 +176,6 @@ class AgentService(AgentServiceInterface):
176
176
  audio_input_format: Literal[
177
177
  "flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
178
178
  ] = "mp4",
179
- audio_transcription_real_time: bool = True,
180
179
  prompt: Optional[str] = None,
181
180
  ) -> AsyncGenerator[Union[str, bytes], None]: # pragma: no cover
182
181
  """Generate a response with support for text/audio input/output."""
@@ -195,22 +194,8 @@ class AgentService(AgentServiceInterface):
195
194
  # Handle audio input if provided - KEEP REAL-TIME AUDIO TRANSCRIPTION
196
195
  query_text = ""
197
196
  if not isinstance(query, str):
198
- if audio_transcription_real_time and hasattr(self.llm_provider, "realtime_audio_transcription"):
199
- # Use realtime transcription for faster processing if available
200
- print("Using realtime audio transcription")
201
- async for transcript in self.llm_provider.realtime_audio_transcription(
202
- audio_generator=self._bytes_to_generator(query),
203
- transcription_config={
204
- "input_audio_format": audio_input_format}
205
- ):
206
- query_text += transcript
207
- else:
208
- # Fall back to standard transcription
209
- print("Using standard audio transcription")
210
- async for transcript in self.llm_provider.transcribe_audio(query, input_format=audio_input_format):
211
- query_text += transcript
212
-
213
- print(f"Transcribed query: {query_text}")
197
+ async for transcript in self.llm_provider.transcribe_audio(query, input_format=audio_input_format):
198
+ query_text += transcript
214
199
  else:
215
200
  query_text = query
216
201
 
@@ -47,7 +47,6 @@ class QueryService(QueryServiceInterface):
47
47
  audio_input_format: Literal[
48
48
  "flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
49
49
  ] = "mp4",
50
- audio_transcription_real_time: bool = True,
51
50
  prompt: Optional[str] = None,
52
51
  router: Optional[RoutingServiceInterface] = None,
53
52
  ) -> AsyncGenerator[Union[str, bytes], None]: # pragma: no cover
@@ -61,7 +60,6 @@ class QueryService(QueryServiceInterface):
61
60
  audio_instructions: Audio voice instructions
62
61
  audio_output_format: Audio output format
63
62
  audio_input_format: Audio input format
64
- audio_transcription_real_time: Flag for real-time audio transcription
65
63
  prompt: Optional prompt for the agent
66
64
  router: Optional routing service for processing
67
65
 
@@ -122,7 +120,6 @@ class QueryService(QueryServiceInterface):
122
120
  audio_output_format=audio_output_format,
123
121
  audio_instructions=audio_instructions,
124
122
  prompt=prompt,
125
- audio_transcription_real_time=audio_transcription_real_time,
126
123
  ):
127
124
  yield audio_chunk
128
125
 
@@ -141,7 +138,6 @@ class QueryService(QueryServiceInterface):
141
138
  memory_context=memory_context,
142
139
  output_format="text",
143
140
  prompt=prompt,
144
- audio_transcription_real_time=audio_transcription_real_time,
145
141
  ):
146
142
  yield chunk
147
143
  full_text_response += chunk
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: solana-agent
3
- Version: 24.1.0
3
+ Version: 24.1.1
4
4
  Summary: Agentic IQ
5
5
  License: MIT
6
6
  Keywords: ai,openai,ai agents,agi
@@ -14,11 +14,9 @@ Classifier: Programming Language :: Python :: 3
14
14
  Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Programming Language :: Python :: 3.13
16
16
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
- Requires-Dist: httpx (>=0.28.1,<0.29.0)
18
17
  Requires-Dist: openai (>=1.71.0,<2.0.0)
19
18
  Requires-Dist: pydantic (>=2.11.2,<3.0.0)
20
19
  Requires-Dist: pymongo (>=4.11.3,<5.0.0)
21
- Requires-Dist: websockets (>=15.0.1,<16.0.0)
22
20
  Requires-Dist: zep-cloud (>=2.9.0,<3.0.0)
23
21
  Project-URL: Documentation, https://docs.solana-agent.com
24
22
  Project-URL: Repository, https://github.com/truemagic-coder/solana-agent
@@ -375,15 +373,6 @@ async for response in solana_agent.process("user123", audio_content, output_form
375
373
  print(response, end="")
376
374
  ```
377
375
 
378
- ### Real-Time Audio Transcription
379
-
380
- It is possible to disable real-time audio transcription responses to save on costs.
381
-
382
- ```python
383
- async for response in solana_agent.process("user123", "What is the latest news on Canada?", audio_transcription_real_time=False):
384
- print(response, end="")
385
- ```
386
-
387
376
  ## Tools
388
377
 
389
378
  Tools can be used from plugins like Solana Agent Kit (sakit) or via inline tools. Tools available via plugins integrate automatically with Solana Agent.
@@ -1,22 +1,22 @@
1
1
  solana_agent/__init__.py,sha256=ceYeUpjIitpln8YK1r0JVJU8mzG6cRPYu-HLny3d-Tw,887
2
2
  solana_agent/adapters/__init__.py,sha256=tiEEuuy0NF3ngc_tGEcRTt71zVI58v3dYY9RvMrF2Cg,204
3
- solana_agent/adapters/llm_adapter.py,sha256=LLRRIhtJcPrNd2qIAHmEsFE5YyuUg53-POoiNKIradQ,12833
3
+ solana_agent/adapters/llm_adapter.py,sha256=J4Ftsbk8Yx1cEYQXhaf7WXYDBCoA4FsE6pxOeFGvcHo,5573
4
4
  solana_agent/adapters/mongodb_adapter.py,sha256=qqEFbY_v1XGyFXBmwd5HSXSSHnA9wWo-Hm1vGEyIG0k,2718
5
5
  solana_agent/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- solana_agent/client/solana_agent.py,sha256=iIRuwOP1jChAgiP_ewW2lEOV-PE6AtVROlt-s8mBbyg,5415
6
+ solana_agent/client/solana_agent.py,sha256=M2AHloEFXEAM321je9xRdos5dXNQigQ0uYqnzXv7-iA,5208
7
7
  solana_agent/domains/__init__.py,sha256=HiC94wVPRy-QDJSSRywCRrhrFfTBeHjfi5z-QfZv46U,168
8
8
  solana_agent/domains/agent.py,sha256=WTo-pEc66V6D_35cpDE-kTsw1SJM-dtylPZ7em5em7Q,2659
9
9
  solana_agent/domains/routing.py,sha256=UDlgTjUoC9xIBVYu_dnf9-KG_bBgdEXAv_UtDOrYo0w,650
10
10
  solana_agent/factories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  solana_agent/factories/agent_factory.py,sha256=mJQb1G0-gebizZvSVHm4NAxRMB1kemm2w_BAcYlN15Y,5496
12
12
  solana_agent/interfaces/__init__.py,sha256=IQs1WIM1FeKP1-kY2FEfyhol_dB-I-VAe2rD6jrVF6k,355
13
- solana_agent/interfaces/client/client.py,sha256=ymZiJEVy966HKVTZR75MdcrTfct6MPielHKdvfCYF_g,1742
13
+ solana_agent/interfaces/client/client.py,sha256=CB8YuSsn-Lvinrb12huyIVaFpJqVDh8EHsHJi9SVXM4,1690
14
14
  solana_agent/interfaces/plugins/plugins.py,sha256=T8HPBsekmzVwfU_Rizp-vtzAeYkMlKMYD7U9d0Wjq9c,3338
15
15
  solana_agent/interfaces/providers/data_storage.py,sha256=NqGeFvAzhz9rr-liLPRNCGjooB2EIhe-EVsMmX__b0M,1658
16
16
  solana_agent/interfaces/providers/llm.py,sha256=09E6NgMcIpf_nJGgdVLjlZAF2HGHtW5EmhIbaEiylt0,1972
17
17
  solana_agent/interfaces/providers/memory.py,sha256=oNOH8WZXVW8assDigIWZAWiwkxbpDiKupxA2RB6tQvQ,1010
18
- solana_agent/interfaces/services/agent.py,sha256=KHGFjmxj0yE04VTeNa6Jpk-34OEMhDgAtzmPkpUBdRA,2165
19
- solana_agent/interfaces/services/query.py,sha256=2i-Qq4Bel5P5U1O5wWUYzYoECFwiMkNj7n0K1v1edd4,1532
18
+ solana_agent/interfaces/services/agent.py,sha256=ETAfz_VbtOgpTDIpo9tMSJnUAM5boPJXw9R7b_WEu3o,2113
19
+ solana_agent/interfaces/services/query.py,sha256=yo2JZPJSy2iwxtkUlMz0emm9u_27xNgnrAFJRHQoulQ,1480
20
20
  solana_agent/interfaces/services/routing.py,sha256=UzJC-z-Q9puTWPFGEo2_CAhIxuxP5IRnze7S66NSrsI,397
21
21
  solana_agent/plugins/__init__.py,sha256=coZdgJKq1ExOaj6qB810i3rEhbjdVlrkN76ozt_Ojgo,193
22
22
  solana_agent/plugins/manager.py,sha256=Il49hXeqvu0b02pURNNp7mY8kp9_sqpi_vJIWBW5Hc0,5044
@@ -26,10 +26,10 @@ solana_agent/plugins/tools/auto_tool.py,sha256=DgES_cZ6xKSf_HJpFINpvJxrjVlk5oeqa
26
26
  solana_agent/repositories/__init__.py,sha256=fP83w83CGzXLnSdq-C5wbw9EhWTYtqE2lQTgp46-X_4,163
27
27
  solana_agent/repositories/memory.py,sha256=75zuqAMn4YFafiLsE8RvjFNd3p5ensXbFWv6VvlhFtE,7297
28
28
  solana_agent/services/__init__.py,sha256=ab_NXJmwYUCmCrCzuTlZ47bJZINW0Y0F5jfQ9OovidU,163
29
- solana_agent/services/agent.py,sha256=d6Sv6W6Vtuhf5JHknUchjAD8XSUOkXALkIImnre93j8,25524
30
- solana_agent/services/query.py,sha256=vWopHKES-K0KpxPCSZNyunRJrkBVGGQC13awd0Sd56M,11450
29
+ solana_agent/services/agent.py,sha256=9hL3j6efi8XfA3Xn7X1UB1eaQ1Ic_Og2mrYqjetHtYI,24646
30
+ solana_agent/services/query.py,sha256=IFEWYfkDCbp8W0FDooAor_UZe7H1cqgrud-CzoGlu-8,11154
31
31
  solana_agent/services/routing.py,sha256=PMCSG5m3uLMaHMj3dxNvNfcFZaeaDi7kMr7AEBCzwDE,6499
32
- solana_agent-24.1.0.dist-info/LICENSE,sha256=BnSRc-NSFuyF2s496l_4EyrwAP6YimvxWcjPiJ0J7g4,1057
33
- solana_agent-24.1.0.dist-info/METADATA,sha256=WC9LoaQVgFHhA0bfXC_c57iYU7V-ZW1TJVDrCbmUmh0,20685
34
- solana_agent-24.1.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
35
- solana_agent-24.1.0.dist-info/RECORD,,
32
+ solana_agent-24.1.1.dist-info/LICENSE,sha256=BnSRc-NSFuyF2s496l_4EyrwAP6YimvxWcjPiJ0J7g4,1057
33
+ solana_agent-24.1.1.dist-info/METADATA,sha256=zUuJR_cjSUaG5lSi1hDtI4veShusbIrqzGlUYMxXRmw,20307
34
+ solana_agent-24.1.1.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
35
+ solana_agent-24.1.1.dist-info/RECORD,,