solana-agent 27.3.5__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.
Files changed (33) hide show
  1. solana_agent/__init__.py +1 -3
  2. solana_agent/adapters/mongodb_adapter.py +5 -2
  3. solana_agent/adapters/openai_adapter.py +32 -27
  4. solana_agent/adapters/pinecone_adapter.py +91 -63
  5. solana_agent/client/solana_agent.py +38 -23
  6. solana_agent/domains/agent.py +7 -13
  7. solana_agent/domains/routing.py +5 -5
  8. solana_agent/factories/agent_factory.py +49 -34
  9. solana_agent/interfaces/client/client.py +22 -13
  10. solana_agent/interfaces/plugins/plugins.py +2 -1
  11. solana_agent/interfaces/providers/data_storage.py +9 -2
  12. solana_agent/interfaces/providers/llm.py +26 -12
  13. solana_agent/interfaces/providers/memory.py +1 -1
  14. solana_agent/interfaces/providers/vector_storage.py +3 -9
  15. solana_agent/interfaces/services/agent.py +21 -6
  16. solana_agent/interfaces/services/knowledge_base.py +6 -8
  17. solana_agent/interfaces/services/query.py +16 -5
  18. solana_agent/interfaces/services/routing.py +0 -1
  19. solana_agent/plugins/manager.py +14 -9
  20. solana_agent/plugins/registry.py +13 -11
  21. solana_agent/plugins/tools/__init__.py +0 -5
  22. solana_agent/plugins/tools/auto_tool.py +1 -0
  23. solana_agent/repositories/memory.py +20 -22
  24. solana_agent/services/__init__.py +1 -1
  25. solana_agent/services/agent.py +119 -89
  26. solana_agent/services/knowledge_base.py +182 -131
  27. solana_agent/services/query.py +48 -24
  28. solana_agent/services/routing.py +30 -18
  29. {solana_agent-27.3.5.dist-info → solana_agent-27.3.7.dist-info}/METADATA +6 -3
  30. solana_agent-27.3.7.dist-info/RECORD +39 -0
  31. solana_agent-27.3.5.dist-info/RECORD +0 -39
  32. {solana_agent-27.3.5.dist-info → solana_agent-27.3.7.dist-info}/LICENSE +0 -0
  33. {solana_agent-27.3.5.dist-info → solana_agent-27.3.7.dist-info}/WHEEL +0 -0
@@ -8,7 +8,9 @@ class AgentService(ABC):
8
8
  """Interface for agent management and response generation."""
9
9
 
10
10
  @abstractmethod
11
- def register_ai_agent(self, name: str, instructions: str, specialization: str) -> None:
11
+ def register_ai_agent(
12
+ self, name: str, instructions: str, specialization: str
13
+ ) -> None:
12
14
  """Register an AI agent with its specialization."""
13
15
  pass
14
16
 
@@ -25,11 +27,22 @@ class AgentService(ABC):
25
27
  query: Union[str, bytes],
26
28
  memory_context: str = "",
27
29
  output_format: Literal["text", "audio"] = "text",
28
- audio_voice: Literal["alloy", "ash", "ballad", "coral", "echo",
29
- "fable", "onyx", "nova", "sage", "shimmer"] = "nova",
30
+ audio_voice: Literal[
31
+ "alloy",
32
+ "ash",
33
+ "ballad",
34
+ "coral",
35
+ "echo",
36
+ "fable",
37
+ "onyx",
38
+ "nova",
39
+ "sage",
40
+ "shimmer",
41
+ ] = "nova",
30
42
  audio_instructions: str = "You speak in a friendly and helpful manner.",
31
- audio_output_format: Literal['mp3', 'opus',
32
- 'aac', 'flac', 'wav', 'pcm'] = "aac",
43
+ audio_output_format: Literal[
44
+ "mp3", "opus", "aac", "flac", "wav", "pcm"
45
+ ] = "aac",
33
46
  prompt: Optional[str] = None,
