solana-agent 29.2.0__tar.gz → 29.2.2__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.
Files changed (43) hide show
  1. {solana_agent-29.2.0 → solana_agent-29.2.2}/PKG-INFO +49 -20
  2. {solana_agent-29.2.0 → solana_agent-29.2.2}/README.md +48 -19
  3. {solana_agent-29.2.0 → solana_agent-29.2.2}/pyproject.toml +1 -1
  4. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/adapters/openai_adapter.py +12 -10
  5. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/interfaces/providers/llm.py +5 -1
  6. solana_agent-29.2.2/solana_agent/services/agent.py +467 -0
  7. solana_agent-29.2.0/solana_agent/services/agent.py +0 -956
  8. {solana_agent-29.2.0 → solana_agent-29.2.2}/LICENSE +0 -0
  9. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/__init__.py +0 -0
  10. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/adapters/__init__.py +0 -0
  11. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/adapters/mongodb_adapter.py +0 -0
  12. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/adapters/pinecone_adapter.py +0 -0
  13. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/cli.py +0 -0
  14. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/client/__init__.py +0 -0
  15. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/client/solana_agent.py +0 -0
  16. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/domains/__init__.py +0 -0
  17. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/domains/agent.py +0 -0
  18. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/domains/routing.py +0 -0
  19. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/factories/__init__.py +0 -0
  20. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/factories/agent_factory.py +0 -0
  21. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/guardrails/pii.py +0 -0
  22. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/interfaces/__init__.py +0 -0
  23. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/interfaces/client/client.py +0 -0
  24. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/interfaces/guardrails/guardrails.py +0 -0
  25. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/interfaces/plugins/plugins.py +0 -0
  26. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/interfaces/providers/data_storage.py +0 -0
  27. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/interfaces/providers/memory.py +0 -0
  28. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/interfaces/providers/vector_storage.py +0 -0
  29. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/interfaces/services/agent.py +0 -0
  30. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/interfaces/services/knowledge_base.py +0 -0
  31. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/interfaces/services/query.py +0 -0
  32. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/interfaces/services/routing.py +0 -0
  33. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/plugins/__init__.py +0 -0
  34. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/plugins/manager.py +0 -0
  35. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/plugins/registry.py +0 -0
  36. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/plugins/tools/__init__.py +0 -0
  37. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/plugins/tools/auto_tool.py +0 -0
  38. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/repositories/__init__.py +0 -0
  39. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/repositories/memory.py +0 -0
  40. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/services/__init__.py +0 -0
  41. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/services/knowledge_base.py +0 -0
  42. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/services/query.py +0 -0
  43. {solana_agent-29.2.0 → solana_agent-29.2.2}/solana_agent/services/routing.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: solana-agent
3
- Version: 29.2.0
3
+ Version: 29.2.2
4
4
  Summary: AI Agents for Solana
5
5
  License: MIT
6
6
  Keywords: solana,solana ai,solana agent,ai,ai agent,ai agents
