solana-agent 24.1.2__py3-none-any.whl → 25.0.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.
- solana_agent/adapters/llm_adapter.py +89 -11
- solana_agent/factories/agent_factory.py +32 -12
- solana_agent/interfaces/providers/llm.py +9 -1
- solana_agent/interfaces/services/agent.py +0 -3
- solana_agent/services/agent.py +15 -14
- solana_agent/services/query.py +1 -2
- solana_agent/services/routing.py +9 -0
- {solana_agent-24.1.2.dist-info → solana_agent-25.0.1.dist-info}/METADATA +31 -60
- {solana_agent-24.1.2.dist-info → solana_agent-25.0.1.dist-info}/RECORD +11 -11
- {solana_agent-24.1.2.dist-info → solana_agent-25.0.1.dist-info}/LICENSE +0 -0
- {solana_agent-24.1.2.dist-info → solana_agent-25.0.1.dist-info}/WHEEL +0 -0
@@ -3,10 +3,13 @@ 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
|
-
from
|
6
|
+
from copy import deepcopy
|
7
|
+
from typing import AsyncGenerator, Literal, Optional, Type, TypeVar
|
7
8
|
|
8
9
|
from openai import AsyncOpenAI
|
9
10
|
from pydantic import BaseModel
|
11
|
+
import instructor
|
12
|
+
from instructor import Mode
|
10
13
|
|
11
14
|
from solana_agent.interfaces.providers.llm import LLMProvider
|
12
15
|
|
@@ -103,6 +106,9 @@ class OpenAIAdapter(LLMProvider):
|
|
103
106
|
self,
|
104
107
|
prompt: str,
|
105
108
|
system_prompt: str = "",
|
109
|
+
api_key: Optional[str] = None,
|
110
|
+
base_url: Optional[str] = None,
|
111
|
+
model: Optional[str] = None,
|
106
112
|
) -> AsyncGenerator[str, None]: # pragma: no cover
|
107
113
|
"""Generate text from OpenAI models."""
|
108
114
|
messages = []
|
@@ -118,8 +124,18 @@ class OpenAIAdapter(LLMProvider):
|
|
118
124
|
"stream": True,
|
119
125
|
"model": self.text_model,
|
120
126
|
}
|
127
|
+
|
128
|
+
client = deepcopy(self.client)
|
129
|
+
|
130
|
+
if api_key and base_url:
|
131
|
+
client.api_key = api_key
|
132
|
+
client.base_url = base_url
|
133
|
+
|
134
|
+
if model:
|
135
|
+
request_params["model"] = model
|
136
|
+
|
121
137
|
try:
|
122
|
-
response = await
|
138
|
+
response = await client.chat.completions.create(**request_params)
|
123
139
|
|
124
140
|
async for chunk in response:
|
125
141
|
if chunk.choices:
|
@@ -138,21 +154,83 @@ class OpenAIAdapter(LLMProvider):
|
|
138
154
|
prompt: str,
|
139
155
|
system_prompt: str,
|
140
156
|
model_class: Type[T],
|
157
|
+
api_key: Optional[str] = None,
|
158
|
+
base_url: Optional[str] = None,
|
159
|
+
model: Optional[str] = None,
|
141
160
|
) -> T: # pragma: no cover
|
142
|
-
"""Generate structured output using Pydantic model parsing."""
|
143
|
-
messages = []
|
144
|
-
if system_prompt:
|
145
|
-
messages.append({"role": "system", "content": system_prompt})
|
161
|
+
"""Generate structured output using Pydantic model parsing with Instructor."""
|
146
162
|
|
163
|
+
messages = []
|
164
|
+
messages.append({"role": "system", "content": system_prompt})
|
147
165
|
messages.append({"role": "user", "content": prompt})
|
148
166
|
|
149
167
|
try:
|
150
|
-
|
151
|
-
|
168
|
+
if api_key and base_url:
|
169
|
+
self.client.api_key = api_key
|
170
|
+
self.client.base_url = base_url
|
171
|
+
|
172
|
+
if model:
|
173
|
+
self.parse_model = model
|
174
|
+
|
175
|
+
# Create a patched client with TOOLS_STRICT mode
|
176
|
+
patched_client = instructor.from_openai(
|
177
|
+
self.client, mode=Mode.TOOLS_STRICT)
|
178
|
+
|
179
|
+
# Use instructor's structured generation with function calling
|
180
|
+
response = await patched_client.chat.completions.create(
|
152
181
|
model=self.parse_model,
|
153
182
|
messages=messages,
|
154
|
-
|
183
|
+
response_model=model_class,
|
184
|
+
max_retries=2 # Automatically retry on validation errors
|
155
185
|
)
|
156
|
-
return
|
186
|
+
return response
|
157
187
|
except Exception as e:
|
158
|
-
print(
|
188
|
+
print(
|
189
|
+
f"Error with instructor parsing (TOOLS_STRICT mode): {e}")
|
190
|
+
|
191
|
+
try:
|
192
|
+
# First fallback: Try regular JSON mode
|
193
|
+
patched_client = instructor.from_openai(
|
194
|
+
self.client, mode=Mode.JSON)
|
195
|
+
response = await patched_client.chat.completions.create(
|
196
|
+
model=self.parse_model,
|
197
|
+
messages=messages,
|
198
|
+
response_model=model_class,
|
199
|
+
max_retries=1
|
200
|
+
)
|
201
|
+
return response
|
202
|
+
except Exception as json_error:
|
203
|
+
print(f"JSON mode fallback also failed: {json_error}")
|
204
|
+
|
205
|
+
try:
|
206
|
+
# Final fallback: Manual extraction with a detailed prompt
|
207
|
+
fallback_system_prompt = f"""
|
208
|
+
{system_prompt}
|
209
|
+
|
210
|
+
You must respond with valid JSON that can be parsed as the following Pydantic model:
|
211
|
+
{model_class.model_json_schema()}
|
212
|
+
|
213
|
+
Ensure the response contains ONLY the JSON object and nothing else.
|
214
|
+
"""
|
215
|
+
|
216
|
+
# Regular completion without instructor
|
217
|
+
completion = await self.client.chat.completions.create(
|
218
|
+
model=self.parse_model,
|
219
|
+
messages=[
|
220
|
+
{"role": "system", "content": fallback_system_prompt},
|
221
|
+
{"role": "user", "content": prompt}
|
222
|
+
],
|
223
|
+
response_format={"type": "json_object"}
|
224
|
+
)
|
225
|
+
|
226
|
+
# Extract and parse the JSON response
|
227
|
+
json_str = completion.choices[0].message.content
|
228
|
+
|
229
|
+
# Use Pydantic to parse and validate
|
230
|
+
return model_class.model_validate_json(json_str)
|
231
|
+
|
232
|
+
except Exception as fallback_error:
|
233
|
+
print(f"All fallback methods failed: {fallback_error}")
|
234
|
+
raise ValueError(
|
235
|
+
f"Failed to generate structured output: {e}. All fallbacks failed."
|
236
|
+
) from e
|
@@ -86,23 +86,43 @@ class SolanaAgentFactory:
|
|
86
86
|
zep_api_key=config["zep"].get("api_key")
|
87
87
|
)
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
89
|
+
if "gemini" in config and "api_key" in config["gemini"]:
|
90
|
+
# Create primary services
|
91
|
+
agent_service = AgentService(
|
92
|
+
llm_provider=llm_adapter,
|
93
|
+
business_mission=business_mission,
|
94
|
+
config=config,
|
95
|
+
api_key=config["gemini"]["api_key"],
|
96
|
+
base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
|
97
|
+
model="gemini-2.0-flash",
|
98
|
+
)
|
99
|
+
|
100
|
+
# Create routing service
|
101
|
+
routing_service = RoutingService(
|
102
|
+
llm_provider=llm_adapter,
|
103
|
+
agent_service=agent_service,
|
104
|
+
api_key=config["gemini"]["api_key"],
|
105
|
+
base_url="https://generativelanguage.googleapis.com/v1beta/openai/",
|
106
|
+
model="gemini-2.0-flash",
|
107
|
+
)
|
108
|
+
else:
|
109
|
+
# Create primary services
|
110
|
+
agent_service = AgentService(
|
111
|
+
llm_provider=llm_adapter,
|
112
|
+
business_mission=business_mission,
|
113
|
+
config=config,
|
114
|
+
)
|
115
|
+
|
116
|
+
# Create routing service
|
117
|
+
routing_service = RoutingService(
|
118
|
+
llm_provider=llm_adapter,
|
119
|
+
agent_service=agent_service,
|
120
|
+
)
|
95
121
|
|
96
122
|
# Debug the agent service tool registry
|
97
123
|
print(
|
98
124
|
f"Agent service tools after initialization: {agent_service.tool_registry.list_all_tools()}")
|
99
125
|
|
100
|
-
# Create routing service
|
101
|
-
routing_service = RoutingService(
|
102
|
-
llm_provider=llm_adapter,
|
103
|
-
agent_service=agent_service,
|
104
|
-
)
|
105
|
-
|
106
126
|
# Initialize plugin system
|
107
127
|
agent_service.plugin_manager = PluginManager(
|
108
128
|
config=config,
|
@@ -15,13 +15,21 @@ class LLMProvider(ABC):
|
|
15
15
|
self,
|
16
16
|
prompt: str,
|
17
17
|
system_prompt: str = "",
|
18
|
+
api_key: Optional[str] = None,
|
19
|
+
base_url: Optional[str] = None,
|
20
|
+
model: Optional[str] = None,
|
18
21
|
) -> AsyncGenerator[str, None]:
|
19
22
|
"""Generate text from the language model."""
|
20
23
|
pass
|
21
24
|
|
22
25
|
@abstractmethod
|
23
26
|
async def parse_structured_output(
|
24
|
-
self, prompt: str,
|
27
|
+
self, prompt: str,
|
28
|
+
system_prompt: str,
|
29
|
+
model_class: Type[T],
|
30
|
+
api_key: Optional[str] = None,
|
31
|
+
base_url: Optional[str] = None,
|
32
|
+
model: Optional[str] = None
|
25
33
|
) -> T:
|
26
34
|
"""Generate structured output using a specific model class."""
|
27
35
|
pass
|
@@ -30,9 +30,6 @@ class AgentService(ABC):
|
|
30
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
|
-
audio_input_format: Literal[
|
34
|
-
"flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
|
35
|
-
] = "mp4",
|
36
33
|
prompt: Optional[str] = None,
|
37
34
|
) -> AsyncGenerator[Union[str, bytes], None]:
|
38
35
|
"""Generate a response from an agent."""
|
solana_agent/services/agent.py
CHANGED
@@ -26,6 +26,9 @@ class AgentService(AgentServiceInterface):
|
|
26
26
|
llm_provider: LLMProvider,
|
27
27
|
business_mission: Optional[BusinessMission] = None,
|
28
28
|
config: Optional[Dict[str, Any]] = None,
|
29
|
+
api_key: Optional[str] = None,
|
30
|
+
base_url: Optional[str] = None,
|
31
|
+
model: Optional[str] = None,
|
29
32
|
):
|
30
33
|
"""Initialize the agent service.
|
31
34
|
|
@@ -40,6 +43,9 @@ class AgentService(AgentServiceInterface):
|
|
40
43
|
self.last_text_response = ""
|
41
44
|
self.tool_registry = ToolRegistry(config=self.config)
|
42
45
|
self.agents: List[AIAgent] = []
|
46
|
+
self.api_key = api_key
|
47
|
+
self.base_url = base_url
|
48
|
+
self.model = model
|
43
49
|
|
44
50
|
self.plugin_manager = PluginManager(
|
45
51
|
config=self.config,
|
@@ -173,9 +179,6 @@ class AgentService(AgentServiceInterface):
|
|
173
179
|
audio_instructions: str = "You speak in a friendly and helpful manner.",
|
174
180
|
audio_output_format: Literal['mp3', 'opus',
|
175
181
|
'aac', 'flac', 'wav', 'pcm'] = "aac",
|
176
|
-
audio_input_format: Literal[
|
177
|
-
"flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
|
178
|
-
] = "mp4",
|
179
182
|
prompt: Optional[str] = None,
|
180
183
|
) -> AsyncGenerator[Union[str, bytes], None]: # pragma: no cover
|
181
184
|
"""Generate a response with support for text/audio input/output."""
|
@@ -191,14 +194,6 @@ class AgentService(AgentServiceInterface):
|
|
191
194
|
return
|
192
195
|
|
193
196
|
try:
|
194
|
-
# Handle audio input if provided - KEEP REAL-TIME AUDIO TRANSCRIPTION
|
195
|
-
query_text = ""
|
196
|
-
if not isinstance(query, str):
|
197
|
-
async for transcript in self.llm_provider.transcribe_audio(query, input_format=audio_input_format):
|
198
|
-
query_text += transcript
|
199
|
-
else:
|
200
|
-
query_text = query
|
201
|
-
|
202
197
|
# Get system prompt
|
203
198
|
system_prompt = self.get_agent_system_prompt(agent_name)
|
204
199
|
|
@@ -234,10 +229,13 @@ class AgentService(AgentServiceInterface):
|
|
234
229
|
|
235
230
|
# Generate and stream response (ALWAYS use non-realtime for text generation)
|
236
231
|
print(
|
237
|
-
f"Generating response with {len(
|
232
|
+
f"Generating response with {len(query)} characters of query text")
|
238
233
|
async for chunk in self.llm_provider.generate_text(
|
239
|
-
prompt=
|
234
|
+
prompt=query,
|
240
235
|
system_prompt=tool_calling_system_prompt,
|
236
|
+
api_key=self.api_key,
|
237
|
+
base_url=self.base_url,
|
238
|
+
model=self.model,
|
241
239
|
):
|
242
240
|
# If we have pending text from the previous chunk, combine it with this chunk
|
243
241
|
if pending_chunk:
|
@@ -288,7 +286,7 @@ class AgentService(AgentServiceInterface):
|
|
288
286
|
|
289
287
|
# Create new prompt with search/tool results
|
290
288
|
# Using "Search Result" instead of "TOOL RESPONSE" to avoid model repeating "TOOL"
|
291
|
-
user_prompt = f"{
|
289
|
+
user_prompt = f"{query}\n\nSearch Result: {response_text}"
|
292
290
|
tool_system_prompt = system_prompt + \
|
293
291
|
"\n DO NOT use the tool calling format again."
|
294
292
|
|
@@ -299,6 +297,9 @@ class AgentService(AgentServiceInterface):
|
|
299
297
|
async for processed_chunk in self.llm_provider.generate_text(
|
300
298
|
prompt=user_prompt,
|
301
299
|
system_prompt=tool_system_prompt,
|
300
|
+
api_key=self.api_key,
|
301
|
+
base_url=self.base_url,
|
302
|
+
model=self.model,
|
302
303
|
):
|
303
304
|
complete_text_response += processed_chunk
|
304
305
|
yield processed_chunk
|
solana_agent/services/query.py
CHANGED
@@ -112,11 +112,10 @@ class QueryService(QueryServiceInterface):
|
|
112
112
|
async for audio_chunk in self.agent_service.generate_response(
|
113
113
|
agent_name=agent_name,
|
114
114
|
user_id=user_id,
|
115
|
-
query=
|
115
|
+
query=user_text,
|
116
116
|
memory_context=memory_context,
|
117
117
|
output_format="audio",
|
118
118
|
audio_voice=audio_voice,
|
119
|
-
audio_input_format=audio_input_format,
|
120
119
|
audio_output_format=audio_output_format,
|
121
120
|
audio_instructions=audio_instructions,
|
122
121
|
prompt=prompt,
|
solana_agent/services/routing.py
CHANGED
@@ -18,6 +18,9 @@ class RoutingService(RoutingServiceInterface):
|
|
18
18
|
self,
|
19
19
|
llm_provider: LLMProvider,
|
20
20
|
agent_service: AgentService,
|
21
|
+
api_key: Optional[str] = None,
|
22
|
+
base_url: Optional[str] = None,
|
23
|
+
model: Optional[str] = None,
|
21
24
|
):
|
22
25
|
"""Initialize the routing service.
|
23
26
|
|
@@ -27,6 +30,9 @@ class RoutingService(RoutingServiceInterface):
|
|
27
30
|
"""
|
28
31
|
self.llm_provider = llm_provider
|
29
32
|
self.agent_service = agent_service
|
33
|
+
self.api_key = api_key
|
34
|
+
self.base_url = base_url
|
35
|
+
self.model = model
|
30
36
|
|
31
37
|
async def _analyze_query(self, query: str) -> Dict[str, Any]:
|
32
38
|
"""Analyze a query to determine routing information.
|
@@ -75,6 +81,9 @@ class RoutingService(RoutingServiceInterface):
|
|
75
81
|
prompt=prompt,
|
76
82
|
system_prompt="Match user queries to the most appropriate agent based on specializations.",
|
77
83
|
model_class=QueryAnalysis,
|
84
|
+
api_key=self.api_key,
|
85
|
+
base_url=self.base_url,
|
86
|
+
model=self.model,
|
78
87
|
)
|
79
88
|
|
80
89
|
return {
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: solana-agent
|
3
|
-
Version:
|
3
|
+
Version: 25.0.1
|
4
4
|
Summary: Agentic IQ
|
5
5
|
License: MIT
|
6
6
|
Keywords: ai,openai,ai agents,agi
|
@@ -14,6 +14,7 @@ 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: instructor (>=1.7.9,<2.0.0)
|
17
18
|
Requires-Dist: openai (>=1.71.0,<2.0.0)
|
18
19
|
Requires-Dist: pydantic (>=2.11.2,<3.0.0)
|
19
20
|
Requires-Dist: pymongo (>=4.11.3,<5.0.0)
|
@@ -75,16 +76,17 @@ Build your AI business in three lines of code!
|
|
75
76
|
### Tech
|
76
77
|
|
77
78
|
* [Python](https://python.org) - Programming Language
|
78
|
-
* [OpenAI](https://openai.com) - LLM
|
79
|
+
* [OpenAI](https://openai.com) & [Gemini](https://aistudio.google.com/) - LLM Providers
|
79
80
|
* [MongoDB](https://mongodb.com) - Conversational History (optional)
|
80
81
|
* [Zep Cloud](https://getzep.com) - Conversational Memory (optional)
|
81
82
|
|
82
83
|
### LLMs
|
83
84
|
|
84
|
-
* [gpt-4o-mini](https://platform.openai.com/docs/models/gpt-4o-mini)
|
85
|
+
* [gpt-4o-mini](https://platform.openai.com/docs/models/gpt-4o-mini) or [gemini-2.0-flash](https://ai.google.dev/gemini-api/docs/models#gemini-2.0-flash)
|
85
86
|
* [gpt-4o-mini-tts](https://platform.openai.com/docs/models/gpt-4o-mini-tts)
|
86
87
|
* [gpt-4o-mini-transcribe](https://platform.openai.com/docs/models/gpt-4o-mini-transcribe)
|
87
88
|
|
89
|
+
|
88
90
|
## Installation
|
89
91
|
|
90
92
|
You can install Solana Agent using pip:
|
@@ -144,6 +146,9 @@ Keep this in mind while designing your agentic systems using Solana Agent.
|
|
144
146
|
from solana_agent import SolanaAgent
|
145
147
|
|
146
148
|
config = {
|
149
|
+
"gemini": {
|
150
|
+
"api_key": "your-gemini-api-key",
|
151
|
+
},
|
147
152
|
"openai": {
|
148
153
|
"api_key": "your-openai-api-key",
|
149
154
|
},
|
@@ -167,24 +172,15 @@ async for response in solana_agent.process("user123", "What are the latest AI de
|
|
167
172
|
print(response, end="")
|
168
173
|
```
|
169
174
|
|
170
|
-
Single Agent:
|
171
|
-
|
172
|
-
* OpenAI API calls with no tool call = 1 (agent)
|
173
|
-
|
174
|
-
* OpenAI API calls with tool call = 2 (agent, agent)
|
175
|
-
|
176
|
-
Multiple Agents:
|
177
|
-
|
178
|
-
* OpenAI API calls with no tool call = 2 (router, agent)
|
179
|
-
|
180
|
-
* OpenAI API calls with tool call = 3 (router, agent, agent)
|
181
|
-
|
182
175
|
### Audio/Audio Streaming
|
183
176
|
|
184
177
|
```python
|
185
178
|
from solana_agent import SolanaAgent
|
186
179
|
|
187
180
|
config = {
|
181
|
+
"gemini": {
|
182
|
+
"api_key": "your-gemini-api-key",
|
183
|
+
},
|
188
184
|
"openai": {
|
189
185
|
"api_key": "your-openai-api-key",
|
190
186
|
},
|
@@ -210,25 +206,15 @@ async for response in solana_agent.process("user123", audio_content, output_form
|
|
210
206
|
print(response, end="")
|
211
207
|
```
|
212
208
|
|
213
|
-
Single Agent:
|
214
|
-
|
215
|
-
* OpenAI API calls with no tool call = 3 (audio transcribe, agent, TTS)
|
216
|
-
|
217
|
-
* OpenAI API calls with tool call = 4 (audio transcribe, agent, agent, TTS)
|
218
|
-
|
219
|
-
Multiple Agents:
|
220
|
-
|
221
|
-
* OpenAI API calls with no tool call = 4 (router, audio transcribe, agent, TTS)
|
222
|
-
|
223
|
-
* OpenAI API calls with tool call = 5 (router, audio transcribe, agent, agent, TTS)
|
224
|
-
|
225
|
-
|
226
209
|
### Text/Audio Streaming
|
227
210
|
|
228
211
|
```python
|
229
212
|
from solana_agent import SolanaAgent
|
230
213
|
|
231
214
|
config = {
|
215
|
+
"gemini": {
|
216
|
+
"api_key": "your-gemini-api-key",
|
217
|
+
},
|
232
218
|
"openai": {
|
233
219
|
"api_key": "your-openai-api-key",
|
234
220
|
},
|
@@ -252,24 +238,15 @@ async for response in solana_agent.process("user123", "What is the latest news o
|
|
252
238
|
print(response, end="")
|
253
239
|
```
|
254
240
|
|
255
|
-
Single Agent:
|
256
|
-
|
257
|
-
* OpenAI API calls with no tool call = 2 (agent, TTS)
|
258
|
-
|
259
|
-
* OpenAI API calls with tool call = 3 (agent, agent, TTS)
|
260
|
-
|
261
|
-
Multiple Agents:
|
262
|
-
|
263
|
-
* OpenAI API calls with no tool call = 3 (router, agent, TTS)
|
264
|
-
|
265
|
-
* OpenAI API calls with tool call = 4 (router, agent, agent, TTS)
|
266
|
-
|
267
241
|
### Audio/Text Streaming
|
268
242
|
|
269
243
|
```python
|
270
244
|
from solana_agent import SolanaAgent
|
271
245
|
|
272
246
|
config = {
|
247
|
+
"gemini": {
|
248
|
+
"api_key": "your-gemini-api-key",
|
249
|
+
},
|
273
250
|
"openai": {
|
274
251
|
"api_key": "your-openai-api-key",
|
275
252
|
},
|
@@ -295,18 +272,6 @@ async for response in solana_agent.process("user123", audio_content, audio_input
|
|
295
272
|
print(response, end="")
|
296
273
|
```
|
297
274
|
|
298
|
-
Single Agent:
|
299
|
-
|
300
|
-
* OpenAI API calls with no tool call = 2 (audio transcribe, agent)
|
301
|
-
|
302
|
-
* OpenAI API calls with tool call = 3 (audio transcribe, agent, agent)
|
303
|
-
|
304
|
-
Multiple Agents:
|
305
|
-
|
306
|
-
* OpenAI API calls with no tool call = 3 (router, audio transcribe, agent)
|
307
|
-
|
308
|
-
* OpenAI API calls with tool call = 4 (router, audio transcribe, agent, agent)
|
309
|
-
|
310
275
|
## Optional Feature Configs
|
311
276
|
|
312
277
|
### Business Alignment
|
@@ -332,8 +297,8 @@ config = {
|
|
332
297
|
```python
|
333
298
|
config = {
|
334
299
|
"mongo": {
|
335
|
-
"connection_string": "
|
336
|
-
"database": "
|
300
|
+
"connection_string": "your-mongo-connection-string",
|
301
|
+
"database": "your-database-name"
|
337
302
|
},
|
338
303
|
}
|
339
304
|
```
|
@@ -348,12 +313,6 @@ config = {
|
|
348
313
|
}
|
349
314
|
```
|
350
315
|
|
351
|
-
API Calls:
|
352
|
-
|
353
|
-
* Zep adds 2 API calls per user query (GET and POST)
|
354
|
-
|
355
|
-
* If the Zep user and session isn't created it creates them for 2 API calls (POST)
|
356
|
-
|
357
316
|
### Customize Speech
|
358
317
|
|
359
318
|
This is an audio to audio example using the `audio_instructions` parameter.
|
@@ -390,6 +349,9 @@ Tools can be used from plugins like Solana Agent Kit (sakit) or via inline tools
|
|
390
349
|
from solana_agent import SolanaAgent
|
391
350
|
|
392
351
|
config = {
|
352
|
+
"gemini": {
|
353
|
+
"api_key": "your-gemini-api-key",
|
354
|
+
},
|
393
355
|
"openai": {
|
394
356
|
"api_key": "your-openai-api-key",
|
395
357
|
},
|
@@ -472,6 +434,9 @@ class TestTool(Tool):
|
|
472
434
|
}
|
473
435
|
|
474
436
|
config = {
|
437
|
+
"gemini": {
|
438
|
+
"api_key": "your-gemini-api-key",
|
439
|
+
},
|
475
440
|
"openai": {
|
476
441
|
"api_key": "your-openai-api-key",
|
477
442
|
},
|
@@ -511,6 +476,9 @@ This knowledge is accessible to all your AI agents.
|
|
511
476
|
from solana_agent import SolanaAgent
|
512
477
|
|
513
478
|
config = {
|
479
|
+
"gemini": {
|
480
|
+
"api_key": "your-gemini-api-key",
|
481
|
+
},
|
514
482
|
"openai": {
|
515
483
|
"api_key": "your-openai-api-key",
|
516
484
|
},
|
@@ -538,6 +506,9 @@ from solana_agent import SolanaAgent
|
|
538
506
|
from solana_agent.interfaces.services.routing import RoutingService as RoutingServiceInterface
|
539
507
|
|
540
508
|
config = {
|
509
|
+
"gemini": {
|
510
|
+
"api_key": "your-gemini-api-key",
|
511
|
+
},
|
541
512
|
"openai": {
|
542
513
|
"api_key": "your-openai-api-key",
|
543
514
|
},
|
@@ -1,6 +1,6 @@
|
|
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=Wg-rWJmWlvYFSEdto9rERs26loDGo-Ssx7lmsrFUPlU,8622
|
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
6
|
solana_agent/client/solana_agent.py,sha256=M2AHloEFXEAM321je9xRdos5dXNQigQ0uYqnzXv7-iA,5208
|
@@ -8,14 +8,14 @@ solana_agent/domains/__init__.py,sha256=HiC94wVPRy-QDJSSRywCRrhrFfTBeHjfi5z-QfZv
|
|
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
|
-
solana_agent/factories/agent_factory.py,sha256=
|
11
|
+
solana_agent/factories/agent_factory.py,sha256=mo5ggQR5I1ZCjYknv6vD1U-393WbMsTQEbM6YTb2pRA,6382
|
12
12
|
solana_agent/interfaces/__init__.py,sha256=IQs1WIM1FeKP1-kY2FEfyhol_dB-I-VAe2rD6jrVF6k,355
|
13
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
|
-
solana_agent/interfaces/providers/llm.py,sha256=
|
16
|
+
solana_agent/interfaces/providers/llm.py,sha256=DA1vPWfZPhmZuJOwD5j9VxQmXEEEmyaqKVvbphCnyds,1830
|
17
17
|
solana_agent/interfaces/providers/memory.py,sha256=oNOH8WZXVW8assDigIWZAWiwkxbpDiKupxA2RB6tQvQ,1010
|
18
|
-
solana_agent/interfaces/services/agent.py,sha256=
|
18
|
+
solana_agent/interfaces/services/agent.py,sha256=tVs2piqWVfO1JiRd58e29oP1GWgYuCzberRSfaFfH4M,1979
|
19
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
|
@@ -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=
|
30
|
-
solana_agent/services/query.py,sha256=
|
31
|
-
solana_agent/services/routing.py,sha256=
|
32
|
-
solana_agent-
|
33
|
-
solana_agent-
|
34
|
-
solana_agent-
|
35
|
-
solana_agent-
|
29
|
+
solana_agent/services/agent.py,sha256=M1Aukr9xKGP9mL0jM_JqdRdWSqG4LxF0y0PDAzE_fpY,24608
|
30
|
+
solana_agent/services/query.py,sha256=bhB6bZKWqsEf_fLXfsSC57q0CtmeDI6jUlxc9a0LGJw,11099
|
31
|
+
solana_agent/services/routing.py,sha256=hC5t98KZPHty9kMX27KcuxcmZlwjm0g59uMkR8n7k_w,6818
|
32
|
+
solana_agent-25.0.1.dist-info/LICENSE,sha256=BnSRc-NSFuyF2s496l_4EyrwAP6YimvxWcjPiJ0J7g4,1057
|
33
|
+
solana_agent-25.0.1.dist-info/METADATA,sha256=DM4HWbLFpUieN55GRvCuRRc-iBHgi2E6WijW7ve9H5s,19644
|
34
|
+
solana_agent-25.0.1.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
35
|
+
solana_agent-25.0.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|