34
47
  ) -> AsyncGenerator[Union[str, bytes], None]:
35
48
  """Generate a response from an agent."""
@@ -46,7 +59,9 @@ class AgentService(ABC):
46
59
  pass
47
60
 
48
61
  @abstractmethod
49
- async def execute_tool(self, agent_name: str, tool_name: str, parameters: Dict[str, Any]) -> Dict[str, Any]:
62
+ async def execute_tool(
63
+ self, agent_name: str, tool_name: str, parameters: Dict[str, Any]
64
+ ) -> Dict[str, Any]:
50
65
  """Execute a tool on behalf of an agent."""
51
66
  pass
52
67
 
@@ -13,7 +13,7 @@ class KnowledgeBaseService(ABC):
13
13
  text: str,
14
14
  metadata: Dict[str, Any],
15
15
  document_id: Optional[str] = None,
16
- namespace: Optional[str] = None
16
+ namespace: Optional[str] = None,
17
17
  ) -> str:
18
18
  """
19
19
  Add a document to the knowledge base.
@@ -28,7 +28,7 @@ class KnowledgeBaseService(ABC):
28
28
  top_k: int = 5,
29
29
  namespace: Optional[str] = None,
30
30
  include_content: bool = True,
31
- include_metadata: bool = True
31
+ include_metadata: bool = True,
32
32
  ) -> List[Dict[str, Any]]:
33
33
  """
34
34
  Query the knowledge base with semantic search.
@@ -37,9 +37,7 @@ class KnowledgeBaseService(ABC):
37
37
 
38
38
  @abstractmethod
39
39
  async def delete_document(
40
- self,
41
- document_id: str,
42
- namespace: Optional[str] = None
40
+ self, document_id: str, namespace: Optional[str] = None
43
41
  ) -> bool:
44
42
  """
45
43
  Delete a document from the knowledge base.
@@ -52,7 +50,7 @@ class KnowledgeBaseService(ABC):
52
50
  document_id: str,
53
51
  text: Optional[str] = None,
54
52
  metadata: Optional[Dict[str, Any]] = None,
55
- namespace: Optional[str] = None
53
+ namespace: Optional[str] = None,
56
54
  ) -> bool:
57
55
  """
58
56
  Update an existing document in the knowledge base.
@@ -64,7 +62,7 @@ class KnowledgeBaseService(ABC):
64
62
  self,
65
63
  documents: List[Dict[str, Any]],
66
64
  namespace: Optional[str] = None,
67
- batch_size: int = 50
65
+ batch_size: int = 50,
68
66
  ) -> List[str]:
69
67
  """
70
68
  Add multiple documents in batches.
@@ -78,7 +76,7 @@ class KnowledgeBaseService(ABC):
78
76
  metadata: Dict[str, Any],
79
77
  document_id: Optional[str] = None,
80
78
  namespace: Optional[str] = None,
81
- chunk_batch_size: int = 50
79
+ chunk_batch_size: int = 50,
82
80
  ) -> str:
83
81
  """
84
82
  Add a PDF document to the knowledge base.
@@ -13,11 +13,22 @@ class QueryService(ABC):
13
13
  user_id: str,
14
14
  query: Union[str, bytes],
15
15
  output_format: Literal["text", "audio"] = "text",
16
- audio_voice: Literal["alloy", "ash", "ballad", "coral", "echo",
17
- "fable", "onyx", "nova", "sage", "shimmer"] = "nova",
16
+ audio_voice: Literal[
17
+ "alloy",
18
+ "ash",
19
+ "ballad",
20
+ "coral",
21
+ "echo",
22
+ "fable",
23
+ "onyx",
24
+ "nova",
25
+ "sage",
26
+ "shimmer",
27
+ ] = "nova",
18
28
  audio_instructions: str = "You speak in a friendly and helpful manner.",