@@ -41,9 +41,7 @@ Description-Content-Type: text/markdown
41
41
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
42
42
  [![codecov](https://img.shields.io/codecov/c/github/truemagic-coder/solana-agent/main.svg)](https://codecov.io/gh/truemagic-coder/solana-agent)
43
43
  [![Build Status](https://img.shields.io/github/actions/workflow/status/truemagic-coder/solana-agent/ci.yml?branch=main)](https://github.com/truemagic-coder/solana-agent/actions/workflows/ci.yml)
44
- [![Lines of Code](https://tokei.rs/b1/github/truemagic-coder/solana-agent?type=python&category=code&style=flat)](https://github.com/truemagic-coder/solana-agent)
45
44
  [![Ruff Style](https://img.shields.io/badge/style-ruff-41B5BE)](https://github.com/astral-sh/ruff)
46
- [![Libraries.io dependency status for GitHub repo](https://img.shields.io/librariesio/github/truemagic-coder/solana-agent)](https://libraries.io/pypi/solana-agent)
47
45
 
48
46
  ![Solana Agent Logo](https://dl.walletbubbles.com/solana-agent-logo.png?width=200)
49
47
 
@@ -56,7 +54,7 @@ Build your AI agents in three lines of code!
56
54
  * Simple Agent Definition
57
55
  * Fast Responses
58
56
  * Multi-Vendor Support
59
- * Solana Ecosystem Integration
57
+ * Solana Integration
60
58
  * Multi-Agent Swarm
61
59
  * Multi-Modal (Images & Audio & Text)
62
60
  * Conversational Memory & History
@@ -81,7 +79,7 @@ Build your AI agents in three lines of code!
81
79
  * Simple agent definition using JSON
82
80
  * Fast AI responses
83
81
  * Multi-vendor support including OpenAI, Grok, and Gemini AI services
84
- * Solana Ecosystem Integration via [AgentiPy](https://github.com/niceberginc/agentipy)
82
+ * Solana Integration with transfers and swaps
85
83
  * MCP tool usage with first-class support for [Zapier](https://zapier.com/mcp)
86
84
  * Integrated observability and tracing via [Pydantic Logfire](https://pydantic.dev/logfire)
87
85
  * Designed for a multi-agent swarm
@@ -108,7 +106,6 @@ Build your AI agents in three lines of code!
108
106
  * [MongoDB](https://mongodb.com) - Conversational History (optional)
109
107
  * [Zep Cloud](https://getzep.com) - Conversational Memory (optional)
110
108
  * [Pinecone](https://pinecone.io) - Knowledge Base (optional)
111
- * [AgentiPy](https://agentipy.fun) - Solana Ecosystem (optional)
112
109
  * [Zapier](https://zapier.com) - App Integrations (optional)
113
110
  * [Pydantic Logfire](https://pydantic.dev/logfire) - Observability and Tracing (optional)
114
111
 
@@ -658,36 +655,68 @@ Tools empower agents to interact with external systems, fetch data, or perform a
658
655
 
659
656
  Tools can be used from plugins like Solana Agent Kit (sakit) or via inline tools. Tools available via plugins integrate automatically with Solana Agent.
660
657
 
661
- * Agents can use multiple tools per response and should apply the right sequential order (like send an email to bob@bob.com with the latest news on Solana)
662
- * Agents choose the best tools for the job
663
- * Solana Agent doesn't use OpenAI function calling (tools) as they don't support async functions
664
- * Solana Agent tools are async functions
658
+ ### Solana Transfer
665
659
 
666
- ### Solana
660
+ This plugin enables Solana Agent to transfer SOL and SPL tokens from the agent's wallet to the destination wallet.
661
+
662
+ Don't use tickers - but mint addresses in your user queries.
667
663
 
668
664
  `pip install sakit`
669
665
 
670
666
  ```python
671
667
  config = {
672
668
  "tools": {
673
- "solana": {
674
- "private_key": "your-solana-wallet-private-key", # base58 encoded string
675
- "rpc_url": "your-solana-rpc-url",
669
+ "solana_transfer": {
670
+ "rpc_url": "my-rpc-url", # Required - your RPC URL - Helius is recommended
671
+ "private_key": "my-private-key", # Required - base58 string - please use env vars to store the key as it is very confidential
676
672
  },
677
673
  },
678
674
  "agents": [
679
675
  {
680
676
  "name": "solana_expert",
681
- "instructions": "You are an expert Solana blockchain assistant. You always use the Solana tool to perform actions on the Solana blockchain.",
682
- "specialization": "Solana blockchain interaction",
683
- "tools": ["solana"], # Enable the tool for this agent
677
+ "instructions": "You are a Solana expert that can transfer tokens.",
678
+ "specialization": "Solana Blockchain",
679
+ "tools": ["solana_transfer"], # Enable the tool for this agent
684
680
  }
685
- ]
681
+ ],
682
+ }
683
+
684
+ solana_agent = SolanaAgent(config=config)
685
+
686
+ async for response in solana_agent.process("user123", "Transfer 0.01 Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB to DzvqBkUHUhuhHtNKGWSCVEAm2rHdm9bxxdQYC6mZBZyF"):
687
+ print(response, end="")
688
+ ```
689
+
690
+ ### Solana Swap
691
+
692
+ This plugin enables Solana Agent to trade (swap) tokens using Jupiter.
693
+
694
+ Don't use tickers - but mint addresses in your user queries.
695
+
696
+ `pip install sakit`
697
+
698
+ ```python
699
+ config = {
700
+ "tools": {
701
+ "solana_swap": {
702
+ "rpc_url": "my-rpc-url", # Required - your RPC URL - Helius is recommended
703
+ "private_key": "my-private-key", # Required - base58 string - please use env vars to store the key as it is very confidential
704
+ "jupiter_url": "my-custom-url" # Optional - if you are using a custom Jupiter service like Metis from QuickNode
705
+ },
706
+ },
707
+ "agents": [
708
+ {
709
+ "name": "solana_expert",
710
+ "instructions": "You are a Solana expert that can swap tokens.",
711
+ "specialization": "Solana Blockchain",
712
+ "tools": ["solana_swap"], # Enable the tool for this agent
713
+ }
714
+ ],
686
715
  }
687
716
 
688
717
  solana_agent = SolanaAgent(config=config)
689
718
 
690
- async for response in solana_agent.process("user123", "What is my SOL balance?"):
719
+ async for response in solana_agent.process("user123", "Swap 0.01 Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB to So11111111111111111111111111111111111111112"):
691
720
  print(response, end="")
692
721
  ```
693
722
 
@@ -739,7 +768,7 @@ from solana_agent import SolanaAgent
739
768
  config = {
740
769
  "tools": {
741
770
  "mcp": {
742
- "urls": ["my-zapier-mcp-url"],
771
+ "url": "my-zapier-mcp-url",
743
772
  }
744
773
  },
745
774
  "agents": [
@@ -6,9 +6,7 @@
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
7
7
  [![codecov](https://img.shields.io/codecov/c/github/truemagic-coder/solana-agent/main.svg)](https://codecov.io/gh/truemagic-coder/solana-agent)
8
8
  [![Build Status](https://img.shields.io/github/actions/workflow/status/truemagic-coder/solana-agent/ci.yml?branch=main)](https://github.com/truemagic-coder/solana-agent/actions/workflows/ci.yml)
9
- [![Lines of Code](https://tokei.rs/b1/github/truemagic-coder/solana-agent?type=python&category=code&style=flat)](https://github.com/truemagic-coder/solana-agent)
10
9
  [![Ruff Style](https://img.shields.io/badge/style-ruff-41B5BE)](https://github.com/astral-sh/ruff)
11
- [![Libraries.io dependency status for GitHub repo](https://img.shields.io/librariesio/github/truemagic-coder/solana-agent)](https://libraries.io/pypi/solana-agent)
12
10
 
13
11
  ![Solana Agent Logo](https://dl.walletbubbles.com/solana-agent-logo.png?width=200)
14
12
 
@@ -21,7 +19,7 @@ Build your AI agents in three lines of code!
21
19
  * Simple Agent Definition
22
20
  * Fast Responses
23
21
  * Multi-Vendor Support
24
- * Solana Ecosystem Integration
22
+ * Solana Integration
25
23
  * Multi-Agent Swarm
26
24
  * Multi-Modal (Images & Audio & Text)
27
25
  * Conversational Memory & History
@@ -46,7 +44,7 @@ Build your AI agents in three lines of code!
46
44
  * Simple agent definition using JSON
47
45
  * Fast AI responses
48
46
  * Multi-vendor support including OpenAI, Grok, and Gemini AI services
49
- * Solana Ecosystem Integration via [AgentiPy](https://github.com/niceberginc/agentipy)
47
+ * Solana Integration with transfers and swaps
50
48
  * MCP tool usage with first-class support for [Zapier](https://zapier.com/mcp)
51
49
  * Integrated observability and tracing via [Pydantic Logfire](https://pydantic.dev/logfire)
52
50
  * Designed for a multi-agent swarm
@@ -73,7 +71,6 @@ Build your AI agents in three lines of code!
73
71
  * [MongoDB](https://mongodb.com) - Conversational History (optional)
74
72
  * [Zep Cloud](https://getzep.com) - Conversational Memory (optional)
75
73
  * [Pinecone](https://pinecone.io) - Knowledge Base (optional)
76
- * [AgentiPy](https://agentipy.fun) - Solana Ecosystem (optional)
77
74
  * [Zapier](https://zapier.com) - App Integrations (optional)
78
75
  * [Pydantic Logfire](https://pydantic.dev/logfire) - Observability and Tracing (optional)
79
76
 
@@ -623,36 +620,68 @@ Tools empower agents to interact with external systems, fetch data, or perform a
623
620
 
624
621
  Tools can be used from plugins like Solana Agent Kit (sakit) or via inline tools. Tools available via plugins integrate automatically with Solana Agent.
625
622
 
626
- * Agents can use multiple tools per response and should apply the right sequential order (like send an email to bob@bob.com with the latest news on Solana)
627
- * Agents choose the best tools for the job
628
- * Solana Agent doesn't use OpenAI function calling (tools) as they don't support async functions
629
- * Solana Agent tools are async functions
623
+ ### Solana Transfer
630
624
 
631
- ### Solana
625
+ This plugin enables Solana Agent to transfer SOL and SPL tokens from the agent's wallet to the destination wallet.
626
+
627
+ Don't use tickers - but mint addresses in your user queries.
632
628
 
633
629
  `pip install sakit`
634
630
 
635
631
  ```python
636
632
  config = {
637
633
  "tools": {
638
- "solana": {
639
- "private_key": "your-solana-wallet-private-key", # base58 encoded string
640
- "rpc_url": "your-solana-rpc-url",
634
+ "solana_transfer": {
635
+ "rpc_url": "my-rpc-url", # Required - your RPC URL - Helius is recommended
636
+ "private_key": "my-private-key", # Required - base58 string - please use env vars to store the key as it is very confidential
641
637
  },
642
638
  },
643
639
  "agents": [
644
640
  {
645
641
  "name": "solana_expert",
646
- "instructions": "You are an expert Solana blockchain assistant. You always use the Solana tool to perform actions on the Solana blockchain.",
647
- "specialization": "Solana blockchain interaction",
648
- "tools": ["solana"], # Enable the tool for this agent
642
+ "instructions": "You are a Solana expert that can transfer tokens.",
643
+ "specialization": "Solana Blockchain",
644
+ "tools": ["solana_transfer"], # Enable the tool for this agent
649
645
  }
650
- ]
646
+ ],
647
+ }
648
+
649
+ solana_agent = SolanaAgent(config=config)
650
+
651
+ async for response in solana_agent.process("user123", "Transfer 0.01 Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB to DzvqBkUHUhuhHtNKGWSCVEAm2rHdm9bxxdQYC6mZBZyF"):
652
+ print(response, end="")
653
+ ```
654
+
655
+ ### Solana Swap
656
+
657
+ This plugin enables Solana Agent to trade (swap) tokens using Jupiter.
658
+
659
+ Don't use tickers - but mint addresses in your user queries.
660
+
661
+ `pip install sakit`
662
+
663
+ ```python
664
+ config = {
665
+ "tools": {
666
+ "solana_swap": {
667
+ "rpc_url": "my-rpc-url", # Required - your RPC URL - Helius is recommended
668
+ "private_key": "my-private-key", # Required - base58 string - please use env vars to store the key as it is very confidential
669
+ "jupiter_url": "my-custom-url" # Optional - if you are using a custom Jupiter service like Metis from QuickNode
670
+ },
671
+ },
672
+ "agents": [
673
+ {
674
+ "name": "solana_expert",
675
+ "instructions": "You are a Solana expert that can swap tokens.",
676
+ "specialization": "Solana Blockchain",
677
+ "tools": ["solana_swap"], # Enable the tool for this agent
678
+ }
679
+ ],
651
680
  }
652
681
 
653
682
  solana_agent = SolanaAgent(config=config)
654
683
 
655
- async for response in solana_agent.process("user123", "What is my SOL balance?"):
684
+ async for response in solana_agent.process("user123", "Swap 0.01 Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB to So11111111111111111111111111111111111111112"):
656
685
  print(response, end="")
657
686
  ```
658
687
 
@@ -704,7 +733,7 @@ from solana_agent import SolanaAgent
704
733
  config = {
705
734
  "tools": {
706
735
  "mcp": {
707
- "urls": ["my-zapier-mcp-url"],
736
+ "url": "my-zapier-mcp-url",
708
737
  }
709
738
  },
710
739
  "agents": [
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "solana-agent"
3
- version = "29.2.0"
3
+ version = "29.2.2"
4
4
  description = "AI Agents for Solana"
5
5
  authors = ["Bevan Hunt <bevan@bevanhunt.com>"]
6
6
  license = "MIT"
@@ -163,8 +163,10 @@ class OpenAIAdapter(LLMProvider):
163
163
  api_key: Optional[str] = None,
164
164
  base_url: Optional[str] = None,
165
165
  model: Optional[str] = None,
166
- ) -> str: # pragma: no cover
167
- """Generate text from OpenAI models as a single string (no images)."""
166
+ functions: Optional[List[Dict[str, Any]]] = None,
167
+ function_call: Optional[Union[str, Dict[str, Any]]] = None,
168
+ ) -> Any: # pragma: no cover
169
+ """Generate text or function call from OpenAI models."""
168
170
  messages = []
169
171
  if system_prompt:
170
172
  messages.append({"role": "system", "content": system_prompt})
@@ -174,6 +176,10 @@ class OpenAIAdapter(LLMProvider):
174
176
  "messages": messages,
175
177
  "model": model or self.text_model,
176
178
  }
179
+ if functions:
180
+ request_params["functions"] = functions
181
+ if function_call:
182
+ request_params["function_call"] = function_call
177
183
 
178
184
  if api_key and base_url:
179
185
  client = AsyncOpenAI(api_key=api_key, base_url=base_url)
@@ -185,17 +191,13 @@ class OpenAIAdapter(LLMProvider):
185
191
 
186
192
  try:
187
193
  response = await client.chat.completions.create(**request_params)
188
- if response.choices and response.choices[0].message.content:
189
- return response.choices[0].message.content
190
- else:
191
- logger.warning("Received non-streaming response with no content.")
192
- return ""
193
- except OpenAIError as e: # Catch specific OpenAI errors
194
+ return response
195
+ except OpenAIError as e:
194
196
  logger.error(f"OpenAI API error during text generation: {e}")
195
- return f"I apologize, but I encountered an API error: {e}"
197
+ return None
196
198
  except Exception as e:
197
199
  logger.exception(f"Error in generate_text: {e}")
198
- return f"I apologize, but I encountered an unexpected error: {e}"
200
+ return None
199
201
 
200
202
  def _calculate_gpt41_image_cost(self, width: int, height: int, model: str) -> int:
201
203
  """Calculates the token cost for an image with GPT-4.1 models."""
@@ -1,6 +1,8 @@
1
1
  from abc import ABC, abstractmethod
2
2
  from typing import (
3
+ Any,
3
4
  AsyncGenerator,
5
+ Dict,
4
6
  List,
5
7
  Literal,
6
8
  Optional,
@@ -26,7 +28,9 @@ class LLMProvider(ABC):
26
28
  api_key: Optional[str] = None,
27
29
  base_url: Optional[str] = None,
28
30
  model: Optional[str] = None,
29
- ) -> str:
31
+ functions: Optional[List[Dict[str, Any]]] = None,
32
+ function_call: Optional[Union[str, Dict[str, Any]]] = None,
33
+ ) -> Any:
30
34
  """Generate text from the language model."""
31
35
  pass
32
36