solana-agent 20.1.2__py3-none-any.whl → 31.4.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.
- solana_agent/__init__.py +10 -5
- solana_agent/adapters/ffmpeg_transcoder.py +375 -0
- solana_agent/adapters/mongodb_adapter.py +15 -2
- solana_agent/adapters/openai_adapter.py +679 -0
- solana_agent/adapters/openai_realtime_ws.py +1813 -0
- solana_agent/adapters/pinecone_adapter.py +543 -0
- solana_agent/cli.py +128 -0
- solana_agent/client/solana_agent.py +180 -20
- solana_agent/domains/agent.py +13 -13
- solana_agent/domains/routing.py +18 -8
- solana_agent/factories/agent_factory.py +239 -38
- solana_agent/guardrails/pii.py +107 -0
- solana_agent/interfaces/client/client.py +95 -12
- solana_agent/interfaces/guardrails/guardrails.py +26 -0
- solana_agent/interfaces/plugins/plugins.py +2 -1
- solana_agent/interfaces/providers/__init__.py +0 -0
- solana_agent/interfaces/providers/audio.py +40 -0
- solana_agent/interfaces/providers/data_storage.py +9 -2
- solana_agent/interfaces/providers/llm.py +86 -9
- solana_agent/interfaces/providers/memory.py +13 -1
- solana_agent/interfaces/providers/realtime.py +212 -0
- solana_agent/interfaces/providers/vector_storage.py +53 -0
- solana_agent/interfaces/services/agent.py +27 -12
- solana_agent/interfaces/services/knowledge_base.py +59 -0
- solana_agent/interfaces/services/query.py +41 -8
- solana_agent/interfaces/services/routing.py +0 -1
- solana_agent/plugins/manager.py +37 -16
- solana_agent/plugins/registry.py +34 -19
- solana_agent/plugins/tools/__init__.py +0 -5
- solana_agent/plugins/tools/auto_tool.py +1 -0
- solana_agent/repositories/memory.py +332 -111
- solana_agent/services/__init__.py +1 -1
- solana_agent/services/agent.py +390 -241
- solana_agent/services/knowledge_base.py +768 -0
- solana_agent/services/query.py +1858 -153
- solana_agent/services/realtime.py +626 -0
- solana_agent/services/routing.py +104 -51
- solana_agent-31.4.0.dist-info/METADATA +1070 -0
- solana_agent-31.4.0.dist-info/RECORD +49 -0
- {solana_agent-20.1.2.dist-info → solana_agent-31.4.0.dist-info}/WHEEL +1 -1
- solana_agent-31.4.0.dist-info/entry_points.txt +3 -0
- solana_agent/adapters/llm_adapter.py +0 -160
- solana_agent-20.1.2.dist-info/METADATA +0 -464
- solana_agent-20.1.2.dist-info/RECORD +0 -35
- {solana_agent-20.1.2.dist-info → solana_agent-31.4.0.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
solana_agent/__init__.py,sha256=iu0PnSAEZ6qzzHFVu7WVCQVbeCZmiZ6axUDDgWRn1j4,1070
|
|
2
|
+
solana_agent/adapters/__init__.py,sha256=tiEEuuy0NF3ngc_tGEcRTt71zVI58v3dYY9RvMrF2Cg,204
|
|
3
|
+
solana_agent/adapters/ffmpeg_transcoder.py,sha256=d2T6hDBZe_beLkZTJiWSKeeOB47U12-dF4o4PXehnKU,12166
|
|
4
|
+
solana_agent/adapters/mongodb_adapter.py,sha256=Hq3S8VzfLmnPjV40z8yJXGqUamOJcX5GbOMd-1nNWO4,3175
|
|
5
|
+
solana_agent/adapters/openai_adapter.py,sha256=vesYtOdMhGR2Q_kQ2GpJ8PHJzL1UYFYACkHr91GMSkA,27867
|
|
6
|
+
solana_agent/adapters/openai_realtime_ws.py,sha256=z9iJOmAw9skKqrO9d4fvCYl7ZPR-KVBhlYclBrMqQxI,84343
|
|
7
|
+
solana_agent/adapters/pinecone_adapter.py,sha256=XlfOpoKHwzpaU4KZnovO2TnEYbsw-3B53ZKQDtBeDgU,23847
|
|
8
|
+
solana_agent/cli.py,sha256=FGvTIQmKLp6XsQdyKtuhIIfbBtMmcCCXfigNrj4bzMc,4704
|
|
9
|
+
solana_agent/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
solana_agent/client/solana_agent.py,sha256=MXqoIS5oD9tSdMj76Dqh0__YUqlYoqgkScDE7iYQkjM,10666
|
|
11
|
+
solana_agent/domains/__init__.py,sha256=HiC94wVPRy-QDJSSRywCRrhrFfTBeHjfi5z-QfZv46U,168
|
|
12
|
+
solana_agent/domains/agent.py,sha256=8pAi1-kIgzFNANt3dyQjw-1zbThcNdpEllbAGWi79uI,2841
|
|
13
|
+
solana_agent/domains/routing.py,sha256=rb7YyeH4CJmjtuoBMk7f8kUFddcT5tUBZ9Bj8mJ4VV8,845
|
|
14
|
+
solana_agent/factories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
+
solana_agent/factories/agent_factory.py,sha256=fgRa-mnMlNWYMC8jLEkeaa1hUcjT2u8e-5ICXZHtKm4,15364
|
|
16
|
+
solana_agent/guardrails/pii.py,sha256=FCz1IC3mmkr41QFFf5NaC0fwJrVkwFsxgyOCS2POO5I,4428
|
|
17
|
+
solana_agent/interfaces/__init__.py,sha256=IQs1WIM1FeKP1-kY2FEfyhol_dB-I-VAe2rD6jrVF6k,355
|
|
18
|
+
solana_agent/interfaces/client/client.py,sha256=XAp3BmY4N-RlYJHJOfGJl8PBEk9fiy0RsEDmmP7LLRk,3823
|
|
19
|
+
solana_agent/interfaces/guardrails/guardrails.py,sha256=gZCQ1FrirW-mX6s7FoYrbRs6golsp-x269kk4kQiZzc,572
|
|
20
|
+
solana_agent/interfaces/plugins/plugins.py,sha256=Rz52cWBLdotwf4kV-2mC79tRYlN29zHSu1z9-y1HVPk,3329
|
|
21
|
+
solana_agent/interfaces/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
solana_agent/interfaces/providers/audio.py,sha256=CescIuGBEUQZ4XRyxb_1VYrO9x3Q80ilp-sxpYpxAyQ,1213
|
|
23
|
+
solana_agent/interfaces/providers/data_storage.py,sha256=Y92Cq8BtC55VlsYLD7bo3ofqQabNnlg7Q4H1Q6CDsLU,1713
|
|
24
|
+
solana_agent/interfaces/providers/llm.py,sha256=EnOfGH4bjg_EjTP6dUxxcdvKFn3NKfcpVyATUlJuARA,3563
|
|
25
|
+
solana_agent/interfaces/providers/memory.py,sha256=28X1LeS-bEac4yoIXdRPyuRU91oW9Kdt2NZtDmwSTxM,1360
|
|
26
|
+
solana_agent/interfaces/providers/realtime.py,sha256=gbNKuTyfB5L1zbKhxAJaD8QiSaRr__0Xe0mvgrwpxkk,6557
|
|
27
|
+
solana_agent/interfaces/providers/vector_storage.py,sha256=XPYzvoWrlDVFCS9ItBmoqCFWXXWNYY-d9I7_pvP7YYk,1561
|
|
28
|
+
solana_agent/interfaces/services/agent.py,sha256=Hz3ldNb0NDMp8Rm9E3GM0L3kMAO3XLJ6U2HAh6gdPeU,2176
|
|
29
|
+
solana_agent/interfaces/services/knowledge_base.py,sha256=Mu8lCGFXPmI_IW5LRGti7octLoWZIg4k5PmGwPfe7LQ,1479
|
|
30
|
+
solana_agent/interfaces/services/query.py,sha256=M_sq9TZl3tzXUe6Yz3RcCqinJStVGbmHsAOnIqgzUaM,2177
|
|
31
|
+
solana_agent/interfaces/services/routing.py,sha256=Qbn3-DQGVSQKaegHDekSFmn_XCklA0H2f0XUx9-o3wA,367
|
|
32
|
+
solana_agent/plugins/__init__.py,sha256=coZdgJKq1ExOaj6qB810i3rEhbjdVlrkN76ozt_Ojgo,193
|
|
33
|
+
solana_agent/plugins/manager.py,sha256=mO_dKSVJ8GToD3wZflMcpKDEBXRoaaMRtY267HENCI0,5542
|
|
34
|
+
solana_agent/plugins/registry.py,sha256=VAG0BWdUUIsEE-VpATtHi8qat7ziPuh7pKuzGXauwgc,4173
|
|
35
|
+
solana_agent/plugins/tools/__init__.py,sha256=VDjJxvUjefIy10VztQ9WDKgIegvDbIXBQWsHLhxdZ3o,125
|
|
36
|
+
solana_agent/plugins/tools/auto_tool.py,sha256=uihijtlc9CCqCIaRcwPuuN7o1SHIpWL2GV3vr33GG3E,1576
|
|
37
|
+
solana_agent/repositories/__init__.py,sha256=fP83w83CGzXLnSdq-C5wbw9EhWTYtqE2lQTgp46-X_4,163
|
|
38
|
+
solana_agent/repositories/memory.py,sha256=cipt9eC5YApi8ozFXAV5xq7QxQJExJmVdgGjkBjHwF0,17279
|
|
39
|
+
solana_agent/services/__init__.py,sha256=iko0c2MlF8b_SA_nuBGFllr2E3g_JowOrOzGcnU9tkA,162
|
|
40
|
+
solana_agent/services/agent.py,sha256=OS_7kQ5VxR3B2Xw1Ce3IaGpeHGFuEtobVjTYtkO1slc,23219
|
|
41
|
+
solana_agent/services/knowledge_base.py,sha256=ZvOPrSmcNDgUzz4bJIQ4LeRl9vMZiK9hOfs71IpB7Bk,32735
|
|
42
|
+
solana_agent/services/query.py,sha256=YTsRHesrFqzKc5ARdBl60MN8lJNjlk_-S_AV_G7ymbk,91075
|
|
43
|
+
solana_agent/services/realtime.py,sha256=knjExZZd-a5_gvks9p2Sje9QKcAeZ_1oaLiREKFmsc0,25168
|
|
44
|
+
solana_agent/services/routing.py,sha256=wT8XctVrbR5UoZhUSGX_H68XucpCr3KG71SVElWE3CQ,9114
|
|
45
|
+
solana_agent-31.4.0.dist-info/METADATA,sha256=-k8dmQdeSLwb80fl6dhzkurC5nD1rBQuBlHHv14P-54,37027
|
|
46
|
+
solana_agent-31.4.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
47
|
+
solana_agent-31.4.0.dist-info/entry_points.txt,sha256=-AuT_mfqk8dlZ0pHuAjx1ouAWpTRjpqvEUa6YV3lmc0,53
|
|
48
|
+
solana_agent-31.4.0.dist-info/licenses/LICENSE,sha256=BnSRc-NSFuyF2s496l_4EyrwAP6YimvxWcjPiJ0J7g4,1057
|
|
49
|
+
solana_agent-31.4.0.dist-info/RECORD,,
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
LLM provider adapters for the Solana Agent system.
|
|
3
|
-
|
|
4
|
-
These adapters implement the LLMProvider interface for different LLM services.
|
|
5
|
-
"""
|
|
6
|
-
from typing import AsyncGenerator, List, Literal, Type, TypeVar, Union
|
|
7
|
-
|
|
8
|
-
from openai import OpenAI
|
|
9
|
-
from pydantic import BaseModel
|
|
10
|
-
|
|
11
|
-
from solana_agent.interfaces.providers.llm import LLMProvider
|
|
12
|
-
|
|
13
|
-
T = TypeVar('T', bound=BaseModel)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class OpenAIAdapter(LLMProvider):
|
|
17
|
-
"""OpenAI implementation of LLMProvider with web search capabilities."""
|
|
18
|
-
|
|
19
|
-
def __init__(self, api_key: str):
|
|
20
|
-
self.client = OpenAI(api_key=api_key)
|
|
21
|
-
self.parse_model = "gpt-4o-mini"
|
|
22
|
-
self.text_model = "gpt-4o-mini"
|
|
23
|
-
self.transcription_model = "gpt-4o-mini-transcribe"
|
|
24
|
-
self.tts_model = "tts-1"
|
|
25
|
-
|
|
26
|
-
async def tts(
|
|
27
|
-
self,
|
|
28
|
-
text: str,
|
|
29
|
-
instructions: str = "",
|
|
30
|
-
voice: Literal["alloy", "ash", "ballad", "coral", "echo",
|
|
31
|
-
"fable", "onyx", "nova", "sage", "shimmer"] = "nova",
|
|
32
|
-
response_format: Literal['mp3', 'opus',
|
|
33
|
-
'aac', 'flac', 'wav', 'pcm'] = "aac",
|
|
34
|
-
) -> AsyncGenerator[bytes, None]: # pragma: no cover
|
|
35
|
-
"""Stream text-to-speech audio from OpenAI models.
|
|
36
|
-
|
|
37
|
-
Args:
|
|
38
|
-
text: Text to convert to speech
|
|
39
|
-
instructions: Optional instructions for speech generation
|
|
40
|
-
voice: Voice to use for synthesis
|
|
41
|
-
response_format: Audio format
|
|
42
|
-
|
|
43
|
-
Yields:
|
|
44
|
-
Audio bytes as they become available
|
|
45
|
-
"""
|
|
46
|
-
try:
|
|
47
|
-
stream = self.client.audio.speech.create(
|
|
48
|
-
model=self.tts_model,
|
|
49
|
-
voice=voice,
|
|
50
|
-
input=text,
|
|
51
|
-
response_format=response_format
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
# Stream the bytes in chunks
|
|
55
|
-
for chunk in stream.iter_bytes(chunk_size=1024 * 16): # 16KB chunks
|
|
56
|
-
yield chunk
|
|
57
|
-
|
|
58
|
-
except Exception as e:
|
|
59
|
-
print(f"Error in text_to_speech: {str(e)}")
|
|
60
|
-
import traceback
|
|
61
|
-
print(traceback.format_exc())
|
|
62
|
-
yield b"" # Return empty bytes on error
|
|
63
|
-
|
|
64
|
-
except Exception as e:
|
|
65
|
-
print(f"Error in text_to_speech: {str(e)}")
|
|
66
|
-
import traceback
|
|
67
|
-
print(traceback.format_exc())
|
|
68
|
-
yield f"I apologize, but I encountered an error converting text to speech: {str(e)}"
|
|
69
|
-
|
|
70
|
-
async def transcribe_audio(
|
|
71
|
-
self,
|
|
72
|
-
audio_bytes: bytes,
|
|
73
|
-
input_format: Literal[
|
|
74
|
-
"flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
|
|
75
|
-
] = "mp4",
|
|
76
|
-
) -> AsyncGenerator[str, None]: # pragma: no cover
|
|
77
|
-
"""Stream transcription of an audio file.
|
|
78
|
-
|
|
79
|
-
Args:
|
|
80
|
-
audio_bytes: Audio file bytes
|
|
81
|
-
input_format: Format of the input audio file
|
|
82
|
-
|
|
83
|
-
Yields:
|
|
84
|
-
Transcript text chunks as they become available
|
|
85
|
-
"""
|
|
86
|
-
try:
|
|
87
|
-
stream = self.client.audio.transcriptions.create(
|
|
88
|
-
model=self.transcription_model,
|
|
89
|
-
file=(f"file.{input_format}", audio_bytes),
|
|
90
|
-
response_format="text",
|
|
91
|
-
stream=True
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
for event in stream:
|
|
95
|
-
if hasattr(event, 'text') and event.text:
|
|
96
|
-
yield event.text
|
|
97
|
-
|
|
98
|
-
except Exception as e:
|
|
99
|
-
print(f"Error in transcribe_audio: {str(e)}")
|
|
100
|
-
import traceback
|
|
101
|
-
print(traceback.format_exc())
|
|
102
|
-
yield f"I apologize, but I encountered an error transcribing the audio: {str(e)}"
|
|
103
|
-
|
|
104
|
-
async def generate_text(
|
|
105
|
-
self,
|
|
106
|
-
prompt: str,
|
|
107
|
-
system_prompt: str = "",
|
|
108
|
-
) -> AsyncGenerator[str, None]: # pragma: no cover
|
|
109
|
-
"""Generate text from OpenAI models."""
|
|
110
|
-
messages = []
|
|
111
|
-
|
|
112
|
-
if system_prompt:
|
|
113
|
-
messages.append({"role": "system", "content": system_prompt})
|
|
114
|
-
|
|
115
|
-
messages.append({"role": "user", "content": prompt})
|
|
116
|
-
|
|
117
|
-
# Prepare request parameters
|
|
118
|
-
request_params = {
|
|
119
|
-
"messages": messages,
|
|
120
|
-
"stream": True,
|
|
121
|
-
"model": self.text_model,
|
|
122
|
-
}
|
|
123
|
-
try:
|
|
124
|
-
response = self.client.chat.completions.create(**request_params)
|
|
125
|
-
|
|
126
|
-
for chunk in response:
|
|
127
|
-
if chunk.choices:
|
|
128
|
-
if chunk.choices[0].delta.content:
|
|
129
|
-
text = chunk.choices[0].delta.content
|
|
130
|
-
yield text
|
|
131
|
-
|
|
132
|
-
except Exception as e:
|
|
133
|
-
print(f"Error in generate_text: {str(e)}")
|
|
134
|
-
import traceback
|
|
135
|
-
print(traceback.format_exc())
|
|
136
|
-
yield f"I apologize, but I encountered an error: {str(e)}"
|
|
137
|
-
|
|
138
|
-
async def parse_structured_output(
|
|
139
|
-
self,
|
|
140
|
-
prompt: str,
|
|
141
|
-
system_prompt: str,
|
|
142
|
-
model_class: Type[T],
|
|
143
|
-
) -> T: # pragma: no cover
|
|
144
|
-
"""Generate structured output using Pydantic model parsing."""
|
|
145
|
-
messages = []
|
|
146
|
-
if system_prompt:
|
|
147
|
-
messages.append({"role": "system", "content": system_prompt})
|
|
148
|
-
|
|
149
|
-
messages.append({"role": "user", "content": prompt})
|
|
150
|
-
|
|
151
|
-
try:
|
|
152
|
-
# First try the beta parsing API
|
|
153
|
-
completion = self.client.beta.chat.completions.parse(
|
|
154
|
-
model=self.parse_model,
|
|
155
|
-
messages=messages,
|
|
156
|
-
response_format=model_class,
|
|
157
|
-
)
|
|
158
|
-
return completion.choices[0].message.parsed
|
|
159
|
-
except Exception as e:
|
|
160
|
-
print(f"Error with beta.parse method: {e}")
|
|
@@ -1,464 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.3
|
|
2
|
-
Name: solana-agent
|
|
3
|
-
Version: 20.1.2
|
|
4
|
-
Summary: Agentic IQ
|
|
5
|
-
License: MIT
|
|
6
|
-
Keywords: ai,openai,ai agents,agi
|
|
7
|
-
Author: Bevan Hunt
|
|
8
|
-
Author-email: bevan@bevanhunt.com
|
|
9
|
-
Requires-Python: >=3.12,<4.0
|
|
10
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
-
Classifier: Intended Audience :: Developers
|
|
12
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
-
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
-
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
17
|
-
Requires-Dist: openai (>=1.68.2,<2.0.0)
|
|
18
|
-
Requires-Dist: pydantic (>=2.11.1,<3.0.0)
|
|
19
|
-
Requires-Dist: pymongo (>=4.11.3,<5.0.0)
|
|
20
|
-
Requires-Dist: zep-cloud (>=2.8.0,<3.0.0)
|
|
21
|
-
Requires-Dist: zep-python (>=2.0.2,<3.0.0)
|
|
22
|
-
Project-URL: Documentation, https://docs.solana-agent.com
|
|
23
|
-
Project-URL: Repository, https://github.com/truemagic-coder/solana-agent
|
|
24
|
-
Description-Content-Type: text/markdown
|
|
25
|
-
|
|
26
|
-
# Solana Agent
|
|
27
|
-
|
|
28
|
-
[](https://pypi.org/project/solana-agent/)
|
|
29
|
-
[](https://pypi.org/project/solana-agent/)
|
|
30
|
-
[](https://opensource.org/licenses/MIT)
|
|
31
|
-
[](https://www.python.org/downloads/)
|
|
32
|
-
[](https://codecov.io/gh/truemagic-coder/solana-agent)
|
|
33
|
-
[](https://github.com/truemagic-coder/solana-agent/actions/workflows/ci.yml)
|
|
34
|
-
[](https://github.com/truemagic-coder/solana-agent)
|
|
35
|
-
|
|
36
|
-

|
|
37
|
-
|
|
38
|
-
## Agentic IQ
|
|
39
|
-
|
|
40
|
-
Build your AI business in three lines of code!
|
|
41
|
-
|
|
42
|
-
## Why?
|
|
43
|
-
* Three lines of code required
|
|
44
|
-
* Multi-Modal Streaming
|
|
45
|
-
* Conversational Memory & History
|
|
46
|
-
* Intelligent Routing
|
|
47
|
-
* Business Alignment
|
|
48
|
-
* Extensible Tooling
|
|
49
|
-
* Simple Business Definition
|
|
50
|
-
* Tested & Secure
|
|
51
|
-
* Built in Python
|
|
52
|
-
* Deployed by [CometHeart](https://cometheart.com) & [WalletBubbles](https://walletbubbles.com)
|
|
53
|
-
|
|
54
|
-
## Features
|
|
55
|
-
|
|
56
|
-
* Seamless text and audio streaming with real-time multi-modal processing
|
|
57
|
-
* Persistent memory that preserves context across all agent interactions
|
|
58
|
-
* Streamlined message history for all agent interactions
|
|
59
|
-
* Intelligent query routing to agents with optimal domain expertise or your own custom routing
|
|
60
|
-
* Unified value system ensuring brand-aligned agent responses
|
|
61
|
-
* Powerful tool integration using standard Python packages and/or inline classes
|
|
62
|
-
* Assigned tools are utilized by agents automatically and effectively
|
|
63
|
-
* Simple business definition using JSON
|
|
64
|
-
|
|
65
|
-
## Stack
|
|
66
|
-
|
|
67
|
-
* [Python](https://python.org) - Programming Language
|
|
68
|
-
* [OpenAI](https://openai.com) - LLMs
|
|
69
|
-
* [MongoDB](https://mongodb.com) - Conversational History (optional)
|
|
70
|
-
* [Zep](https://getzep.com) - Conversational Memory (optional)
|
|
71
|
-
|
|
72
|
-
## Installation
|
|
73
|
-
|
|
74
|
-
You can install Solana Agent using pip:
|
|
75
|
-
|
|
76
|
-
`pip install solana-agent`
|
|
77
|
-
|
|
78
|
-
## Usage
|
|
79
|
-
|
|
80
|
-
### Business Alignment Config - Optional
|
|
81
|
-
|
|
82
|
-
```python
|
|
83
|
-
config = {
|
|
84
|
-
"business": {
|
|
85
|
-
"mission": "To provide users with a one-stop shop for their queries.",
|
|
86
|
-
"values": {
|
|
87
|
-
"Friendliness": "Users must be treated fairly, openly, and with friendliness.",
|
|
88
|
-
"Ethical": "Agents must use a strong ethical framework in their interactions with users.",
|
|
89
|
-
},
|
|
90
|
-
"goals": [
|
|
91
|
-
"Empower users with great answers to their queries.",
|
|
92
|
-
],
|
|
93
|
-
"voice": "The voice of the brand is that of a research business."
|
|
94
|
-
},
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### Conversational History Config - Optional
|
|
99
|
-
|
|
100
|
-
```python
|
|
101
|
-
config = {
|
|
102
|
-
"mongo": {
|
|
103
|
-
"connection_string": "mongodb://localhost:27017",
|
|
104
|
-
"database": "solana_agent"
|
|
105
|
-
},
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### Conversational Memory Config - Optional
|
|
110
|
-
|
|
111
|
-
```python
|
|
112
|
-
config = {
|
|
113
|
-
"zep": {
|
|
114
|
-
"api_key": "your-zep-api-key",
|
|
115
|
-
"base_url": "your-zep-base-url", # not applicable if using Zep Cloud
|
|
116
|
-
},
|
|
117
|
-
}
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
### Text/Text Streaming
|
|
121
|
-
|
|
122
|
-
```python
|
|
123
|
-
from solana_agent import SolanaAgent
|
|
124
|
-
|
|
125
|
-
config = {
|
|
126
|
-
"openai": {
|
|
127
|
-
"api_key": "your-openai-api-key",
|
|
128
|
-
},
|
|
129
|
-
"agents": [
|
|
130
|
-
{
|
|
131
|
-
"name": "research_specialist",
|
|
132
|
-
"instructions": "You are an expert researcher who synthesizes complex information clearly.",
|
|
133
|
-
"specialization": "Research and knowledge synthesis",
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
"name": "customer_support",
|
|
137
|
-
"instructions": "You provide friendly, helpful customer support responses.",
|
|
138
|
-
"specialization": "Customer inquiries",
|
|
139
|
-
}
|
|
140
|
-
],
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
solana_agent = SolanaAgent(config=config)
|
|
144
|
-
|
|
145
|
-
async for response in solana_agent.process("user123", "What are the latest AI developments?"):
|
|
146
|
-
print(response, end="")
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
### Audio/Audio Streaming
|
|
150
|
-
|
|
151
|
-
```python
|
|
152
|
-
from solana_agent import SolanaAgent
|
|
153
|
-
|
|
154
|
-
config = {
|
|
155
|
-
"openai": {
|
|
156
|
-
"api_key": "your-openai-api-key",
|
|
157
|
-
},
|
|
158
|
-
"agents": [
|
|
159
|
-
{
|
|
160
|
-
"name": "research_specialist",
|
|
161
|
-
"instructions": "You are an expert researcher who synthesizes complex information clearly.",
|
|
162
|
-
"specialization": "Research and knowledge synthesis",
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
"name": "customer_support",
|
|
166
|
-
"instructions": "You provide friendly, helpful customer support responses.",
|
|
167
|
-
"specialization": "Customer inquiries",
|
|
168
|
-
}
|
|
169
|
-
],
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
solana_agent = SolanaAgent(config=config)
|
|
173
|
-
|
|
174
|
-
audio_content = audio_file.read()
|
|
175
|
-
|
|
176
|
-
async for response in solana_agent.process("user123", audio_content, output_format="audio", audio_voice="nova", audio_input_format="webm", audio_output_format="aac"):
|
|
177
|
-
print(response, end="")
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Text/Audio Streaming
|
|
181
|
-
|
|
182
|
-
```python
|
|
183
|
-
from solana_agent import SolanaAgent
|
|
184
|
-
|
|
185
|
-
config = {
|
|
186
|
-
"openai": {
|
|
187
|
-
"api_key": "your-openai-api-key",
|
|
188
|
-
},
|
|
189
|
-
"agents": [
|
|
190
|
-
{
|
|
191
|
-
"name": "research_specialist",
|
|
192
|
-
"instructions": "You are an expert researcher who synthesizes complex information clearly.",
|
|
193
|
-
"specialization": "Research and knowledge synthesis",
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
"name": "customer_support",
|
|
197
|
-
"instructions": "You provide friendly, helpful customer support responses.",
|
|
198
|
-
"specialization": "Customer inquiries",
|
|
199
|
-
}
|
|
200
|
-
],
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
solana_agent = SolanaAgent(config=config)
|
|
204
|
-
|
|
205
|
-
async for response in solana_agent.process("user123", "What is the latest news on Elon Musk?", output_format="audio", audio_voice="nova", audio_output_format="aac"):
|
|
206
|
-
print(response, end="")
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
### Audio/Text Streaming
|
|
210
|
-
|
|
211
|
-
```python
|
|
212
|
-
from solana_agent import SolanaAgent
|
|
213
|
-
|
|
214
|
-
config = {
|
|
215
|
-
"openai": {
|
|
216
|
-
"api_key": "your-openai-api-key",
|
|
217
|
-
},
|
|
218
|
-
"agents": [
|
|
219
|
-
{
|
|
220
|
-
"name": "research_specialist",
|
|
221
|
-
"instructions": "You are an expert researcher who synthesizes complex information clearly.",
|
|
222
|
-
"specialization": "Research and knowledge synthesis",
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
"name": "customer_support",
|
|
226
|
-
"instructions": "You provide friendly, helpful customer support responses.",
|
|
227
|
-
"specialization": "Customer inquiries",
|
|
228
|
-
}
|
|
229
|
-
],
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
solana_agent = SolanaAgent(config=config)
|
|
233
|
-
|
|
234
|
-
audio_content = audio_file.read()
|
|
235
|
-
|
|
236
|
-
async for response in solana_agent.process("user123", audio_content, audio_input_format="aac"):
|
|
237
|
-
print(response, end="")
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
### Plugins
|
|
241
|
-
|
|
242
|
-
Plugins like Solana Agent Kit (sakit) integrate automatically with Solana Agent.
|
|
243
|
-
|
|
244
|
-
`pip install sakit`
|
|
245
|
-
|
|
246
|
-
```python
|
|
247
|
-
from solana_agent import SolanaAgent
|
|
248
|
-
|
|
249
|
-
config = {
|
|
250
|
-
"openai": {
|
|
251
|
-
"api_key": "your-openai-api-key",
|
|
252
|
-
},
|
|
253
|
-
"tools": {
|
|
254
|
-
"search_internet": {
|
|
255
|
-
"api_key": "your-perplexity-key", # Required
|
|
256
|
-
"citations": True, # Optional, defaults to True
|
|
257
|
-
"model": "sonar" # Optional, defaults to "sonar"
|
|
258
|
-
},
|
|
259
|
-
},
|
|
260
|
-
"agents": [
|
|
261
|
-
{
|
|
262
|
-
"name": "research_specialist",
|
|
263
|
-
"instructions": "You are an expert researcher who synthesizes complex information clearly.",
|
|
264
|
-
"specialization": "Research and knowledge synthesis",
|
|
265
|
-
"tools": ["search_internet"],
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
"name": "customer_support",
|
|
269
|
-
"instructions": "You provide friendly, helpful customer support responses.",
|
|
270
|
-
"specialization": "Customer inquiries",
|
|
271
|
-
}
|
|
272
|
-
],
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
solana_agent = SolanaAgent(config=config)
|
|
276
|
-
|
|
277
|
-
async for response in solana_agent.process("user123", "What are the latest AI developments?"):
|
|
278
|
-
print(response, end="")
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
To create a plugin like Solana Agent Kit - read the [code](https://github.com/truemagic-coder/solana-agent-kit)
|
|
282
|
-
|
|
283
|
-
### Custom Inline Tools
|
|
284
|
-
|
|
285
|
-
```python
|
|
286
|
-
from solana_agent import SolanaAgent
|
|
287
|
-
from solana_agent.interfaces.plugins.plugins import Tool
|
|
288
|
-
|
|
289
|
-
class TestTool(Tool):
|
|
290
|
-
def __init__(self):
|
|
291
|
-
# your tool initialization - delete the following pass
|
|
292
|
-
pass
|
|
293
|
-
|
|
294
|
-
@property
|
|
295
|
-
def name(self) -> str:
|
|
296
|
-
return "test_function"
|
|
297
|
-
|
|
298
|
-
@property
|
|
299
|
-
def description(self) -> str:
|
|
300
|
-
return "Test function for Solana Agent"
|
|
301
|
-
|
|
302
|
-
def configure(self, config: Dict[str, Any]) -> None:
|
|
303
|
-
"""Configure with all possible API key locations."""
|
|
304
|
-
super().configure(config)
|
|
305
|
-
|
|
306
|
-
# read your config values - delete the following pass
|
|
307
|
-
pass
|
|
308
|
-
|
|
309
|
-
def get_schema(self) -> Dict[str, Any]:
|
|
310
|
-
# this is an example schema
|
|
311
|
-
return {
|
|
312
|
-
"type": "object",
|
|
313
|
-
"properties": {
|
|
314
|
-
"query": {"type": "string", "description": "Search query text"},
|
|
315
|
-
"user_id": {"type": "string", "description": "User ID for the search session"}
|
|
316
|
-
},
|
|
317
|
-
"required": ["query", "user_id"]
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
async def execute(self, **params) -> Dict[str, Any]:
|
|
321
|
-
try:
|
|
322
|
-
# your tool logic
|
|
323
|
-
result = "Your tool results"
|
|
324
|
-
|
|
325
|
-
return {
|
|
326
|
-
"status": "success",
|
|
327
|
-
"result": result,
|
|
328
|
-
}
|
|
329
|
-
except Exception as e:
|
|
330
|
-
return {
|
|
331
|
-
"status": "error",
|
|
332
|
-
"message": f"Error: {str(e)}",
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
config = {
|
|
336
|
-
"openai": {
|
|
337
|
-
"api_key": "your-openai-api-key",
|
|
338
|
-
},
|
|
339
|
-
"agents": [
|
|
340
|
-
{
|
|
341
|
-
"name": "research_specialist",
|
|
342
|
-
"instructions": "You are an expert researcher who synthesizes complex information clearly.",
|
|
343
|
-
"specialization": "Research and knowledge synthesis",
|
|
344
|
-
},
|
|
345
|
-
{
|
|
346
|
-
"name": "customer_support",
|
|
347
|
-
"instructions": "You provide friendly, helpful customer support responses.",
|
|
348
|
-
"specialization": "Customer inquiries",
|
|
349
|
-
}
|
|
350
|
-
],
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
solana_agent = SolanaAgent(config=config)
|
|
354
|
-
|
|
355
|
-
test_tool = TestTool()
|
|
356
|
-
|
|
357
|
-
solana_agent.register_tool(test_tool)
|
|
358
|
-
|
|
359
|
-
async for response in solana_agent.process("user123", "What are the latest AI developments?"):
|
|
360
|
-
print(response, end="")
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
### Custom Prompt Injection at Runtime
|
|
364
|
-
|
|
365
|
-
```python
|
|
366
|
-
from solana_agent import SolanaAgent
|
|
367
|
-
|
|
368
|
-
config = {
|
|
369
|
-
"openai": {
|
|
370
|
-
"api_key": "your-openai-api-key",
|
|
371
|
-
},
|
|
372
|
-
"agents": [
|
|
373
|
-
{
|
|
374
|
-
"name": "research_specialist",
|
|
375
|
-
"instructions": "You are an expert researcher who synthesizes complex information clearly.",
|
|
376
|
-
"specialization": "Research and knowledge synthesis",
|
|
377
|
-
},
|
|
378
|
-
{
|
|
379
|
-
"name": "customer_support",
|
|
380
|
-
"instructions": "You provide friendly, helpful customer support responses.",
|
|
381
|
-
"specialization": "Customer inquiries",
|
|
382
|
-
}
|
|
383
|
-
],
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
solana_agent = SolanaAgent(config=config)
|
|
387
|
-
|
|
388
|
-
async for response in solana_agent.process("user123", "What are the latest AI developments?", "Always end your sentences with eh?"):
|
|
389
|
-
print(response, end="")
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
### Custom Routing
|
|
393
|
-
|
|
394
|
-
```python
|
|
395
|
-
from solana_agent import SolanaAgent
|
|
396
|
-
from solana_agent.interfaces.services.routing import RoutingService as RoutingServiceInterface
|
|
397
|
-
|
|
398
|
-
config = {
|
|
399
|
-
"openai": {
|
|
400
|
-
"api_key": "your-openai-api-key",
|
|
401
|
-
},
|
|
402
|
-
"agents": [
|
|
403
|
-
{
|
|
404
|
-
"name": "research_specialist",
|
|
405
|
-
"instructions": "You are an expert researcher who synthesizes complex information clearly.",
|
|
406
|
-
"specialization": "Research and knowledge synthesis",
|
|
407
|
-
},
|
|
408
|
-
{
|
|
409
|
-
"name": "customer_support",
|
|
410
|
-
"instructions": "You provide friendly, helpful customer support responses.",
|
|
411
|
-
"specialization": "Customer inquiries",
|
|
412
|
-
}
|
|
413
|
-
],
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
class Router(RoutingServiceInterface)
|
|
417
|
-
def __init__(self):
|
|
418
|
-
# your router initialization - delete the following pass
|
|
419
|
-
pass
|
|
420
|
-
|
|
421
|
-
async def route_query(self, query: str) -> str:
|
|
422
|
-
# a simple example to route always to customer_support agent
|
|
423
|
-
return "customer_support"
|
|
424
|
-
|
|
425
|
-
router = Router()
|
|
426
|
-
|
|
427
|
-
solana_agent = SolanaAgent(config=config)
|
|
428
|
-
|
|
429
|
-
async for response in solana_agent.process("user123", "What are the latest AI developments?", router=router):
|
|
430
|
-
print(response, end="")
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
## Notes
|
|
434
|
-
* Solana Agent agents can only call one tool per response.
|
|
435
|
-
* Solana Agent agents choose the best tool for the job.
|
|
436
|
-
* Solana Agent tools do not use OpenAI function calling.
|
|
437
|
-
* Solana Agent tools are async functions.
|
|
438
|
-
|
|
439
|
-
## Local Setup
|
|
440
|
-
|
|
441
|
-
A Docker Compose and Zep Config file is available at the root of this project
|
|
442
|
-
|
|
443
|
-
## API Documentation
|
|
444
|
-
|
|
445
|
-
The official up-to-date documentation site
|
|
446
|
-
|
|
447
|
-
[Solana Agent Documentation Site](https://docs.solana-agent.com)
|
|
448
|
-
|
|
449
|
-
## Official Tools
|
|
450
|
-
|
|
451
|
-
The official collection of tools in one plugin
|
|
452
|
-
|
|
453
|
-
[Solana Agent Kit](https://github.com/truemagic-coder/solana-agent-kit)
|
|
454
|
-
|
|
455
|
-
## Example App
|
|
456
|
-
|
|
457
|
-
The official example app written in FastAPI and Next.js
|
|
458
|
-
|
|
459
|
-
[Solana Agent Example App](https://github.com/truemagic-coder/solana-agent-app)
|
|
460
|
-
|
|
461
|
-
## License
|
|
462
|
-
|
|
463
|
-
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
464
|
-
|