solana-agent 22.0.1__py3-none-any.whl → 22.0.3__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.
- solana_agent/adapters/llm_adapter.py +14 -16
- solana_agent/client/solana_agent.py +2 -2
- solana_agent/interfaces/client/client.py +1 -1
- solana_agent/interfaces/providers/llm.py +1 -1
- solana_agent/interfaces/services/agent.py +1 -1
- solana_agent/interfaces/services/query.py +1 -1
- solana_agent/services/agent.py +38 -8
- solana_agent/services/query.py +4 -3
- {solana_agent-22.0.1.dist-info → solana_agent-22.0.3.dist-info}/METADATA +10 -1
- {solana_agent-22.0.1.dist-info → solana_agent-22.0.3.dist-info}/RECORD +12 -12
- {solana_agent-22.0.1.dist-info → solana_agent-22.0.3.dist-info}/LICENSE +0 -0
- {solana_agent-22.0.1.dist-info → solana_agent-22.0.3.dist-info}/WHEEL +0 -0
@@ -22,12 +22,12 @@ class OpenAIAdapter(LLMProvider):
|
|
22
22
|
self.text_model = "gpt-4o-mini"
|
23
23
|
self.internet_search_model = "gpt-4o-mini-search-preview"
|
24
24
|
self.transcription_model = "gpt-4o-mini-transcribe"
|
25
|
-
self.tts_model = "tts
|
25
|
+
self.tts_model = "gpt-4o-mini-tts"
|
26
26
|
|
27
27
|
async def tts(
|
28
28
|
self,
|
29
29
|
text: str,
|
30
|
-
instructions: str = "",
|
30
|
+
instructions: str = "You speak in a friendly and helpful manner.",
|
31
31
|
voice: Literal["alloy", "ash", "ballad", "coral", "echo",
|
32
32
|
"fable", "onyx", "nova", "sage", "shimmer"] = "nova",
|
33
33
|
response_format: Literal['mp3', 'opus',
|
@@ -45,16 +45,16 @@ class OpenAIAdapter(LLMProvider):
|
|
45
45
|
Audio bytes as they become available
|
46
46
|
"""
|
47
47
|
try:
|
48
|
-
|
48
|
+
with self.client.audio.speech.with_streaming_response.create(
|
49
49
|
model=self.tts_model,
|
50
50
|
voice=voice,
|
51
|
+
instructions=instructions,
|
51
52
|
input=text,
|
52
53
|
response_format=response_format
|
53
|
-
)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
yield chunk
|
54
|
+
) as stream:
|
55
|
+
# Stream the bytes in 16KB chunks
|
56
|
+
for chunk in stream.iter_bytes(chunk_size=1024 * 16):
|
57
|
+
yield chunk
|
58
58
|
|
59
59
|
except Exception as e:
|
60
60
|
print(f"Error in text_to_speech: {str(e)}")
|
@@ -66,7 +66,7 @@ class OpenAIAdapter(LLMProvider):
|
|
66
66
|
print(f"Error in text_to_speech: {str(e)}")
|
67
67
|
import traceback
|
68
68
|
print(traceback.format_exc())
|
69
|
-
yield
|
69
|
+
yield b"" # Return empty bytes on error
|
70
70
|
|
71
71
|
async def transcribe_audio(
|
72
72
|
self,
|
@@ -85,16 +85,14 @@ class OpenAIAdapter(LLMProvider):
|
|
85
85
|
Transcript text chunks as they become available
|
86
86
|
"""
|
87
87
|
try:
|
88
|
-
|
88
|
+
with self.client.audio.transcriptions.with_streaming_response.create(
|
89
89
|
model=self.transcription_model,
|
90
90
|
file=(f"file.{input_format}", audio_bytes),
|
91
91
|
response_format="text",
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
if hasattr(event, 'text') and event.text:
|
97
|
-
yield event.text
|
92
|
+
) as stream:
|
93
|
+
# Stream the text in 16KB chunks
|
94
|
+
for chunk in stream.iter_text(chunk_size=1024 * 16):
|
95
|
+
yield chunk
|
98
96
|
|
99
97
|
except Exception as e:
|
100
98
|
print(f"Error in transcribe_audio: {str(e)}")
|
@@ -49,7 +49,7 @@ class SolanaAgent(SolanaAgentInterface):
|
|
49
49
|
output_format: Literal["text", "audio"] = "text",
|
50
50
|
audio_voice: Literal["alloy", "ash", "ballad", "coral", "echo",
|
51
51
|
"fable", "onyx", "nova", "sage", "shimmer"] = "nova",
|
52
|
-
audio_instructions:
|
52
|
+
audio_instructions: str = "You speak in a friendly and helpful manner.",
|
53
53
|
audio_output_format: Literal['mp3', 'opus',
|
54
54
|
'aac', 'flac', 'wav', 'pcm'] = "aac",
|
55
55
|
audio_input_format: Literal[
|
@@ -66,7 +66,7 @@ class SolanaAgent(SolanaAgentInterface):
|
|
66
66
|
prompt: Optional prompt for the agent
|
67
67
|
output_format: Response format ("text" or "audio")
|
68
68
|
audio_voice: Voice to use for audio output
|
69
|
-
audio_instructions:
|
69
|
+
audio_instructions: Audio voice instructions
|
70
70
|
audio_output_format: Audio output format
|
71
71
|
audio_input_format: Audio input format
|
72
72
|
router: Optional routing service for processing
|
@@ -17,7 +17,7 @@ class SolanaAgent(ABC):
|
|
17
17
|
output_format: Literal["text", "audio"] = "text",
|
18
18
|
audio_voice: Literal["alloy", "ash", "ballad", "coral", "echo",
|
19
19
|
"fable", "onyx", "nova", "sage", "shimmer"] = "nova",
|
20
|
-
audio_instructions:
|
20
|
+
audio_instructions: str = "You speak in a friendly and helpful manner.",
|
21
21
|
audio_output_format: Literal['mp3', 'opus',
|
22
22
|
'aac', 'flac', 'wav', 'pcm'] = "aac",
|
23
23
|
audio_input_format: Literal[
|
@@ -31,7 +31,7 @@ class LLMProvider(ABC):
|
|
31
31
|
async def tts(
|
32
32
|
self,
|
33
33
|
text: str,
|
34
|
-
instructions: str = "",
|
34
|
+
instructions: str = "You speak in a friendly and helpful manner.",
|
35
35
|
voice: Literal["alloy", "ash", "ballad", "coral", "echo",
|
36
36
|
"fable", "onyx", "nova", "sage", "shimmer"] = "nova",
|
37
37
|
response_format: Literal['mp3', 'opus',
|
@@ -27,7 +27,7 @@ class AgentService(ABC):
|
|
27
27
|
output_format: Literal["text", "audio"] = "text",
|
28
28
|
audio_voice: Literal["alloy", "ash", "ballad", "coral", "echo",
|
29
29
|
"fable", "onyx", "nova", "sage", "shimmer"] = "nova",
|
30
|
-
audio_instructions:
|
30
|
+
audio_instructions: str = "You speak in a friendly and helpful manner.",
|
31
31
|
audio_output_format: Literal['mp3', 'opus',
|
32
32
|
'aac', 'flac', 'wav', 'pcm'] = "aac",
|
33
33
|
audio_input_format: Literal[
|
@@ -13,7 +13,7 @@ class QueryService(ABC):
|
|
13
13
|
output_format: Literal["text", "audio"] = "text",
|
14
14
|
audio_voice: Literal["alloy", "ash", "ballad", "coral", "echo",
|
15
15
|
"fable", "onyx", "nova", "sage", "shimmer"] = "nova",
|
16
|
-
audio_instructions:
|
16
|
+
audio_instructions: str = "You speak in a friendly and helpful manner.",
|
17
17
|
audio_output_format: Literal['mp3', 'opus',
|
18
18
|
'aac', 'flac', 'wav', 'pcm'] = "aac",
|
19
19
|
audio_input_format: Literal[
|
solana_agent/services/agent.py
CHANGED
@@ -169,7 +169,7 @@ class AgentService(AgentServiceInterface):
|
|
169
169
|
output_format: Literal["text", "audio"] = "text",
|
170
170
|
audio_voice: Literal["alloy", "ash", "ballad", "coral", "echo",
|
171
171
|
"fable", "onyx", "nova", "sage", "shimmer"] = "nova",
|
172
|
-
audio_instructions:
|
172
|
+
audio_instructions: str = "You speak in a friendly and helpful manner.",
|
173
173
|
audio_output_format: Literal['mp3', 'opus',
|
174
174
|
'aac', 'flac', 'wav', 'pcm'] = "aac",
|
175
175
|
audio_input_format: Literal[
|
@@ -276,7 +276,7 @@ class AgentService(AgentServiceInterface):
|
|
276
276
|
tool_response += processed_chunk
|
277
277
|
|
278
278
|
# Add to our complete text record and full audio buffer
|
279
|
-
tool_response = self.
|
279
|
+
tool_response = self._clean_for_audio(
|
280
280
|
tool_response)
|
281
281
|
complete_text_response += tool_response
|
282
282
|
full_response_buffer += tool_response
|
@@ -318,8 +318,8 @@ class AgentService(AgentServiceInterface):
|
|
318
318
|
|
319
319
|
# For audio output, now process the complete response
|
320
320
|
if output_format == "audio" and full_response_buffer:
|
321
|
-
# Clean
|
322
|
-
full_response_buffer = self.
|
321
|
+
# Clean text before TTS
|
322
|
+
full_response_buffer = self._clean_for_audio(
|
323
323
|
full_response_buffer)
|
324
324
|
|
325
325
|
# Process the entire response with TTS
|
@@ -427,14 +427,14 @@ class AgentService(AgentServiceInterface):
|
|
427
427
|
- Use exact tool names as shown in AVAILABLE TOOLS
|
428
428
|
"""
|
429
429
|
|
430
|
-
def
|
431
|
-
"""Remove Markdown formatting and
|
430
|
+
def _clean_for_audio(self, text: str) -> str:
|
431
|
+
"""Remove Markdown formatting, emojis, and non-pronounceable characters from text.
|
432
432
|
|
433
433
|
Args:
|
434
|
-
text: Input text with potential Markdown formatting
|
434
|
+
text: Input text with potential Markdown formatting and special characters
|
435
435
|
|
436
436
|
Returns:
|
437
|
-
Clean text without Markdown
|
437
|
+
Clean text without Markdown, emojis, and special characters
|
438
438
|
"""
|
439
439
|
import re
|
440
440
|
|
@@ -469,4 +469,34 @@ class AgentService(AgentServiceInterface):
|
|
469
469
|
# Remove multiple consecutive newlines (keep just one)
|
470
470
|
text = re.sub(r'\n{3,}', '\n\n', text)
|
471
471
|
|
472
|
+
# Remove emojis and other non-pronounceable characters
|
473
|
+
# Common emoji Unicode ranges
|
474
|
+
emoji_pattern = re.compile(
|
475
|
+
"["
|
476
|
+
"\U0001F600-\U0001F64F" # emoticons
|
477
|
+
"\U0001F300-\U0001F5FF" # symbols & pictographs
|
478
|
+
"\U0001F680-\U0001F6FF" # transport & map symbols
|
479
|
+
"\U0001F700-\U0001F77F" # alchemical symbols
|
480
|
+
"\U0001F780-\U0001F7FF" # Geometric Shapes
|
481
|
+
"\U0001F800-\U0001F8FF" # Supplemental Arrows-C
|
482
|
+
"\U0001F900-\U0001F9FF" # Supplemental Symbols and Pictographs
|
483
|
+
"\U0001FA00-\U0001FA6F" # Chess Symbols
|
484
|
+
"\U0001FA70-\U0001FAFF" # Symbols and Pictographs Extended-A
|
485
|
+
"\U00002702-\U000027B0" # Dingbats
|
486
|
+
"\U000024C2-\U0000257F" # Enclosed characters
|
487
|
+
"\U00002600-\U000026FF" # Miscellaneous Symbols
|
488
|
+
"\U00002700-\U000027BF" # Dingbats
|
489
|
+
"\U0000FE00-\U0000FE0F" # Variation Selectors
|
490
|
+
"\U0001F1E0-\U0001F1FF" # Flags (iOS)
|
491
|
+
"]+",
|
492
|
+
flags=re.UNICODE
|
493
|
+
)
|
494
|
+
text = emoji_pattern.sub(r' ', text)
|
495
|
+
|
496
|
+
# Replace special characters that can cause issues with TTS
|
497
|
+
text = re.sub(r'[^\w\s\.\,\;\:\?\!\'\"\-\(\)]', ' ', text)
|
498
|
+
|
499
|
+
# Replace multiple spaces with a single space
|
500
|
+
text = re.sub(r'\s+', ' ', text)
|
501
|
+
|
472
502
|
return text.strip()
|
solana_agent/services/query.py
CHANGED
@@ -41,7 +41,7 @@ class QueryService(QueryServiceInterface):
|
|
41
41
|
output_format: Literal["text", "audio"] = "text",
|
42
42
|
audio_voice: Literal["alloy", "ash", "ballad", "coral", "echo",
|
43
43
|
"fable", "onyx", "nova", "sage", "shimmer"] = "nova",
|
44
|
-
audio_instructions:
|
44
|
+
audio_instructions: str = "You speak in a friendly and helpful manner.",
|
45
45
|
audio_output_format: Literal['mp3', 'opus',
|
46
46
|
'aac', 'flac', 'wav', 'pcm'] = "aac",
|
47
47
|
audio_input_format: Literal[
|
@@ -58,7 +58,7 @@ class QueryService(QueryServiceInterface):
|
|
58
58
|
query: Text query or audio bytes
|
59
59
|
output_format: Response format ("text" or "audio")
|
60
60
|
audio_voice: Voice for TTS (text-to-speech)
|
61
|
-
audio_instructions:
|
61
|
+
audio_instructions: Audio voice instructions
|
62
62
|
audio_output_format: Audio output format
|
63
63
|
audio_input_format: Audio input format
|
64
64
|
prompt: Optional prompt for the agent
|
@@ -84,7 +84,8 @@ class QueryService(QueryServiceInterface):
|
|
84
84
|
async for chunk in self.agent_service.llm_provider.tts(
|
85
85
|
text=response,
|
86
86
|
voice=audio_voice,
|
87
|
-
response_format=audio_output_format
|
87
|
+
response_format=audio_output_format,
|
88
|
+
instructions=audio_instructions,
|
88
89
|
):
|
89
90
|
yield chunk
|
90
91
|
else:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: solana-agent
|
3
|
-
Version: 22.0.
|
3
|
+
Version: 22.0.3
|
4
4
|
Summary: Agentic IQ
|
5
5
|
License: MIT
|
6
6
|
Keywords: ai,openai,ai agents,agi
|
@@ -249,6 +249,15 @@ async for response in solana_agent.process("user123", "Write me a poem.", intern
|
|
249
249
|
print(response, end="")
|
250
250
|
```
|
251
251
|
|
252
|
+
### Customize Audio Voice
|
253
|
+
|
254
|
+
This is an audio to audio example using the `audio_instructions` parameter.
|
255
|
+
|
256
|
+
```python
|
257
|
+
async for response in solana_agent.process("user123", audio_content, output_format="audio", audio_voice="nova", audio_input_format="webm", audio_output_format="aac", audio_instructions="You speak with an American southern accent"):
|
258
|
+
print(response, end="")
|
259
|
+
```
|
260
|
+
|
252
261
|
## Tools
|
253
262
|
|
254
263
|
Tools can be used from plugins like Solana Agent Kit (sakit) or via custom 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=
|
3
|
+
solana_agent/adapters/llm_adapter.py,sha256=ReCVQH0X0hf5NpLqEMESft5LZtPj3gDNIOBiZpClqzo,5737
|
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
|
6
|
+
solana_agent/client/solana_agent.py,sha256=-bIVaE5p6He4d5VRzYhlAgkMzhql4EVFsujjnoweh2o,5355
|
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=
|
13
|
+
solana_agent/interfaces/client/client.py,sha256=btAt-bVVxsunA6rcbn0jqVmZ1JMxcF_u95CIXByO7fk,1728
|
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
|
-
solana_agent/interfaces/providers/llm.py,sha256=
|
16
|
+
solana_agent/interfaces/providers/llm.py,sha256=_sbgSs3Sy1QAeFCB_jzw_Rjpq-N5wBY5qt6tmFYD9K4,1591
|
17
17
|
solana_agent/interfaces/providers/memory.py,sha256=oNOH8WZXVW8assDigIWZAWiwkxbpDiKupxA2RB6tQvQ,1010
|
18
|
-
solana_agent/interfaces/services/agent.py,sha256=
|
19
|
-
solana_agent/interfaces/services/query.py,sha256=
|
18
|
+
solana_agent/interfaces/services/agent.py,sha256=mvXl5JLiJJz0ajjVuntR-Sz8geRGs9RVqOEBsf8VzzE,2151
|
19
|
+
solana_agent/interfaces/services/query.py,sha256=rKIYjHBeOaFFawFYduJbMRp7imYg-uRElZoizBgua00,1378
|
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=mrpmNSQ0D_eLebNY-cBqtecVVpIGXE7s9jCzOWEAuR4,6984
|
28
28
|
solana_agent/services/__init__.py,sha256=ab_NXJmwYUCmCrCzuTlZ47bJZINW0Y0F5jfQ9OovidU,163
|
29
|
-
solana_agent/services/agent.py,sha256=
|
30
|
-
solana_agent/services/query.py,sha256=
|
29
|
+
solana_agent/services/agent.py,sha256=ODHI66S2Y65lHrE6Kbe0zNORiz16oaMNGT3x6NoKDKo,19909
|
30
|
+
solana_agent/services/query.py,sha256=os_LRkDIwXQuWW_zJMtm__n0Lvi-AvItdanpCs1bXv0,11362
|
31
31
|
solana_agent/services/routing.py,sha256=PMCSG5m3uLMaHMj3dxNvNfcFZaeaDi7kMr7AEBCzwDE,6499
|
32
|
-
solana_agent-22.0.
|
33
|
-
solana_agent-22.0.
|
34
|
-
solana_agent-22.0.
|
35
|
-
solana_agent-22.0.
|
32
|
+
solana_agent-22.0.3.dist-info/LICENSE,sha256=BnSRc-NSFuyF2s496l_4EyrwAP6YimvxWcjPiJ0J7g4,1057
|
33
|
+
solana_agent-22.0.3.dist-info/METADATA,sha256=njD8XhVplqd_P6MtEvMHk88WvXQf7rs2nGuMyq0p4-M,14882
|
34
|
+
solana_agent-22.0.3.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
35
|
+
solana_agent-22.0.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|