19
- audio_output_format: Literal['mp3', 'opus',
20
- 'aac', 'flac', 'wav', 'pcm'] = "aac",
29
+ audio_output_format: Literal[
30
+ "mp3", "opus", "aac", "flac", "wav", "pcm"
31
+ ] = "aac",
21
32
  audio_input_format: Literal[
22
33
  "flac", "mp3", "mp4", "mpeg", "mpga", "m4a", "ogg", "wav", "webm"
23
34
  ] = "mp4",
@@ -33,7 +44,7 @@ class QueryService(ABC):
33
44
  user_id: str,
34
45
  page_num: int = 1,
35
46
  page_size: int = 20,
36
- sort_order: str = "desc" # "asc" for oldest-first, "desc" for newest-first
47
+ sort_order: str = "desc", # "asc" for oldest-first, "desc" for newest-first
37
48
  ) -> Dict[str, Any]:
38
49
  """Get paginated message history for a user."""
39
50
  pass
@@ -1,5 +1,4 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import Any, Tuple
3
2
 
4
3
 
5
4
  class RoutingService(ABC):
@@ -4,11 +4,14 @@ Plugin manager for the Solana Agent system.
4
4
  This module implements the concrete PluginManager that discovers,
5
5
  loads, and manages plugins.
6
6
  """
7
+
7
8
  import importlib
8
9
  from typing import Dict, List, Any, Optional
9
10
  import importlib.metadata
10
11
 
11
- from solana_agent.interfaces.plugins.plugins import PluginManager as PluginManagerInterface
12
+ from solana_agent.interfaces.plugins.plugins import (
13
+ PluginManager as PluginManagerInterface,
14
+ )
12
15
  from solana_agent.interfaces.plugins.plugins import Plugin
13
16
  from solana_agent.plugins.registry import ToolRegistry
14
17
 
@@ -19,7 +22,11 @@ class PluginManager(PluginManagerInterface):
19
22
  # Class variable to track loaded entry points
20
23
  _loaded_entry_points = set()
21
24
 
22
- def __init__(self, config: Optional[Dict[str, Any]] = None, tool_registry: Optional[ToolRegistry] = None):
25
+ def __init__(
26
+ self,
27
+ config: Optional[Dict[str, Any]] = None,
28
+ tool_registry: Optional[ToolRegistry] = None,
29
+ ):
23
30
  """Initialize with optional configuration and tool registry."""
24
31
  self.config = config or {}
25
32
  self.tool_registry = tool_registry or ToolRegistry()
@@ -61,12 +68,13 @@ class PluginManager(PluginManagerInterface):
61
68
  loaded_plugins = []
62
69
 
63
70
  # Discover plugins through entry points
64
- for entry_point in importlib.metadata.entry_points(group='solana_agent.plugins'):
71
+ for entry_point in importlib.metadata.entry_points(
72
+ group="solana_agent.plugins"
73
+ ):
65
74
  # Skip if this entry point has already been loaded
66
75
  entry_point_id = f"{entry_point.name}:{entry_point.value}"
67
76
  if entry_point_id in PluginManager._loaded_entry_points:
68
- print(
69
- f"Skipping already loaded plugin: {entry_point.name}")
77
+ print(f"Skipping already loaded plugin: {entry_point.name}")
70
78
  continue
71
79
 
72
80
  try:
@@ -103,10 +111,7 @@ class PluginManager(PluginManagerInterface):
103
111
  List of plugin details dictionaries
104
112
  """
105
113
  return [
106
- {
107
- "name": plugin.name,
108
- "description": plugin.description
109
- }
114
+ {"name": plugin.name, "description": plugin.description}
110
115
  for plugin in self._plugins.values()
111
116
  ]
112
117
 
@@ -1,12 +1,15 @@
1
1
  """
2
2
  Tool registry for the Solana Agent system.
3
3
 
4
- This module implements the concrete ToolRegistry that manages tools
4
+ This module implements the concrete ToolRegistry that manages tools
5
5
  and their access permissions.
6
6
  """
