solana-agent 19.0.1__tar.gz → 19.1.0__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.
- {solana_agent-19.0.1 → solana_agent-19.1.0}/PKG-INFO +57 -48
- {solana_agent-19.0.1 → solana_agent-19.1.0}/README.md +54 -45
- {solana_agent-19.0.1 → solana_agent-19.1.0}/pyproject.toml +3 -3
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/adapters/llm_adapter.py +0 -13
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/client/solana_agent.py +3 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/factories/agent_factory.py +28 -6
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/interfaces/client/client.py +3 -2
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/interfaces/providers/llm.py +0 -5
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/interfaces/services/agent.py +3 -7
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/interfaces/services/query.py +1 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/repositories/memory.py +42 -31
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/services/agent.py +5 -15
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/services/query.py +11 -4
- {solana_agent-19.0.1 → solana_agent-19.1.0}/LICENSE +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/__init__.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/adapters/__init__.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/adapters/mongodb_adapter.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/client/__init__.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/domains/__init__.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/domains/agent.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/domains/routing.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/factories/__init__.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/interfaces/__init__.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/interfaces/plugins/plugins.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/interfaces/providers/data_storage.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/interfaces/providers/memory.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/interfaces/services/routing.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/plugins/__init__.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/plugins/manager.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/plugins/registry.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/plugins/tools/__init__.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/plugins/tools/auto_tool.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/repositories/__init__.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/services/__init__.py +0 -0
- {solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/services/routing.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: solana-agent
|
3
|
-
Version: 19.0
|
3
|
+
Version: 19.1.0
|
4
4
|
Summary: Agentic IQ
|
5
5
|
License: MIT
|
6
6
|
Keywords: ai,openai,ai agents,agi
|
@@ -13,8 +13,8 @@ Classifier: Programming Language :: Python :: 3.12
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.13
|
14
14
|
Classifier: Programming Language :: Python :: 3 :: Only
|
15
15
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
16
|
-
Requires-Dist: openai (>=1.
|
17
|
-
Requires-Dist: pydantic (>=2.
|
16
|
+
Requires-Dist: openai (>=1.69.0,<2.0.0)
|
17
|
+
Requires-Dist: pydantic (>=2.11.0,<3.0.0)
|
18
18
|
Requires-Dist: pymongo (>=4.11.3,<5.0.0)
|
19
19
|
Requires-Dist: zep-cloud (>=2.8.0,<3.0.0)
|
20
20
|
Requires-Dist: zep-python (>=2.0.2,<3.0.0)
|
@@ -35,41 +35,36 @@ Description-Content-Type: text/markdown
|
|
35
35
|
|
36
36
|
## Agentic IQ
|
37
37
|
|
38
|
-
|
38
|
+
Build your AI business in three lines of code!
|
39
39
|
|
40
|
-
|
41
|
-
*
|
42
|
-
*
|
40
|
+
## Why?
|
41
|
+
* Three lines of code required
|
42
|
+
* Multi-Modal Streaming
|
43
|
+
* Conversational Memory & History
|
44
|
+
* Intelligent Routing
|
45
|
+
* Business Alignment
|
46
|
+
* Extensible Tooling
|
47
|
+
* Simple Business Definition
|
48
|
+
* Tested & Secure
|
49
|
+
* Built in Python
|
50
|
+
* Deployed by [CometHeart](https://cometheart.com) & [WalletBubbles](https://walletbubbles.com)
|
43
51
|
|
44
52
|
## Features
|
45
53
|
|
46
54
|
* Seamless text and audio streaming with real-time multi-modal processing
|
47
|
-
* Persistent memory that preserves context across all agent interactions
|
55
|
+
* Persistent memory that preserves context across all agent interactions
|
56
|
+
* Streamlined message history for all agent interactions
|
48
57
|
* Intelligent query routing to agents with optimal domain expertise
|
49
58
|
* Unified value system ensuring brand-aligned agent responses
|
50
59
|
* Powerful tool integration using standard Python packages and/or inline classes
|
51
60
|
* Assigned tools are utilized by agents automatically and effectively
|
52
61
|
* Simple business definition using JSON
|
53
62
|
|
54
|
-
## Why?
|
55
|
-
* Multi-Modal Streaming
|
56
|
-
* Conversational Memory
|
57
|
-
* Intelligent Routing
|
58
|
-
* Business Alignment
|
59
|
-
* Extensible Tooling
|
60
|
-
* Simple Business Definition
|
61
|
-
* Built using OOP & SOLID in Python - the language of AI
|
62
|
-
* Batteries Included
|
63
|
-
* Small Library: ~2,000 LOC of code & ~1,200 LOC of tests
|
64
|
-
* Few Dependencies
|
65
|
-
* Well Tested
|
66
|
-
* Used in production by [CometHeart](https://cometheart.com) and [WalletBubbles](https://walletbubbles.com)
|
67
|
-
|
68
63
|
## Stack
|
69
64
|
|
70
65
|
* [Python](https://python.org) - Programming Language
|
71
66
|
* [OpenAI](https://openai.com) - LLMs
|
72
|
-
* [MongoDB](https://mongodb.com) -
|
67
|
+
* [MongoDB](https://mongodb.com) - Conversational History (optional)
|
73
68
|
* [Zep](https://getzep.com) - Conversational Memory (optional)
|
74
69
|
|
75
70
|
## Installation
|
@@ -84,7 +79,7 @@ You can install Solana Agent using pip:
|
|
84
79
|
from solana_agent import SolanaAgent
|
85
80
|
|
86
81
|
config = {
|
87
|
-
"business": {
|
82
|
+
"business": { # optional
|
88
83
|
"mission": "To provide users with a one-stop shop for their queries.",
|
89
84
|
"values": {
|
90
85
|
"Friendliness": "Users must be treated fairly, openly, and with friendliness.",
|
@@ -95,17 +90,17 @@ config = {
|
|
95
90
|
],
|
96
91
|
"voice": "The voice of the brand is that of a research business."
|
97
92
|
},
|
98
|
-
"mongo": {
|
93
|
+
"mongo": { # optional
|
99
94
|
"connection_string": "mongodb://localhost:27017",
|
100
95
|
"database": "solana_agent"
|
101
96
|
},
|
102
|
-
"openai": {
|
103
|
-
"api_key": "your-openai-api-key",
|
104
|
-
},
|
105
97
|
"zep": { # optional
|
106
98
|
"api_key": "your-zep-api-key",
|
107
99
|
"base_url": "your-zep-base-url", # not applicable if using Zep Cloud
|
108
100
|
},
|
101
|
+
"openai": {
|
102
|
+
"api_key": "your-openai-api-key",
|
103
|
+
},
|
109
104
|
"agents": [
|
110
105
|
{
|
111
106
|
"name": "research_specialist",
|
@@ -136,7 +131,7 @@ Plugins like Solana Agent Kit (sakit) integrate automatically with Solana Agent.
|
|
136
131
|
from solana_agent import SolanaAgent
|
137
132
|
|
138
133
|
config = {
|
139
|
-
"business": {
|
134
|
+
"business": { # optional
|
140
135
|
"mission": "To provide users with a one-stop shop for their queries.",
|
141
136
|
"values": {
|
142
137
|
"Friendliness": "Users must be treated fairly, openly, and with friendliness.",
|
@@ -147,23 +142,26 @@ config = {
|
|
147
142
|
],
|
148
143
|
"voice": "The voice of the brand is that of a research business."
|
149
144
|
},
|
150
|
-
"
|
145
|
+
"openai": { # optional
|
146
|
+
"api_key": "your-openai-api-key",
|
147
|
+
},
|
148
|
+
"ollama": { # optional
|
149
|
+
"url": "your-ollama-url",
|
150
|
+
},
|
151
|
+
"mongo": { # optional
|
151
152
|
"connection_string": "mongodb://localhost:27017",
|
152
153
|
"database": "solana_agent"
|
153
154
|
},
|
154
|
-
"openai": {
|
155
|
-
"api_key": "your-openai-api-key",
|
156
|
-
},
|
157
155
|
"zep": { # optional
|
158
156
|
"api_key": "your-zep-api-key",
|
159
157
|
"base_url": "your-zep-base-url", # not applicable if using Zep Cloud
|
160
158
|
},
|
161
159
|
"tools": {
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
160
|
+
"search_internet": {
|
161
|
+
"api_key": "your-perplexity-key", # Required
|
162
|
+
"citations": True, # Optional, defaults to True
|
163
|
+
"model": "sonar" # Optional, defaults to "sonar"
|
164
|
+
},
|
167
165
|
},
|
168
166
|
"agents": [
|
169
167
|
{
|
@@ -241,7 +239,7 @@ class TestTool(Tool):
|
|
241
239
|
}
|
242
240
|
|
243
241
|
config = {
|
244
|
-
"business": {
|
242
|
+
"business": { # optional
|
245
243
|
"mission": "To provide users with a one-stop shop for their queries.",
|
246
244
|
"values": {
|
247
245
|
"Friendliness": "Users must be treated fairly, openly, and with friendliness.",
|
@@ -252,13 +250,16 @@ config = {
|
|
252
250
|
],
|
253
251
|
"voice": "The voice of the brand is that of a research business."
|
254
252
|
},
|
255
|
-
"
|
253
|
+
"openai": { # optional
|
254
|
+
"api_key": "your-openai-api-key",
|
255
|
+
},
|
256
|
+
"ollama": { # optional
|
257
|
+
"url": "your-ollama-url",
|
258
|
+
},
|
259
|
+
"mongo": { # optional
|
256
260
|
"connection_string": "mongodb://localhost:27017",
|
257
261
|
"database": "solana_agent"
|
258
262
|
},
|
259
|
-
"openai": {
|
260
|
-
"api_key": "your-openai-api-key",
|
261
|
-
},
|
262
263
|
"zep": { # optional
|
263
264
|
"api_key": "your-zep-api-key",
|
264
265
|
"base_url": "your-zep-base-url", # not applicable if using Zep Cloud
|
@@ -287,24 +288,32 @@ async for response in solana_agent.process("user123", "What are the latest AI de
|
|
287
288
|
print(response, end="")
|
288
289
|
```
|
289
290
|
|
290
|
-
## Notes
|
291
|
+
## Notes
|
291
292
|
* Solana Agent agents can only call one tool per response.
|
292
293
|
* Solana Agent agents choose the best tool for the job.
|
293
294
|
* Solana Agent tools do not use OpenAI function calling.
|
294
295
|
* Solana Agent tools are async functions.
|
296
|
+
* Solana Agent will use OpenAI for audio and Ollama and for text if both config vars are set
|
297
|
+
|
298
|
+
## Local Setup
|
299
|
+
|
300
|
+
A Docker Compose and Zep Config file is available at the root of this project
|
295
301
|
|
296
302
|
## API Documentation
|
297
|
-
* Available at [Solana Agent Documentation Site](https://docs.solana-agent.com)
|
298
303
|
|
299
|
-
|
304
|
+
The official up-to-date documentation site
|
305
|
+
|
306
|
+
[Solana Agent Documentation Site](https://docs.solana-agent.com)
|
307
|
+
|
308
|
+
## Official Tools
|
300
309
|
|
301
|
-
|
310
|
+
The official collection of tools in one plugin
|
302
311
|
|
303
312
|
[Solana Agent Kit](https://github.com/truemagic-coder/solana-agent-kit)
|
304
313
|
|
305
314
|
## Example App
|
306
315
|
|
307
|
-
|
316
|
+
The official example app written in FastAPI and Next.js
|
308
317
|
|
309
318
|
[Solana Agent Example App](https://github.com/truemagic-coder/solana-agent-app)
|
310
319
|
|
@@ -12,41 +12,36 @@
|
|
12
12
|
|
13
13
|
## Agentic IQ
|
14
14
|
|
15
|
-
|
15
|
+
Build your AI business in three lines of code!
|
16
16
|
|
17
|
-
|
18
|
-
*
|
19
|
-
*
|
17
|
+
## Why?
|
18
|
+
* Three lines of code required
|
19
|
+
* Multi-Modal Streaming
|
20
|
+
* Conversational Memory & History
|
21
|
+
* Intelligent Routing
|
22
|
+
* Business Alignment
|
23
|
+
* Extensible Tooling
|
24
|
+
* Simple Business Definition
|
25
|
+
* Tested & Secure
|
26
|
+
* Built in Python
|
27
|
+
* Deployed by [CometHeart](https://cometheart.com) & [WalletBubbles](https://walletbubbles.com)
|
20
28
|
|
21
29
|
## Features
|
22
30
|
|
23
31
|
* Seamless text and audio streaming with real-time multi-modal processing
|
24
|
-
* Persistent memory that preserves context across all agent interactions
|
32
|
+
* Persistent memory that preserves context across all agent interactions
|
33
|
+
* Streamlined message history for all agent interactions
|
25
34
|
* Intelligent query routing to agents with optimal domain expertise
|
26
35
|
* Unified value system ensuring brand-aligned agent responses
|
27
36
|
* Powerful tool integration using standard Python packages and/or inline classes
|
28
37
|
* Assigned tools are utilized by agents automatically and effectively
|
29
38
|
* Simple business definition using JSON
|
30
39
|
|
31
|
-
## Why?
|
32
|
-
* Multi-Modal Streaming
|
33
|
-
* Conversational Memory
|
34
|
-
* Intelligent Routing
|
35
|
-
* Business Alignment
|
36
|
-
* Extensible Tooling
|
37
|
-
* Simple Business Definition
|
38
|
-
* Built using OOP & SOLID in Python - the language of AI
|
39
|
-
* Batteries Included
|
40
|
-
* Small Library: ~2,000 LOC of code & ~1,200 LOC of tests
|
41
|
-
* Few Dependencies
|
42
|
-
* Well Tested
|
43
|
-
* Used in production by [CometHeart](https://cometheart.com) and [WalletBubbles](https://walletbubbles.com)
|
44
|
-
|
45
40
|
## Stack
|
46
41
|
|
47
42
|
* [Python](https://python.org) - Programming Language
|
48
43
|
* [OpenAI](https://openai.com) - LLMs
|
49
|
-
* [MongoDB](https://mongodb.com) -
|
44
|
+
* [MongoDB](https://mongodb.com) - Conversational History (optional)
|
50
45
|
* [Zep](https://getzep.com) - Conversational Memory (optional)
|
51
46
|
|
52
47
|
## Installation
|
@@ -61,7 +56,7 @@ You can install Solana Agent using pip:
|
|
61
56
|
from solana_agent import SolanaAgent
|
62
57
|
|
63
58
|
config = {
|
64
|
-
"business": {
|
59
|
+
"business": { # optional
|
65
60
|
"mission": "To provide users with a one-stop shop for their queries.",
|
66
61
|
"values": {
|
67
62
|
"Friendliness": "Users must be treated fairly, openly, and with friendliness.",
|
@@ -72,17 +67,17 @@ config = {
|
|
72
67
|
],
|
73
68
|
"voice": "The voice of the brand is that of a research business."
|
74
69
|
},
|
75
|
-
"mongo": {
|
70
|
+
"mongo": { # optional
|
76
71
|
"connection_string": "mongodb://localhost:27017",
|
77
72
|
"database": "solana_agent"
|
78
73
|
},
|
79
|
-
"openai": {
|
80
|
-
"api_key": "your-openai-api-key",
|
81
|
-
},
|
82
74
|
"zep": { # optional
|
83
75
|
"api_key": "your-zep-api-key",
|
84
76
|
"base_url": "your-zep-base-url", # not applicable if using Zep Cloud
|
85
77
|
},
|
78
|
+
"openai": {
|
79
|
+
"api_key": "your-openai-api-key",
|
80
|
+
},
|
86
81
|
"agents": [
|
87
82
|
{
|
88
83
|
"name": "research_specialist",
|
@@ -113,7 +108,7 @@ Plugins like Solana Agent Kit (sakit) integrate automatically with Solana Agent.
|
|
113
108
|
from solana_agent import SolanaAgent
|
114
109
|
|
115
110
|
config = {
|
116
|
-
"business": {
|
111
|
+
"business": { # optional
|
117
112
|
"mission": "To provide users with a one-stop shop for their queries.",
|
118
113
|
"values": {
|
119
114
|
"Friendliness": "Users must be treated fairly, openly, and with friendliness.",
|
@@ -124,23 +119,26 @@ config = {
|
|
124
119
|
],
|
125
120
|
"voice": "The voice of the brand is that of a research business."
|
126
121
|
},
|
127
|
-
"
|
122
|
+
"openai": { # optional
|
123
|
+
"api_key": "your-openai-api-key",
|
124
|
+
},
|
125
|
+
"ollama": { # optional
|
126
|
+
"url": "your-ollama-url",
|
127
|
+
},
|
128
|
+
"mongo": { # optional
|
128
129
|
"connection_string": "mongodb://localhost:27017",
|
129
130
|
"database": "solana_agent"
|
130
131
|
},
|
131
|
-
"openai": {
|
132
|
-
"api_key": "your-openai-api-key",
|
133
|
-
},
|
134
132
|
"zep": { # optional
|
135
133
|
"api_key": "your-zep-api-key",
|
136
134
|
"base_url": "your-zep-base-url", # not applicable if using Zep Cloud
|
137
135
|
},
|
138
136
|
"tools": {
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
137
|
+
"search_internet": {
|
138
|
+
"api_key": "your-perplexity-key", # Required
|
139
|
+
"citations": True, # Optional, defaults to True
|
140
|
+
"model": "sonar" # Optional, defaults to "sonar"
|
141
|
+
},
|
144
142
|
},
|
145
143
|
"agents": [
|
146
144
|
{
|
@@ -218,7 +216,7 @@ class TestTool(Tool):
|
|
218
216
|
}
|
219
217
|
|
220
218
|
config = {
|
221
|
-
"business": {
|
219
|
+
"business": { # optional
|
222
220
|
"mission": "To provide users with a one-stop shop for their queries.",
|
223
221
|
"values": {
|
224
222
|
"Friendliness": "Users must be treated fairly, openly, and with friendliness.",
|
@@ -229,13 +227,16 @@ config = {
|
|
229
227
|
],
|
230
228
|
"voice": "The voice of the brand is that of a research business."
|
231
229
|
},
|
232
|
-
"
|
230
|
+
"openai": { # optional
|
231
|
+
"api_key": "your-openai-api-key",
|
232
|
+
},
|
233
|
+
"ollama": { # optional
|
234
|
+
"url": "your-ollama-url",
|
235
|
+
},
|
236
|
+
"mongo": { # optional
|
233
237
|
"connection_string": "mongodb://localhost:27017",
|
234
238
|
"database": "solana_agent"
|
235
239
|
},
|
236
|
-
"openai": {
|
237
|
-
"api_key": "your-openai-api-key",
|
238
|
-
},
|
239
240
|
"zep": { # optional
|
240
241
|
"api_key": "your-zep-api-key",
|
241
242
|
"base_url": "your-zep-base-url", # not applicable if using Zep Cloud
|
@@ -264,24 +265,32 @@ async for response in solana_agent.process("user123", "What are the latest AI de
|
|
264
265
|
print(response, end="")
|
265
266
|
```
|
266
267
|
|
267
|
-
## Notes
|
268
|
+
## Notes
|
268
269
|
* Solana Agent agents can only call one tool per response.
|
269
270
|
* Solana Agent agents choose the best tool for the job.
|
270
271
|
* Solana Agent tools do not use OpenAI function calling.
|
271
272
|
* Solana Agent tools are async functions.
|
273
|
+
* Solana Agent will use OpenAI for audio and Ollama and for text if both config vars are set
|
274
|
+
|
275
|
+
## Local Setup
|
276
|
+
|
277
|
+
A Docker Compose and Zep Config file is available at the root of this project
|
272
278
|
|
273
279
|
## API Documentation
|
274
|
-
* Available at [Solana Agent Documentation Site](https://docs.solana-agent.com)
|
275
280
|
|
276
|
-
|
281
|
+
The official up-to-date documentation site
|
282
|
+
|
283
|
+
[Solana Agent Documentation Site](https://docs.solana-agent.com)
|
284
|
+
|
285
|
+
## Official Tools
|
277
286
|
|
278
|
-
|
287
|
+
The official collection of tools in one plugin
|
279
288
|
|
280
289
|
[Solana Agent Kit](https://github.com/truemagic-coder/solana-agent-kit)
|
281
290
|
|
282
291
|
## Example App
|
283
292
|
|
284
|
-
|
293
|
+
The official example app written in FastAPI and Next.js
|
285
294
|
|
286
295
|
[Solana Agent Example App](https://github.com/truemagic-coder/solana-agent-app)
|
287
296
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "solana-agent"
|
3
|
-
version = "19.0
|
3
|
+
version = "19.1.0"
|
4
4
|
description = "Agentic IQ"
|
5
5
|
authors = ["Bevan Hunt <bevan@bevanhunt.com>"]
|
6
6
|
license = "MIT"
|
@@ -18,8 +18,8 @@ python_paths = [".", "tests"]
|
|
18
18
|
|
19
19
|
[tool.poetry.dependencies]
|
20
20
|
python = ">=3.12,<4.0"
|
21
|
-
openai = "^1.
|
22
|
-
pydantic = "^2.
|
21
|
+
openai = "^1.69.0"
|
22
|
+
pydantic = "^2.11.0"
|
23
23
|
pymongo = "^4.11.3"
|
24
24
|
zep-cloud = "^2.8.0"
|
25
25
|
zep-python = "^2.0.2"
|
@@ -135,19 +135,6 @@ class OpenAIAdapter(LLMProvider):
|
|
135
135
|
print(traceback.format_exc())
|
136
136
|
yield f"I apologize, but I encountered an error: {str(e)}"
|
137
137
|
|
138
|
-
def generate_embedding(self, text: str) -> List[float]: # pragma: no cover
|
139
|
-
"""Generate embeddings for a given text using OpenAI's embedding model."""
|
140
|
-
try:
|
141
|
-
response = self.client.embeddings.create(
|
142
|
-
model="text-embedding-3-small",
|
143
|
-
input=text
|
144
|
-
)
|
145
|
-
return response.data[0].embedding
|
146
|
-
except Exception as e:
|
147
|
-
print(f"Error generating embedding: {e}")
|
148
|
-
# Return a zero vector as fallback (not ideal but prevents crashing)
|
149
|
-
return [0.0] * 1536 # Standard size for text-embedding-3-small
|
150
|
-
|
151
138
|
async def parse_structured_output(
|
152
139
|
self,
|
153
140
|
prompt: str,
|
@@ -44,6 +44,7 @@ class SolanaAgent(SolanaAgentInterface):
|
|
44
44
|
self,
|
45
45
|
user_id: str,
|
46
46
|
message: Union[str, bytes],
|
47
|
+
prompt: Optional[str] = None,
|
47
48
|
output_format: Literal["text", "audio"] = "text",
|
48
49
|
audio_voice: Literal["alloy", "ash", "ballad", "coral", "echo",
|
49
50
|
"fable", "onyx", "nova", "sage", "shimmer"] = "nova",
|
@@ -59,6 +60,7 @@ class SolanaAgent(SolanaAgentInterface):
|
|
59
60
|
Args:
|
60
61
|
user_id: User ID
|
61
62
|
message: Text message or audio bytes
|
63
|
+
prompt: Optional prompt for the agent
|
62
64
|
output_format: Response format ("text" or "audio")
|
63
65
|
audio_voice: Voice to use for audio output
|
64
66
|
audio_instructions: Optional instructions for audio synthesis
|
@@ -76,6 +78,7 @@ class SolanaAgent(SolanaAgentInterface):
|
|
76
78
|
audio_instructions=audio_instructions,
|
77
79
|
audio_output_format=audio_output_format,
|
78
80
|
audio_input_format=audio_input_format,
|
81
|
+
prompt=prompt,
|
79
82
|
):
|
80
83
|
yield chunk
|
81
84
|
|
@@ -37,10 +37,19 @@ class SolanaAgentFactory:
|
|
37
37
|
Configured QueryService instance
|
38
38
|
"""
|
39
39
|
# Create adapters
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
|
41
|
+
if "mongo" in config:
|
42
|
+
# MongoDB connection string and database name
|
43
|
+
if "connection_string" not in config["mongo"]:
|
44
|
+
raise ValueError("MongoDB connection string is required.")
|
45
|
+
if "database" not in config["mongo"]:
|
46
|
+
raise ValueError("MongoDB database name is required.")
|
47
|
+
db_adapter = MongoDBAdapter(
|
48
|
+
connection_string=config["mongo"]["connection_string"],
|
49
|
+
database_name=config["mongo"]["database"],
|
50
|
+
)
|
51
|
+
else:
|
52
|
+
db_adapter = None
|
44
53
|
|
45
54
|
llm_adapter = OpenAIAdapter(
|
46
55
|
api_key=config["openai"]["api_key"],
|
@@ -59,12 +68,25 @@ class SolanaAgentFactory:
|
|
59
68
|
)
|
60
69
|
|
61
70
|
# Create repositories
|
62
|
-
|
71
|
+
memory_provider = None
|
72
|
+
|
73
|
+
if "zep" in config and "mongo" in config:
|
74
|
+
if "api_key" not in config["zep"]:
|
75
|
+
raise ValueError("Zep API key is required.")
|
63
76
|
memory_provider = MemoryRepository(
|
64
77
|
db_adapter, config["zep"].get("api_key"), config["zep"].get("base_url"))
|
65
|
-
|
78
|
+
|
79
|
+
if "mongo" in config and not "zep" in config:
|
66
80
|
memory_provider = MemoryRepository(db_adapter)
|
67
81
|
|
82
|
+
if "zep" in config and not "mongo" in config:
|
83
|
+
if "api_key" not in config["zep"]:
|
84
|
+
raise ValueError("Zep API key is required.")
|
85
|
+
memory_provider = MemoryRepository(
|
86
|
+
zep_api_key=config["zep"].get("api_key"),
|
87
|
+
zep_base_url=config["zep"].get("base_url")
|
88
|
+
)
|
89
|
+
|
68
90
|
# Create primary services
|
69
91
|
agent_service = AgentService(
|
70
92
|
llm_provider=llm_adapter,
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
from typing import Any, AsyncGenerator, Dict, Literal, Union
|
2
|
+
from typing import Any, AsyncGenerator, Dict, Literal, Optional, Union
|
3
3
|
|
4
4
|
from solana_agent.interfaces.plugins.plugins import Tool
|
5
5
|
|
@@ -15,12 +15,13 @@ class SolanaAgent(ABC):
|
|
15
15
|
output_format: Literal["text", "audio"] = "text",
|
16
16
|
audio_voice: Literal["alloy", "ash", "ballad", "coral", "echo",
|
17
17
|
"fable", "onyx", "nova", "sage", "shimmer"] = "nova",
|
18
|
-
audio_instructions: str = None,
|
18
|
+
audio_instructions: Optional[str] = None,
|
19
19
|
audio_output_format: Literal['mp3', 'opus',
|
20
20
|
'aac', 'flac', 'wav', 'pcm'] = "aac",
|
21
21
|
audio_input_format: Literal[
|
22
22
|
"flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
|
23
23
|
] = "mp4",
|
24
|
+
prompt: Optional[str] = None,
|
24
25
|
) -> AsyncGenerator[Union[str, bytes], None]:
|
25
26
|
"""Process a user message and return the response stream."""
|
26
27
|
pass
|
@@ -19,11 +19,6 @@ class LLMProvider(ABC):
|
|
19
19
|
"""Generate text from the language model."""
|
20
20
|
pass
|
21
21
|
|
22
|
-
@abstractmethod
|
23
|
-
def generate_embedding(self, text: str) -> List[float]:
|
24
|
-
"""Generate embedding vector for text."""
|
25
|
-
pass
|
26
|
-
|
27
22
|
@abstractmethod
|
28
23
|
async def parse_structured_output(
|
29
24
|
self, prompt: str, system_prompt: str, model_class: Type[T],
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
from typing import Any, AsyncGenerator, Dict, List, Literal, Union
|
2
|
+
from typing import Any, AsyncGenerator, Dict, List, Literal, Optional, Union
|
3
3
|
|
4
4
|
from solana_agent.domains.agent import AIAgent
|
5
5
|
|
@@ -17,11 +17,6 @@ class AgentService(ABC):
|
|
17
17
|
"""Get the system prompt for an agent."""
|
18
18
|
pass
|
19
19
|
|
20
|
-
@abstractmethod
|
21
|
-
def get_specializations(self) -> Dict[str, str]:
|
22
|
-
"""Get all registered specializations."""
|
23
|
-
pass
|
24
|
-
|
25
20
|
@abstractmethod
|
26
21
|
async def generate_response(
|
27
22
|
self,
|
@@ -32,12 +27,13 @@ class AgentService(ABC):
|
|
32
27
|
output_format: Literal["text", "audio"] = "text",
|
33
28
|
audio_voice: Literal["alloy", "ash", "ballad", "coral", "echo",
|
34
29
|
"fable", "onyx", "nova", "sage", "shimmer"] = "nova",
|
35
|
-
audio_instructions: str = None,
|
30
|
+
audio_instructions: Optional[str] = None,
|
36
31
|
audio_output_format: Literal['mp3', 'opus',
|
37
32
|
'aac', 'flac', 'wav', 'pcm'] = "aac",
|
38
33
|
audio_input_format: Literal[
|
39
34
|
"flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
|
40
35
|
] = "mp4",
|
36
|
+
prompt: Optional[str] = None,
|
41
37
|
) -> AsyncGenerator[Union[str, bytes], None]:
|
42
38
|
"""Generate a response from an agent."""
|
43
39
|
pass
|
@@ -19,6 +19,7 @@ class QueryService(ABC):
|
|
19
19
|
audio_input_format: Literal[
|
20
20
|
"flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
|
21
21
|
] = "mp4",
|
22
|
+
prompt: Optional[str] = None,
|
22
23
|
) -> AsyncGenerator[Union[str, bytes], None]:
|
23
24
|
"""Process the user request and generate a response."""
|
24
25
|
pass
|
@@ -12,19 +12,23 @@ class MemoryRepository(MemoryProvider):
|
|
12
12
|
|
13
13
|
def __init__(
|
14
14
|
self,
|
15
|
-
mongo_adapter: MongoDBAdapter,
|
15
|
+
mongo_adapter: Optional[MongoDBAdapter] = None,
|
16
16
|
zep_api_key: Optional[str] = None,
|
17
17
|
zep_base_url: Optional[str] = None
|
18
18
|
):
|
19
19
|
"""Initialize the combined memory provider."""
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
if not mongo_adapter:
|
21
|
+
self.mongo = None
|
22
|
+
self.collection = None
|
23
|
+
else:
|
24
|
+
# Initialize MongoDB
|
25
|
+
self.mongo = mongo_adapter
|
26
|
+
self.collection = "conversations"
|
23
27
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
# Ensure MongoDB collection and indexes
|
29
|
+
self.mongo.create_collection(self.collection)
|
30
|
+
self.mongo.create_index(self.collection, [("user_id", 1)])
|
31
|
+
self.mongo.create_index(self.collection, [("timestamp", 1)])
|
28
32
|
|
29
33
|
# Initialize Zep
|
30
34
|
if zep_api_key and not zep_base_url:
|
@@ -37,22 +41,23 @@ class MemoryRepository(MemoryProvider):
|
|
37
41
|
async def store(self, user_id: str, messages: List[Dict[str, Any]]) -> None:
|
38
42
|
"""Store messages in both Zep and MongoDB."""
|
39
43
|
# Store in MongoDB as single document
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
44
|
+
if self.mongo:
|
45
|
+
try:
|
46
|
+
# Extract user and assistant messages
|
47
|
+
user_message = next(msg["content"]
|
48
|
+
for msg in messages if msg["role"] == "user")
|
49
|
+
assistant_message = next(
|
50
|
+
msg["content"] for msg in messages if msg["role"] == "assistant")
|
51
|
+
|
52
|
+
doc = {
|
53
|
+
"user_id": user_id,
|
54
|
+
"user_message": user_message,
|
55
|
+
"assistant_message": assistant_message,
|
56
|
+
"timestamp": datetime.now(timezone.utc)
|
57
|
+
}
|
58
|
+
self.mongo.insert_one(self.collection, doc)
|
59
|
+
except Exception as e:
|
60
|
+
print(f"MongoDB storage error: {e}")
|
56
61
|
|
57
62
|
# Store in Zep with role-based format
|
58
63
|
if not self.zep:
|
@@ -99,13 +104,14 @@ class MemoryRepository(MemoryProvider):
|
|
99
104
|
|
100
105
|
async def delete(self, user_id: str) -> None:
|
101
106
|
"""Delete memory from both systems."""
|
102
|
-
|
103
|
-
|
104
|
-
self.
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
107
|
+
if self.mongo:
|
108
|
+
try:
|
109
|
+
self.mongo.delete_all(
|
110
|
+
self.collection,
|
111
|
+
{"user_id": user_id}
|
112
|
+
)
|
113
|
+
except Exception as e:
|
114
|
+
print(f"MongoDB deletion error: {e}")
|
109
115
|
|
110
116
|
if not self.zep:
|
111
117
|
return
|
@@ -125,9 +131,14 @@ class MemoryRepository(MemoryProvider):
|
|
125
131
|
skip: int = 0
|
126
132
|
) -> List[Dict]:
|
127
133
|
"""Find documents matching query."""
|
134
|
+
if not self.mongo:
|
135
|
+
return []
|
128
136
|
return self.mongo.find(collection, query, sort=sort, limit=limit, skip=skip)
|
129
137
|
|
130
138
|
def count_documents(self, collection: str, query: Dict) -> int:
|
139
|
+
"""Count documents matching query."""
|
140
|
+
if not self.mongo:
|
141
|
+
return 0
|
131
142
|
return self.mongo.count_documents(collection, query)
|
132
143
|
|
133
144
|
def _truncate(self, text: str, limit: int = 2500) -> str:
|
@@ -108,20 +108,6 @@ class AgentService(AgentServiceInterface):
|
|
108
108
|
"""
|
109
109
|
return {agent.name: agent for agent in self.agents}
|
110
110
|
|
111
|
-
def get_specializations(self) -> Dict[str, str]:
|
112
|
-
"""Get all registered specializations.
|
113
|
-
|
114
|
-
Returns:
|
115
|
-
Dictionary mapping specialization names to descriptions
|
116
|
-
"""
|
117
|
-
specializations = {}
|
118
|
-
|
119
|
-
for agent in self.agents:
|
120
|
-
if agent.specialization:
|
121
|
-
specializations[agent.specialization] = f"AI expertise in {agent.specialization}"
|
122
|
-
|
123
|
-
return specializations
|
124
|
-
|
125
111
|
def assign_tool_for_agent(self, agent_name: str, tool_name: str) -> bool:
|
126
112
|
"""Assign a tool to an agent.
|
127
113
|
|
@@ -187,6 +173,7 @@ class AgentService(AgentServiceInterface):
|
|
187
173
|
audio_input_format: Literal[
|
188
174
|
"flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
|
189
175
|
] = "mp4",
|
176
|
+
prompt: Optional[str] = None,
|
190
177
|
) -> AsyncGenerator[Union[str, bytes], None]: # pragma: no cover
|
191
178
|
"""Generate a response with support for text/audio input/output.
|
192
179
|
|
@@ -200,6 +187,7 @@ class AgentService(AgentServiceInterface):
|
|
200
187
|
audio_instructions: Optional instructions for audio synthesis
|
201
188
|
audio_output_format: Audio output format
|
202
189
|
audio_input_format: Audio input format
|
190
|
+
prompt: Optional prompt for the agent
|
203
191
|
|
204
192
|
Yields:
|
205
193
|
Text chunks or audio bytes depending on output_format
|
@@ -233,7 +221,9 @@ class AgentService(AgentServiceInterface):
|
|
233
221
|
# Add User ID and memory context
|
234
222
|
system_prompt += f"\n\nUser ID: {user_id}"
|
235
223
|
if memory_context:
|
236
|
-
system_prompt += f"\n\
|
224
|
+
system_prompt += f"\n\nMEMORY CONTEXT: {memory_context}"
|
225
|
+
if prompt:
|
226
|
+
system_prompt += f"\n\nADDITIONAL PROMPT: {prompt}"
|
237
227
|
|
238
228
|
# Keep track of the complete text response
|
239
229
|
complete_text_response = ""
|
@@ -46,14 +46,19 @@ class QueryService(QueryServiceInterface):
|
|
46
46
|
audio_input_format: Literal[
|
47
47
|
"flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
|
48
48
|
] = "mp4",
|
49
|
+
prompt: Optional[str] = None,
|
49
50
|
) -> AsyncGenerator[Union[str, bytes], None]: # pragma: no cover
|
50
51
|
"""Process the user request with appropriate agent.
|
51
52
|
|
52
53
|
Args:
|
53
54
|
user_id: User ID
|
54
55
|
query: Text query or audio bytes
|
55
|
-
output_format: Response format ("text" or "audio")
|
56
|
-
|
56
|
+
output_format: Response format ("text" or "audio")
|
57
|
+
audio_voice: Voice for TTS (text-to-speech)
|
58
|
+
audio_instructions: Optional instructions for TTS
|
59
|
+
audio_output_format: Audio output format
|
60
|
+
audio_input_format: Audio input format
|
61
|
+
prompt: Optional prompt for the agent
|
57
62
|
|
58
63
|
Yields:
|
59
64
|
Response chunks (text strings or audio bytes)
|
@@ -105,7 +110,8 @@ class QueryService(QueryServiceInterface):
|
|
105
110
|
audio_voice=audio_voice,
|
106
111
|
audio_input_format=audio_input_format,
|
107
112
|
audio_output_format=audio_output_format,
|
108
|
-
audio_instructions=audio_instructions
|
113
|
+
audio_instructions=audio_instructions,
|
114
|
+
prompt=prompt,
|
109
115
|
):
|
110
116
|
yield audio_chunk
|
111
117
|
|
@@ -122,7 +128,8 @@ class QueryService(QueryServiceInterface):
|
|
122
128
|
user_id=user_id,
|
123
129
|
query=user_text,
|
124
130
|
memory_context=memory_context,
|
125
|
-
output_format="text"
|
131
|
+
output_format="text",
|
132
|
+
prompt=prompt,
|
126
133
|
):
|
127
134
|
yield chunk
|
128
135
|
full_text_response += chunk
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{solana_agent-19.0.1 → solana_agent-19.1.0}/solana_agent/interfaces/providers/data_storage.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|