solana-agent 27.3.6__py3-none-any.whl → 27.3.7__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 +1 -3
- solana_agent/adapters/mongodb_adapter.py +5 -2
- solana_agent/adapters/openai_adapter.py +32 -27
- solana_agent/adapters/pinecone_adapter.py +91 -63
- solana_agent/client/solana_agent.py +38 -23
- solana_agent/domains/agent.py +7 -13
- solana_agent/domains/routing.py +5 -5
- solana_agent/factories/agent_factory.py +49 -34
- solana_agent/interfaces/client/client.py +22 -13
- solana_agent/interfaces/plugins/plugins.py +2 -1
- solana_agent/interfaces/providers/data_storage.py +9 -2
- solana_agent/interfaces/providers/llm.py +26 -12
- solana_agent/interfaces/providers/memory.py +1 -1
- solana_agent/interfaces/providers/vector_storage.py +3 -9
- solana_agent/interfaces/services/agent.py +21 -6
- solana_agent/interfaces/services/knowledge_base.py +6 -8
- solana_agent/interfaces/services/query.py +16 -5
- solana_agent/interfaces/services/routing.py +0 -1
- solana_agent/plugins/manager.py +14 -9
- solana_agent/plugins/registry.py +13 -11
- solana_agent/plugins/tools/__init__.py +0 -5
- solana_agent/plugins/tools/auto_tool.py +1 -0
- solana_agent/repositories/memory.py +20 -22
- solana_agent/services/__init__.py +1 -1
- solana_agent/services/agent.py +119 -89
- solana_agent/services/knowledge_base.py +182 -131
- solana_agent/services/query.py +48 -24
- solana_agent/services/routing.py +30 -18
- {solana_agent-27.3.6.dist-info → solana_agent-27.3.7.dist-info}/METADATA +2 -1
- solana_agent-27.3.7.dist-info/RECORD +39 -0
- solana_agent-27.3.6.dist-info/RECORD +0 -39
- {solana_agent-27.3.6.dist-info → solana_agent-27.3.7.dist-info}/LICENSE +0 -0
- {solana_agent-27.3.6.dist-info → solana_agent-27.3.7.dist-info}/WHEEL +0 -0
@@ -4,6 +4,7 @@ Simplified client interface for interacting with the Solana Agent system.
|
|
4
4
|
This module provides a clean API for end users to interact with
|
5
5
|
the agent system without dealing with internal implementation details.
|
6
6
|
"""
|
7
|
+
|
7
8
|
import json
|
8
9
|
import importlib.util
|
9
10
|
from typing import AsyncGenerator, Dict, Any, List, Literal, Optional, Union
|
@@ -34,8 +35,7 @@ class SolanaAgent(SolanaAgentInterface):
|
|
34
35
|
config = json.load(f)
|
35
36
|
else:
|
36
37
|
# Assume it's a Python file
|
37
|
-
spec = importlib.util.spec_from_file_location(
|
38
|
-
"config", config_path)
|
38
|
+
spec = importlib.util.spec_from_file_location("config", config_path)
|
39
39
|
config_module = importlib.util.module_from_spec(spec)
|
40
40
|
spec.loader.exec_module(config_module)
|
41
41
|
config = config_module.config
|
@@ -48,11 +48,22 @@ class SolanaAgent(SolanaAgentInterface):
|
|
48
48
|
message: Union[str, bytes],
|
49
49
|
prompt: Optional[str] = None,
|
50
50
|
output_format: Literal["text", "audio"] = "text",
|
51
|
-
audio_voice: Literal[
|
52
|
-
|
51
|
+
audio_voice: Literal[
|
52
|
+
"alloy",
|
53
|
+
"ash",
|
54
|
+
"ballad",
|
55
|
+
"coral",
|
56
|
+
"echo",
|
57
|
+
"fable",
|
58
|
+
"onyx",
|
59
|
+
"nova",
|
60
|
+
"sage",
|
61
|
+
"shimmer",
|
62
|
+
] = "nova",
|
53
63
|
audio_instructions: str = "You speak in a friendly and helpful manner.",
|
54
|
-
audio_output_format: Literal[
|
55
|
-
|
64
|
+
audio_output_format: Literal[
|
65
|
+
"mp3", "opus", "aac", "flac", "wav", "pcm"
|
66
|
+
] = "aac",
|
56
67
|
audio_input_format: Literal[
|
57
68
|
"flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
|
58
69
|
] = "mp4",
|
@@ -101,7 +112,7 @@ class SolanaAgent(SolanaAgentInterface):
|
|
101
112
|
user_id: str,
|
102
113
|
page_num: int = 1,
|
103
114
|
page_size: int = 20,
|
104
|
-
sort_order: str = "desc" # "asc" for oldest-first, "desc" for newest-first
|
115
|
+
sort_order: str = "desc", # "asc" for oldest-first, "desc" for newest-first
|
105
116
|
) -> Dict[str, Any]: # pragma: no cover
|
106
117
|
"""
|
107
118
|
Get paginated message history for a user.
|
@@ -130,27 +141,29 @@ class SolanaAgent(SolanaAgentInterface):
|
|
130
141
|
Returns:
|
131
142
|
True if successful, False
|
132
143
|
"""
|
133
|
-
success = self.query_service.agent_service.tool_registry.register_tool(
|
134
|
-
tool)
|
144
|
+
success = self.query_service.agent_service.tool_registry.register_tool(tool)
|
135
145
|
if success:
|
136
146
|
self.query_service.agent_service.assign_tool_for_agent(
|
137
|
-
agent_name, tool.name
|
147
|
+
agent_name, tool.name
|
148
|
+
)
|
138
149
|
return success
|
139
150
|
|
140
151
|
def _ensure_kb(self) -> KnowledgeBaseService:
|
141
152
|
"""Checks if the knowledge base service is available and returns it."""
|
142
|
-
if
|
153
|
+
if (
|
154
|
+
hasattr(self.query_service, "knowledge_base")
|
155
|
+
and self.query_service.knowledge_base
|
156
|
+
):
|
143
157
|
return self.query_service.knowledge_base
|
144
158
|
else:
|
145
|
-
raise AttributeError(
|
146
|
-
"Knowledge base service not configured or available.")
|
159
|
+
raise AttributeError("Knowledge base service not configured or available.")
|
147
160
|
|
148
161
|
async def kb_add_document(
|
149
162
|
self,
|
150
163
|
text: str,
|
151
164
|
metadata: Dict[str, Any],
|
152
165
|
document_id: Optional[str] = None,
|
153
|
-
namespace: Optional[str] = None
|
166
|
+
namespace: Optional[str] = None,
|
154
167
|
) -> str:
|
155
168
|
"""
|
156
169
|
Add a document to the knowledge base.
|
@@ -174,7 +187,7 @@ class SolanaAgent(SolanaAgentInterface):
|
|
174
187
|
top_k: int = 5,
|
175
188
|
namespace: Optional[str] = None,
|
176
189
|
include_content: bool = True,
|
177
|
-
include_metadata: bool = True
|
190
|
+
include_metadata: bool = True,
|
178
191
|
) -> List[Dict[str, Any]]:
|
179
192
|
"""
|
180
193
|
Query the knowledge base.
|
@@ -191,12 +204,12 @@ class SolanaAgent(SolanaAgentInterface):
|
|
191
204
|
List of matching documents.
|
192
205
|
"""
|
193
206
|
kb = self._ensure_kb()
|
194
|
-
return await kb.query(
|
207
|
+
return await kb.query(
|
208
|
+
query_text, filter, top_k, namespace, include_content, include_metadata
|
209
|
+
)
|
195
210
|
|
196
211
|
async def kb_delete_document(
|
197
|
-
self,
|
198
|
-
document_id: str,
|
199
|
-
namespace: Optional[str] = None
|
212
|
+
self, document_id: str, namespace: Optional[str] = None
|
200
213
|
) -> bool:
|
201
214
|
"""
|
202
215
|
Delete a document from the knowledge base.
|
@@ -216,7 +229,7 @@ class SolanaAgent(SolanaAgentInterface):
|
|
216
229
|
document_id: str,
|
217
230
|
text: Optional[str] = None,
|
218
231
|
metadata: Optional[Dict[str, Any]] = None,
|
219
|
-
namespace: Optional[str] = None
|
232
|
+
namespace: Optional[str] = None,
|
220
233
|
) -> bool:
|
221
234
|
"""
|
222
235
|
Update an existing document in the knowledge base.
|
@@ -237,7 +250,7 @@ class SolanaAgent(SolanaAgentInterface):
|
|
237
250
|
self,
|
238
251
|
documents: List[Dict[str, Any]],
|
239
252
|
namespace: Optional[str] = None,
|
240
|
-
batch_size: int = 50
|
253
|
+
batch_size: int = 50,
|
241
254
|
) -> List[str]:
|
242
255
|
"""
|
243
256
|
Add multiple documents to the knowledge base in batches.
|
@@ -259,7 +272,7 @@ class SolanaAgent(SolanaAgentInterface):
|
|
259
272
|
metadata: Dict[str, Any],
|
260
273
|
document_id: Optional[str] = None,
|
261
274
|
namespace: Optional[str] = None,
|
262
|
-
chunk_batch_size: int = 50
|
275
|
+
chunk_batch_size: int = 50,
|
263
276
|
) -> str:
|
264
277
|
"""
|
265
278
|
Add a PDF document to the knowledge base via the client.
|
@@ -278,4 +291,6 @@ class SolanaAgent(SolanaAgentInterface):
|
|
278
291
|
# Type check added for clarity, though handled in service
|
279
292
|
if not isinstance(pdf_data, (bytes, str)):
|
280
293
|
raise TypeError("pdf_data must be bytes or a file path string.")
|
281
|
-
return await kb.add_pdf_document(
|
294
|
+
return await kb.add_pdf_document(
|
295
|
+
pdf_data, metadata, document_id, namespace, chunk_batch_size
|
296
|
+
)
|
solana_agent/domains/agent.py
CHANGED
@@ -4,25 +4,20 @@ Domain models for AI and human agents.
|
|
4
4
|
This module defines the core domain models for representing
|
5
5
|
AI agents, human agents, and business mission/values.
|
6
6
|
"""
|
7
|
-
|
7
|
+
|
8
|
+
from typing import List, Dict
|
8
9
|
from pydantic import BaseModel, Field, field_validator
|
9
10
|
|
10
11
|
|
11
12
|
class BusinessMission(BaseModel):
|
12
13
|
"""Business mission and values to guide agent behavior."""
|
13
14
|
|
14
|
-
mission: str = Field(...,
|
15
|
-
description="Business mission statement")
|
15
|
+
mission: str = Field(..., description="Business mission statement")
|
16
16
|
values: List[Dict[str, str]] = Field(
|
17
|
-
default_factory=list,
|
18
|
-
description="Business values as name-description pairs"
|
19
|
-
)
|
20
|
-
goals: List[str] = Field(
|
21
|
-
default_factory=list,
|
22
|
-
description="Business goals"
|
17
|
+
default_factory=list, description="Business values as name-description pairs"
|
23
18
|
)
|
24
|
-
|
25
|
-
|
19
|
+
goals: List[str] = Field(default_factory=list, description="Business goals")
|
20
|
+
voice: str = Field(None, description="Business voice or tone")
|
26
21
|
|
27
22
|
@field_validator("mission")
|
28
23
|
@classmethod
|
@@ -56,8 +51,7 @@ class AIAgent(BaseModel):
|
|
56
51
|
model_config = {"arbitrary_types_allowed": True}
|
57
52
|
|
58
53
|
name: str = Field(..., description="Unique agent identifier name")
|
59
|
-
instructions: str = Field(...,
|
60
|
-
description="Base instructions for the agent")
|
54
|
+
instructions: str = Field(..., description="Base instructions for the agent")
|
61
55
|
specialization: str = Field(..., description="Agent's specialized domain")
|
62
56
|
|
63
57
|
@field_validator("name", "specialization")
|
solana_agent/domains/routing.py
CHANGED
@@ -4,11 +4,11 @@ from pydantic import BaseModel, Field
|
|
4
4
|
|
5
5
|
class QueryAnalysis(BaseModel):
|
6
6
|
"""Analysis of a user query for routing purposes."""
|
7
|
-
|
8
|
-
|
7
|
+
|
8
|
+
primary_specialization: str = Field(..., description="Main specialization needed")
|
9
9
|
secondary_specializations: List[str] = Field(
|
10
|
-
..., description="Other helpful specializations"
|
11
|
-
|
12
|
-
|
10
|
+
..., description="Other helpful specializations"
|
11
|
+
)
|
12
|
+
complexity_level: int = Field(..., description="Complexity level (1-5)")
|
13
13
|
topics: List[str] = Field(..., description="Key topics in the query")
|
14
14
|
confidence: float = Field(..., description="Confidence in the analysis")
|
@@ -4,6 +4,7 @@ Factory for creating and wiring components of the Solana Agent system.
|
|
4
4
|
This module handles the creation and dependency injection for all
|
5
5
|
services and components used in the system.
|
6
6
|
"""
|
7
|
+
|
7
8
|
from typing import Dict, Any
|
8
9
|
|
9
10
|
# Service imports
|
@@ -58,10 +59,12 @@ class SolanaAgentFactory:
|
|
58
59
|
org_config = config["business"]
|
59
60
|
business_mission = BusinessMission(
|
60
61
|
mission=org_config.get("mission", ""),
|
61
|
-
values=[
|
62
|
-
|
62
|
+
values=[
|
63
|
+
{"name": k, "description": v}
|
64
|
+
for k, v in org_config.get("values", {}).items()
|
65
|
+
],
|
63
66
|
goals=org_config.get("goals", []),
|
64
|
-
voice=org_config.get("voice", "")
|
67
|
+
voice=org_config.get("voice", ""),
|
65
68
|
)
|
66
69
|
|
67
70
|
# Create repositories
|
@@ -69,19 +72,22 @@ class SolanaAgentFactory:
|
|
69
72
|
|
70
73
|
if "zep" in config and "mongo" in config:
|
71
74
|
memory_provider = MemoryRepository(
|
72
|
-
mongo_adapter=db_adapter, zep_api_key=config["zep"].get("api_key")
|
75
|
+
mongo_adapter=db_adapter, zep_api_key=config["zep"].get("api_key")
|
76
|
+
)
|
73
77
|
|
74
|
-
if "mongo" in config and
|
78
|
+
if "mongo" in config and "zep" not in config:
|
75
79
|
memory_provider = MemoryRepository(mongo_adapter=db_adapter)
|
76
80
|
|
77
|
-
if "zep" in config and
|
81
|
+
if "zep" in config and "mongo" not in config:
|
78
82
|
if "api_key" not in config["zep"]:
|
79
83
|
raise ValueError("Zep API key is required.")
|
80
|
-
memory_provider = MemoryRepository(
|
81
|
-
zep_api_key=config["zep"].get("api_key")
|
82
|
-
)
|
84
|
+
memory_provider = MemoryRepository(zep_api_key=config["zep"].get("api_key"))
|
83
85
|
|
84
|
-
if
|
86
|
+
if (
|
87
|
+
"gemini" in config
|
88
|
+
and "api_key" in config["gemini"]
|
89
|
+
and "grok" not in config
|
90
|
+
):
|
85
91
|
# Create primary services
|
86
92
|
agent_service = AgentService(
|
87
93
|
llm_provider=llm_adapter,
|
@@ -101,7 +107,12 @@ class SolanaAgentFactory:
|
|
101
107
|
model="gemini-2.0-flash",
|
102
108
|
)
|
103
109
|
|
104
|
-
elif
|
110
|
+
elif (
|
111
|
+
"gemini" in config
|
112
|
+
and "api_key" in config["gemini"]
|
113
|
+
and "grok" in config
|
114
|
+
and "api_key" in config["grok"]
|
115
|
+
):
|
105
116
|
# Create primary services
|
106
117
|
agent_service = AgentService(
|
107
118
|
llm_provider=llm_adapter,
|
@@ -120,7 +131,9 @@ class SolanaAgentFactory:
|
|
120
131
|
model="gemini-2.0-flash",
|
121
132
|
)
|
122
133
|
|
123
|
-
elif
|
134
|
+
elif (
|
135
|
+
"grok" in config and "api_key" in config["grok"] and "gemini" not in config
|
136
|
+
):
|
124
137
|
# Create primary services
|
125
138
|
agent_service = AgentService(
|
126
139
|
llm_provider=llm_adapter,
|
@@ -153,12 +166,12 @@ class SolanaAgentFactory:
|
|
153
166
|
|
154
167
|
# Debug the agent service tool registry
|
155
168
|
print(
|
156
|
-
f"Agent service tools after initialization: {agent_service.tool_registry.list_all_tools()}"
|
169
|
+
f"Agent service tools after initialization: {agent_service.tool_registry.list_all_tools()}"
|
170
|
+
)
|
157
171
|
|
158
172
|
# Initialize plugin system
|
159
173
|
agent_service.plugin_manager = PluginManager(
|
160
|
-
config=config,
|
161
|
-
tool_registry=agent_service.tool_registry
|
174
|
+
config=config, tool_registry=agent_service.tool_registry
|
162
175
|
)
|
163
176
|
try:
|
164
177
|
loaded_plugins = agent_service.plugin_manager.load_plugins()
|
@@ -179,19 +192,18 @@ class SolanaAgentFactory:
|
|
179
192
|
if "tools" in agent_config:
|
180
193
|
for tool_name in agent_config["tools"]:
|
181
194
|
print(
|
182
|
-
f"Available tools before registering {tool_name}: {agent_service.tool_registry.list_all_tools()}"
|
183
|
-
agent_service.assign_tool_for_agent(
|
184
|
-
agent_config["name"], tool_name
|
195
|
+
f"Available tools before registering {tool_name}: {agent_service.tool_registry.list_all_tools()}"
|
185
196
|
)
|
197
|
+
agent_service.assign_tool_for_agent(agent_config["name"], tool_name)
|
186
198
|
print(
|
187
|
-
f"Successfully registered {tool_name} for agent {agent_config['name']}"
|
199
|
+
f"Successfully registered {tool_name} for agent {agent_config['name']}"
|
200
|
+
)
|
188
201
|
|
189
202
|
# Global tool registrations
|
190
203
|
if "agent_tools" in config:
|
191
204
|
for agent_name, tools in config["agent_tools"].items():
|
192
205
|
for tool_name in tools:
|
193
|
-
agent_service.assign_tool_for_agent(
|
194
|
-
agent_name, tool_name)
|
206
|
+
agent_service.assign_tool_for_agent(agent_name, tool_name)
|
195
207
|
|
196
208
|
# Initialize Knowledge Base if configured
|
197
209
|
knowledge_base = None
|
@@ -206,7 +218,8 @@ class SolanaAgentFactory:
|
|
206
218
|
|
207
219
|
# Determine OpenAI model and dimensions for KBService
|
208
220
|
openai_model_name = openai_embed_config.get(
|
209
|
-
"model_name", "text-embedding-3-large"
|
221
|
+
"model_name", "text-embedding-3-large"
|
222
|
+
)
|
210
223
|
if openai_model_name == "text-embedding-3-large":
|
211
224
|
openai_dimensions = 3072
|
212
225
|
elif openai_model_name == "text-embedding-3-small": # pragma: no cover
|
@@ -219,20 +232,20 @@ class SolanaAgentFactory:
|
|
219
232
|
index_name=pinecone_config.get("index_name"),
|
220
233
|
# This dimension MUST match the OpenAI model used by KBService
|
221
234
|
embedding_dimensions=openai_dimensions,
|
222
|
-
cloud_provider=pinecone_config.get(
|
223
|
-
"cloud_provider", "aws"),
|
235
|
+
cloud_provider=pinecone_config.get("cloud_provider", "aws"),
|
224
236
|
region=pinecone_config.get("region", "us-east-1"),
|
225
237
|
metric=pinecone_config.get("metric", "cosine"),
|
226
238
|
create_index_if_not_exists=pinecone_config.get(
|
227
|
-
"create_index", True
|
239
|
+
"create_index", True
|
240
|
+
),
|
228
241
|
# Reranking config
|
229
242
|
use_reranking=pinecone_config.get("use_reranking", False),
|
230
243
|
rerank_model=pinecone_config.get("rerank_model"),
|
231
244
|
rerank_top_k=pinecone_config.get("rerank_top_k", 3),
|
232
245
|
initial_query_top_k_multiplier=pinecone_config.get(
|
233
|
-
"initial_query_top_k_multiplier", 5
|
234
|
-
|
235
|
-
|
246
|
+
"initial_query_top_k_multiplier", 5
|
247
|
+
),
|
248
|
+
rerank_text_field=pinecone_config.get("rerank_text_field", "text"),
|
236
249
|
)
|
237
250
|
|
238
251
|
# Create the KB service using OpenAI embeddings
|
@@ -240,24 +253,27 @@ class SolanaAgentFactory:
|
|
240
253
|
pinecone_adapter=pinecone_adapter,
|
241
254
|
mongodb_adapter=db_adapter,
|
242
255
|
# Pass OpenAI config directly
|
243
|
-
openai_api_key=openai_embed_config.get("api_key")
|
244
|
-
|
256
|
+
openai_api_key=openai_embed_config.get("api_key")
|
257
|
+
or config.get("openai", {}).get("api_key"),
|
245
258
|
openai_model_name=openai_model_name,
|
246
259
|
collection_name=kb_config.get(
|
247
|
-
"collection_name", "knowledge_documents"
|
260
|
+
"collection_name", "knowledge_documents"
|
261
|
+
),
|
248
262
|
# Pass rerank config (though PineconeAdapter handles the logic)
|
249
263
|
rerank_results=pinecone_config.get("use_reranking", False),
|
250
264
|
rerank_top_k=pinecone_config.get("rerank_top_k", 3),
|
251
265
|
# Pass splitter config
|
252
266
|
splitter_buffer_size=splitter_config.get("buffer_size", 1),
|
253
267
|
splitter_breakpoint_percentile=splitter_config.get(
|
254
|
-
"breakpoint_percentile", 95
|
268
|
+
"breakpoint_percentile", 95
|
269
|
+
),
|
255
270
|
)
|
256
271
|
print("Knowledge Base Service initialized successfully.")
|
257
272
|
|
258
273
|
except Exception as e:
|
259
274
|
print(f"Failed to initialize Knowledge Base: {e}")
|
260
275
|
import traceback
|
276
|
+
|
261
277
|
print(traceback.format_exc())
|
262
278
|
knowledge_base = None # Ensure KB is None if init fails
|
263
279
|
|
@@ -267,8 +283,7 @@ class SolanaAgentFactory:
|
|
267
283
|
routing_service=routing_service,
|
268
284
|
memory_provider=memory_provider,
|
269
285
|
knowledge_base=knowledge_base, # Pass the potentially created KB
|
270
|
-
kb_results_count=kb_config.get(
|
271
|
-
"results_count", 3) if kb_config else 3
|
286
|
+
kb_results_count=kb_config.get("results_count", 3) if kb_config else 3,
|
272
287
|
)
|
273
288
|
|
274
289
|
return query_service
|
@@ -14,11 +14,22 @@ class SolanaAgent(ABC):
|
|
14
14
|
message: Union[str, bytes],
|
15
15
|
prompt: Optional[str] = None,
|
16
16
|
output_format: Literal["text", "audio"] = "text",
|
17
|
-
audio_voice: Literal[
|
18
|
-
|
17
|
+
audio_voice: Literal[
|
18
|
+
"alloy",
|
19
|
+
"ash",
|
20
|
+
"ballad",
|
21
|
+
"coral",
|
22
|
+
"echo",
|
23
|
+
"fable",
|
24
|
+
"onyx",
|
25
|
+
"nova",
|
26
|
+
"sage",
|
27
|
+
"shimmer",
|
28
|
+
] = "nova",
|
19
29
|
audio_instructions: str = "You speak in a friendly and helpful manner.",
|
20
|
-
audio_output_format: Literal[
|
21
|
-
|
30
|
+
audio_output_format: Literal[
|
31
|
+
"mp3", "opus", "aac", "flac", "wav", "pcm"
|
32
|
+
] = "aac",
|
22
33
|
audio_input_format: Literal[
|
23
34
|
"flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
|
24
35
|
] = "mp4",
|
@@ -38,7 +49,7 @@ class SolanaAgent(ABC):
|
|
38
49
|
user_id: str,
|
39
50
|
page_num: int = 1,
|
40
51
|
page_size: int = 20,
|
41
|
-
sort_order: str = "desc"
|
52
|
+
sort_order: str = "desc",
|
42
53
|
) -> Dict[str, Any]:
|
43
54
|
"""Get paginated message history for a user."""
|
44
55
|
pass
|
@@ -54,7 +65,7 @@ class SolanaAgent(ABC):
|
|
54
65
|
text: str,
|
55
66
|
metadata: Dict[str, Any],
|
56
67
|
document_id: Optional[str] = None,
|
57
|
-
namespace: Optional[str] = None
|
68
|
+
namespace: Optional[str] = None,
|
58
69
|
) -> str:
|
59
70
|
"""Add a document to the knowledge base."""
|
60
71
|
pass
|
@@ -67,16 +78,14 @@ class SolanaAgent(ABC):
|
|
67
78
|
top_k: int = 5,
|
68
79
|
namespace: Optional[str] = None,
|
69
80
|
include_content: bool = True,
|
70
|
-
include_metadata: bool = True
|
81
|
+
include_metadata: bool = True,
|
71
82
|
) -> List[Dict[str, Any]]:
|
72
83
|
"""Query the knowledge base."""
|
73
84
|
pass
|
74
85
|
|
75
86
|
@abstractmethod
|
76
87
|
async def kb_delete_document(
|
77
|
-
self,
|
78
|
-
document_id: str,
|
79
|
-
namespace: Optional[str] = None
|
88
|
+
self, document_id: str, namespace: Optional[str] = None
|
80
89
|
) -> bool:
|
81
90
|
"""Delete a document from the knowledge base."""
|
82
91
|
pass
|
@@ -87,7 +96,7 @@ class SolanaAgent(ABC):
|
|
87
96
|
document_id: str,
|
88
97
|
text: Optional[str] = None,
|
89
98
|
metadata: Optional[Dict[str, Any]] = None,
|
90
|
-
namespace: Optional[str] = None
|
99
|
+
namespace: Optional[str] = None,
|
91
100
|
) -> bool:
|
92
101
|
"""Update an existing document in the knowledge base."""
|
93
102
|
pass
|
@@ -97,7 +106,7 @@ class SolanaAgent(ABC):
|
|
97
106
|
self,
|
98
107
|
documents: List[Dict[str, Any]],
|
99
108
|
namespace: Optional[str] = None,
|
100
|
-
batch_size: int = 50
|
109
|
+
batch_size: int = 50,
|
101
110
|
) -> List[str]:
|
102
111
|
"""Add multiple documents to the knowledge base in batches."""
|
103
112
|
pass
|
@@ -109,7 +118,7 @@ class SolanaAgent(ABC):
|
|
109
118
|
metadata: Dict[str, Any],
|
110
119
|
document_id: Optional[str] = None,
|
111
120
|
namespace: Optional[str] = None,
|
112
|
-
chunk_batch_size: int = 50
|
121
|
+
chunk_batch_size: int = 50,
|
113
122
|
) -> str:
|
114
123
|
"""Add a PDF document to the knowledge base."""
|
115
124
|
pass
|
@@ -4,8 +4,9 @@ Plugin system interfaces.
|
|
4
4
|
These interfaces define the contracts for the plugin system,
|
5
5
|
enabling extensibility through tools and plugins.
|
6
6
|
"""
|
7
|
+
|
7
8
|
from abc import ABC, abstractmethod
|
8
|
-
from typing import Dict, List, Any, Optional
|
9
|
+
from typing import Dict, List, Any, Optional
|
9
10
|
|
10
11
|
|
11
12
|
class Tool(ABC):
|
@@ -27,13 +27,20 @@ class DataStorageProvider(ABC):
|
|
27
27
|
|
28
28
|
@abstractmethod
|
29
29
|
def find(
|
30
|
-
self,
|
30
|
+
self,
|
31
|
+
collection: str,
|
32
|
+
query: Dict,
|
33
|
+
sort: Optional[List] = None,
|
34
|
+
limit: int = 0,
|
35
|
+
skip: int = 0,
|
31
36
|
) -> List[Dict]:
|
32
37
|
"""Find documents matching query."""
|
33
38
|
pass
|
34
39
|
|
35
40
|
@abstractmethod
|
36
|
-
def update_one(
|
41
|
+
def update_one(
|
42
|
+
self, collection: str, query: Dict, update: Dict, upsert: bool = False
|
43
|
+
) -> bool:
|
37
44
|
"""Update a document."""
|
38
45
|
pass
|
39
46
|
|
@@ -1,10 +1,17 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
from typing import
|
2
|
+
from typing import (
|
3
|
+
AsyncGenerator,
|
4
|
+
List,
|
5
|
+
Literal,
|
6
|
+
Optional,
|
7
|
+
Type,
|
8
|
+
TypeVar,
|
9
|
+
)
|
3
10
|
|
4
11
|
from pydantic import BaseModel
|
5
12
|
|
6
13
|
|
7
|
-
T = TypeVar(
|
14
|
+
T = TypeVar("T", bound=BaseModel)
|
8
15
|
|
9
16
|
|
10
17
|
class LLMProvider(ABC):
|
@@ -24,12 +31,13 @@ class LLMProvider(ABC):
|
|
24
31
|
|
25
32
|
@abstractmethod
|
26
33
|
async def parse_structured_output(
|
27
|
-
self,
|
34
|
+
self,
|
35
|
+
prompt: str,
|
28
36
|
system_prompt: str,
|
29
37
|
model_class: Type[T],
|
30
38
|
api_key: Optional[str] = None,
|
31
39
|
base_url: Optional[str] = None,
|
32
|
-
model: Optional[str] = None
|
40
|
+
model: Optional[str] = None,
|
33
41
|
) -> T:
|
34
42
|
"""Generate structured output using a specific model class."""
|
35
43
|
pass
|
@@ -39,10 +47,19 @@ class LLMProvider(ABC):
|
|
39
47
|
self,
|
40
48
|
text: str,
|
41
49
|
instructions: str = "You speak in a friendly and helpful manner.",
|
42
|
-
voice: Literal[
|
43
|
-
|
44
|
-
|
45
|
-
|
50
|
+
voice: Literal[
|
51
|
+
"alloy",
|
52
|
+
"ash",
|
53
|
+
"ballad",
|
54
|
+
"coral",
|
55
|
+
"echo",
|
56
|
+
"fable",
|
57
|
+
"onyx",
|
58
|
+
"nova",
|
59
|
+
"sage",
|
60
|
+
"shimmer",
|
61
|
+
] = "nova",
|
62
|
+
response_format: Literal["mp3", "opus", "aac", "flac", "wav", "pcm"] = "aac",
|
46
63
|
) -> AsyncGenerator[bytes, None]:
|
47
64
|
"""Stream text-to-speech audio from the language model."""
|
48
65
|
pass
|
@@ -60,10 +77,7 @@ class LLMProvider(ABC):
|
|
60
77
|
|
61
78
|
@abstractmethod
|
62
79
|
async def embed_text(
|
63
|
-
self,
|
64
|
-
text: str,
|
65
|
-
model: Optional[str] = None,
|
66
|
-
dimensions: Optional[int] = None
|
80
|
+
self, text: str, model: Optional[str] = None, dimensions: Optional[int] = None
|
67
81
|
) -> List[float]:
|
68
82
|
"""
|
69
83
|
Generate an embedding for the given text.
|
@@ -5,9 +5,7 @@ class VectorStorageProvider:
|
|
5
5
|
"""Interface for Vector Storage Providers."""
|
6
6
|
|
7
7
|
async def upsert(
|
8
|
-
self,
|
9
|
-
vectors: List[Dict[str, Any]],
|
10
|
-
namespace: Optional[str] = None
|
8
|
+
self, vectors: List[Dict[str, Any]], namespace: Optional[str] = None
|
11
9
|
) -> None:
|
12
10
|
"""Upsert vectors into the storage."""
|
13
11
|
pass
|
@@ -17,7 +15,7 @@ class VectorStorageProvider:
|
|
17
15
|
texts: List[str],
|
18
16
|
ids: List[str],
|
19
17
|
metadatas: Optional[List[Dict[str, Any]]] = None,
|
20
|
-
namespace: Optional[str] = None
|
18
|
+
namespace: Optional[str] = None,
|
21
19
|
) -> None:
|
22
20
|
"""Embeds texts and upserts them into the storage."""
|
23
21
|
pass
|
@@ -46,11 +44,7 @@ class VectorStorageProvider:
|
|
46
44
|
"""Embeds query text and queries the storage."""
|
47
45
|
pass
|
48
46
|
|
49
|
-
async def delete(
|
50
|
-
self,
|
51
|
-
ids: List[str],
|
52
|
-
namespace: Optional[str] = None
|
53
|
-
) -> None:
|
47
|
+
async def delete(self, ids: List[str], namespace: Optional[str] = None) -> None:
|
54
48
|
"""Delete vectors by IDs."""
|
55
49
|
pass
|
56
50
|
|