7
+
7
8
  from typing import Dict, List, Any, Optional
8
9
 
9
- from solana_agent.interfaces.plugins.plugins import ToolRegistry as ToolRegistryInterface
10
+ from solana_agent.interfaces.plugins.plugins import (
11
+ ToolRegistry as ToolRegistryInterface,
12
+ )
10
13
  from solana_agent.interfaces.plugins.plugins import Tool
11
14
 
12
15
 
@@ -39,7 +42,8 @@ class ToolRegistry(ToolRegistryInterface):
39
42
  """Give an agent access to a specific tool."""
40
43
  if tool_name not in self._tools:
41
44
  print(
42
- f"Error: Tool {tool_name} is not registered. Available tools: {list(self._tools.keys())}")
45
+ f"Error: Tool {tool_name} is not registered. Available tools: {list(self._tools.keys())}"
46
+ )
43
47
  return False
44
48
 
45
49
  # Initialize agent's tool list if not exists
@@ -47,12 +51,10 @@ class ToolRegistry(ToolRegistryInterface):
47
51
  self._agent_tools[agent_name] = [tool_name]
48
52
  elif tool_name not in self._agent_tools[agent_name]:
49
53
  # Add new tool to existing list
50
- self._agent_tools[agent_name] = [
51
- *self._agent_tools[agent_name], tool_name]
54
+ self._agent_tools[agent_name] = [*self._agent_tools[agent_name], tool_name]
52
55
 
53
56
  print(f"Successfully assigned tool {tool_name} to agent {agent_name}")
54
- print(
55
- f"Agent {agent_name} now has access to: {self._agent_tools[agent_name]}")
57
+ print(f"Agent {agent_name} now has access to: {self._agent_tools[agent_name]}")
56
58
 
57
59
  return True
58
60
 
@@ -63,12 +65,12 @@ class ToolRegistry(ToolRegistryInterface):
63
65
  {
64
66
  "name": name,
65
67
  "description": self._tools[name].description,
66
- "parameters": self._tools[name].get_schema()
68
+ "parameters": self._tools[name].get_schema(),
67
69
  }
68
- for name in tool_names if name in self._tools
70
+ for name in tool_names
71
+ if name in self._tools
69
72
  ]
70
- print(
71
- f"Tools available to agent {agent_name}: {[t['name'] for t in tools]}")
73
+ print(f"Tools available to agent {agent_name}: {[t['name'] for t in tools]}")
72
74
  return tools
73
75
 
74
76
  def list_all_tools(self) -> List[str]:
@@ -3,8 +3,3 @@ Tools for the Solana Agent system.
3
3
 
4
4
  This package contains the base AutoTool class and built-in tool implementations.
5
5
  """
6
-
7
- from solana_agent.plugins.tools.auto_tool import *
8
-
9
- # Version of the domain model
10
- __version__ = '14.0.0'
@@ -4,6 +4,7 @@ AutoTool implementation for the Solana Agent system.
4
4
  This module provides the base AutoTool class that implements the Tool interface
5
5
  and can be extended to create custom tools.
6
6
  """
7
+
7
8
  from typing import Dict, Any
8
9
 
9
10
  from solana_agent.interfaces.plugins.plugins import Tool
@@ -43,13 +43,18 @@ class MemoryRepository(MemoryProvider):
43
43
  raise ValueError("User ID cannot be None or empty")
44
44
  if not messages or not isinstance(messages, list):
45
45
  raise ValueError("Messages must be a non-empty list")
46
- if not all(isinstance(msg, dict) and "role" in msg and "content" in msg for msg in messages):
46
+ if not all(
47
+ isinstance(msg, dict) and "role" in msg and "content" in msg
48
+ for msg in messages
49
+ ):
47
50
  raise ValueError(
48
- "All messages must be dictionaries with 'role' and 'content' keys")
51
+ "All messages must be dictionaries with 'role' and 'content' keys"
52
+ )
49
53
  for msg in messages:
50
54
  if msg["role"] not in ["user", "assistant"]:
51
55
  raise ValueError(
52
- f"Invalid role '{msg['role']}' in message. Only 'user' and 'assistant' roles are accepted.")
56
+ f"Invalid role '{msg['role']}' in message. Only 'user' and 'assistant' roles are accepted."
57
+ )
53
58
 
54
59
  # Store in MongoDB
55
60
  if self.mongo and len(messages) >= 2:
@@ -71,7 +76,7 @@ class MemoryRepository(MemoryProvider):
71
76
  "user_id": user_id,
72
77
  "user_message": user_msg,
73
78
  "assistant_message": assistant_msg,
74
- "timestamp": datetime.now(timezone.utc)
79
+ "timestamp": datetime.now(timezone.utc),
75
80
  }
76
81
  self.mongo.insert_one(self.collection, doc)
77
82
  except Exception as e:
@@ -96,11 +101,8 @@ class MemoryRepository(MemoryProvider):
96
101
  # Add messages to Zep memory
97
102
  if zep_messages:
98
103
  try:
99
- await self.zep.memory.add(
100
- session_id=user_id,
101
- messages=zep_messages
102
- )
103
- except Exception as e:
104
+ await self.zep.memory.add(session_id=user_id, messages=zep_messages)
105
+ except Exception:
104
106
  try:
105
107
  try:
106
108
  await self.zep.user.add(user_id=user_id)
@@ -108,13 +110,12 @@ class MemoryRepository(MemoryProvider):
108
110
  print(f"Zep user addition error: {e}")
109
111
 
110
112
  try:
111
- await self.zep.memory.add_session(session_id=user_id, user_id=user_id)
113
+ await self.zep.memory.add_session(
114
+ session_id=user_id, user_id=user_id
115
+ )
112
116
  except Exception as e:
113
117
  print(f"Zep session creation error: {e}")
114
- await self.zep.memory.add(
115
- session_id=user_id,
116
- messages=zep_messages
117
- )
118
+ await self.zep.memory.add(session_id=user_id, messages=zep_messages)
118
119
  except Exception as e:
119
120
  print(f"Zep memory addition error: {e}")
120
121
  return
@@ -137,10 +138,7 @@ class MemoryRepository(MemoryProvider):
137
138
  """Delete memory from both systems."""
138
139
  if self.mongo:
139
140
  try:
140
- self.mongo.delete_all(
141
- self.collection,
142
- {"user_id": user_id}
143
- )
141
+ self.mongo.delete_all(self.collection, {"user_id": user_id})
144
142
  except Exception as e:
145
143
  print(f"MongoDB deletion error: {e}")
146
144
 
@@ -163,7 +161,7 @@ class MemoryRepository(MemoryProvider):
163
161
  query: Dict,
164
162
  sort: Optional[List[Tuple]] = None,
165
163
  limit: int = 0,
166
- skip: int = 0
164
+ skip: int = 0,
167
165
  ) -> List[Dict]: # pragma: no cover
168
166
  """Find documents in MongoDB."""
169
167
  if not self.mongo:
@@ -193,9 +191,9 @@ class MemoryRepository(MemoryProvider):
193
191
  return text
194
192
 
195
193
  # Try to truncate at last period before limit
196
- last_period = text.rfind('.', 0, limit)
194
+ last_period = text.rfind(".", 0, limit)
197
195
  if last_period > 0:
198
- return text[:last_period + 1]
196
+ return text[: last_period + 1]
199
197
 
200
198
  # If no period found, truncate at limit and add ellipsis
201
- return text[:limit-3] + "..."
199
+ return text[: limit - 3] + "..."
@@ -1,6 +1,6 @@
1
1
  """
2
2
  Service implementations for the Solana Agent system.
3
3
 
4
- These services implement the business logic interfaces defined in
4
+ These services implement the business logic interfaces defined in
5
5
  solana_agent.interfaces.services.
6
6
  """