solana-agent 31.2.4__py3-none-any.whl → 31.2.6__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/domains/routing.py +16 -6
- solana_agent/services/routing.py +32 -21
- {solana_agent-31.2.4.dist-info → solana_agent-31.2.6.dist-info}/METADATA +5 -5
- {solana_agent-31.2.4.dist-info → solana_agent-31.2.6.dist-info}/RECORD +7 -7
- {solana_agent-31.2.4.dist-info → solana_agent-31.2.6.dist-info}/LICENSE +0 -0
- {solana_agent-31.2.4.dist-info → solana_agent-31.2.6.dist-info}/WHEEL +0 -0
- {solana_agent-31.2.4.dist-info → solana_agent-31.2.6.dist-info}/entry_points.txt +0 -0
solana_agent/domains/routing.py
CHANGED
@@ -5,10 +5,20 @@ from pydantic import BaseModel, Field
|
|
5
5
|
class QueryAnalysis(BaseModel):
|
6
6
|
"""Analysis of a user query for routing purposes."""
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
primary_agent: str = Field(
|
9
|
+
...,
|
10
|
+
description="Name of the primary agent that should handle this query (must be one of the available agent names)",
|
11
|
+
)
|
12
|
+
secondary_agents: List[str] = Field(
|
13
|
+
default_factory=list,
|
14
|
+
description="Names of secondary agents that might be helpful (must be from the available agent names)",
|
15
|
+
)
|
16
|
+
complexity_level: int = Field(
|
17
|
+
default=1, description="Complexity level (1-5)", ge=1, le=5
|
18
|
+
)
|
19
|
+
topics: List[str] = Field(
|
20
|
+
default_factory=list, description="Key topics in the query"
|
21
|
+
)
|
22
|
+
confidence: float = Field(
|
23
|
+
default=0.5, description="Confidence in the analysis", ge=0.0, le=1.0
|
11
24
|
)
|
12
|
-
complexity_level: int = Field(..., description="Complexity level (1-5)")
|
13
|
-
topics: List[str] = Field(..., description="Key topics in the query")
|
14
|
-
confidence: float = Field(..., description="Confidence in the analysis")
|
solana_agent/services/routing.py
CHANGED
@@ -1,11 +1,3 @@
|
|
1
|
-
"""
|
2
|
-
Routing service implementation.
|
3
|
-
|
4
|
-
This service manages query routing to appropriate agents using an LLM-based
|
5
|
-
analysis. It defaults to a small, low-cost model for routing to minimize
|
6
|
-
overhead while maintaining quality.
|
7
|
-
"""
|
8
|
-
|
9
1
|
import logging
|
10
2
|
from typing import Dict, List, Optional, Any
|
11
3
|
from solana_agent.interfaces.services.routing import (
|
@@ -81,37 +73,48 @@ class RoutingService(RoutingServiceInterface):
|
|
81
73
|
|
82
74
|
USER QUERY: {query}
|
83
75
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
76
|
+
ROUTING RULES:
|
77
|
+
- Match the user query to the agent whose specialization best fits the user's intent
|
78
|
+
- Return the EXACT agent name that matches best
|
79
|
+
|
80
|
+
INSTRUCTIONS:
|
81
|
+
- primary_agent: The exact name of the best matching agent (e.g., "onboarding", "event_feedback")
|
82
|
+
- secondary_agents: Other agents that might help (usually empty)
|
83
|
+
- complexity_level: 1-5 (5 being most complex)
|
84
|
+
- topics: Key topics mentioned
|
85
|
+
- confidence: 0.0-1.0 (how confident you are in this routing decision)
|
86
|
+
|
87
|
+
For the query "{query}", which agent should handle it?
|
89
88
|
"""
|
90
89
|
|
91
90
|
try:
|
92
91
|
analysis = await self.llm_provider.parse_structured_output(
|
93
92
|
prompt=prompt,
|
94
|
-
system_prompt="
|
93
|
+
system_prompt="You are an expert at routing user queries to the most appropriate AI agent. Always return the exact agent name that best matches the user's needs based on the specializations provided. If the user mentions a specific topic, prioritize agents whose specialization matches that topic.",
|
95
94
|
model_class=QueryAnalysis,
|
96
95
|
api_key=self.api_key,
|
97
96
|
base_url=self.base_url,
|
98
97
|
model=self.model,
|
99
98
|
)
|
100
99
|
|
100
|
+
logger.debug(f"LLM analysis result: {analysis}")
|
101
|
+
|
101
102
|
return {
|
102
|
-
"primary_specialization": analysis.
|
103
|
-
"secondary_specializations": analysis.
|
103
|
+
"primary_specialization": analysis.primary_agent,
|
104
|
+
"secondary_specializations": analysis.secondary_agents,
|
104
105
|
"complexity_level": analysis.complexity_level,
|
105
106
|
"topics": analysis.topics,
|
106
107
|
"confidence": analysis.confidence,
|
107
108
|
}
|
108
109
|
except Exception as e:
|
109
|
-
logger.error(f"Error analyzing query: {e}")
|
110
|
+
logger.error(f"Error analyzing query: {e}")
|
111
|
+
logger.debug(f"Query that failed: {query}")
|
112
|
+
logger.debug(f"Available agents: {list(agents.keys())}")
|
110
113
|
# Return default analysis on error
|
114
|
+
first_agent = list(agents.keys())[0] if agents else "general"
|
115
|
+
logger.debug(f"Defaulting to first agent: {first_agent}")
|
111
116
|
return {
|
112
|
-
"primary_specialization":
|
113
|
-
if agents
|
114
|
-
else "general",
|
117
|
+
"primary_specialization": first_agent,
|
115
118
|
"secondary_specializations": [],
|
116
119
|
"complexity_level": 1,
|
117
120
|
"topics": [],
|
@@ -143,9 +146,11 @@ class RoutingService(RoutingServiceInterface):
|
|
143
146
|
|
144
147
|
# Always analyze with a small model to select the best agent
|
145
148
|
analysis = await self._analyze_query(query)
|
149
|
+
logger.debug(f"Routing analysis for query '{query}': {analysis}")
|
146
150
|
best_agent = await self._find_best_ai_agent(
|
147
151
|
analysis["primary_specialization"], analysis["secondary_specializations"]
|
148
152
|
)
|
153
|
+
logger.debug(f"Selected agent: {best_agent}")
|
149
154
|
chosen = best_agent or next(iter(agents.keys()))
|
150
155
|
self._last_agent = chosen
|
151
156
|
return chosen
|
@@ -171,6 +176,7 @@ class RoutingService(RoutingServiceInterface):
|
|
171
176
|
|
172
177
|
# First, check if primary_specialization is directly an agent name
|
173
178
|
if primary_specialization in ai_agents:
|
179
|
+
logger.debug(f"Direct agent match: {primary_specialization}")
|
174
180
|
return primary_specialization
|
175
181
|
|
176
182
|
# If not a direct agent name match, use specialization matching
|
@@ -185,6 +191,9 @@ class RoutingService(RoutingServiceInterface):
|
|
185
191
|
or primary_specialization.lower() in agent.specialization.lower()
|
186
192
|
):
|
187
193
|
score += 10
|
194
|
+
logger.debug(
|
195
|
+
f"Specialization match for {agent_id}: '{agent.specialization}' matches '{primary_specialization}'"
|
196
|
+
)
|
188
197
|
|
189
198
|
# Check secondary specializations
|
190
199
|
for sec_spec in secondary_specializations:
|
@@ -209,6 +218,8 @@ class RoutingService(RoutingServiceInterface):
|
|
209
218
|
|
210
219
|
# If no match found, return first agent as fallback
|
211
220
|
if ai_agents:
|
212
|
-
|
221
|
+
fallback_agent = next(iter(ai_agents.keys()))
|
222
|
+
logger.debug(f"No match found, using fallback agent: {fallback_agent}")
|
223
|
+
return fallback_agent
|
213
224
|
|
214
225
|
return None
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: solana-agent
|
3
|
-
Version: 31.2.
|
3
|
+
Version: 31.2.6
|
4
4
|
Summary: AI Agents for Solana
|
5
5
|
License: MIT
|
6
6
|
Keywords: solana,solana ai,solana agent,ai,ai agent,ai agents
|
@@ -15,14 +15,14 @@ Classifier: Programming Language :: Python :: 3.12
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.13
|
16
16
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
17
17
|
Requires-Dist: instructor (==1.11.3)
|
18
|
-
Requires-Dist: llama-index-core (==0.14.
|
18
|
+
Requires-Dist: llama-index-core (==0.14.1)
|
19
19
|
Requires-Dist: llama-index-embeddings-openai (==0.5.1)
|
20
|
-
Requires-Dist: logfire (==4.
|
21
|
-
Requires-Dist: openai (==1.107.
|
20
|
+
Requires-Dist: logfire (==4.7.0)
|
21
|
+
Requires-Dist: openai (==1.107.2)
|
22
22
|
Requires-Dist: pillow (==11.3.0)
|
23
23
|
Requires-Dist: pinecone[asyncio] (==7.3.0)
|
24
24
|
Requires-Dist: pydantic (>=2)
|
25
|
-
Requires-Dist: pymongo (==4.
|
25
|
+
Requires-Dist: pymongo (==4.15.0)
|
26
26
|
Requires-Dist: pypdf (==6.0.0)
|
27
27
|
Requires-Dist: rich (>=13,<14.0)
|
28
28
|
Requires-Dist: scrubadub (==2.0.1)
|
@@ -10,7 +10,7 @@ solana_agent/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
10
10
|
solana_agent/client/solana_agent.py,sha256=hLtiR3xD1eFww7XRdg4dTvxlJnTCepilYmEfABn9L7E,10344
|
11
11
|
solana_agent/domains/__init__.py,sha256=HiC94wVPRy-QDJSSRywCRrhrFfTBeHjfi5z-QfZv46U,168
|
12
12
|
solana_agent/domains/agent.py,sha256=8pAi1-kIgzFNANt3dyQjw-1zbThcNdpEllbAGWi79uI,2841
|
13
|
-
solana_agent/domains/routing.py,sha256=
|
13
|
+
solana_agent/domains/routing.py,sha256=rb7YyeH4CJmjtuoBMk7f8kUFddcT5tUBZ9Bj8mJ4VV8,845
|
14
14
|
solana_agent/factories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
15
|
solana_agent/factories/agent_factory.py,sha256=d9VuD5E9khqVXU_Qu67zKU2yVvXHK2EmercDmSZ4stk,14226
|
16
16
|
solana_agent/guardrails/pii.py,sha256=FCz1IC3mmkr41QFFf5NaC0fwJrVkwFsxgyOCS2POO5I,4428
|
@@ -40,9 +40,9 @@ solana_agent/services/agent.py,sha256=LWjsdmCeygwmjFoazOCVhrb0hdZHQDEQo_DFWZe57L
|
|
40
40
|
solana_agent/services/knowledge_base.py,sha256=ZvOPrSmcNDgUzz4bJIQ4LeRl9vMZiK9hOfs71IpB7Bk,32735
|
41
41
|
solana_agent/services/query.py,sha256=oqNFbQsz2FiSswGkt8ZlNaOR8DAz66hgWXD5kHc7c-M,71428
|
42
42
|
solana_agent/services/realtime.py,sha256=6_44-JaKN0V4gkizaisGLPsopM5Z8xymQcCbq5V3yEc,21054
|
43
|
-
solana_agent/services/routing.py,sha256=
|
44
|
-
solana_agent-31.2.
|
45
|
-
solana_agent-31.2.
|
46
|
-
solana_agent-31.2.
|
47
|
-
solana_agent-31.2.
|
48
|
-
solana_agent-31.2.
|
43
|
+
solana_agent/services/routing.py,sha256=FXVeOwcJiZ77JEcr2Xbd_tJaWCTqcct7KJmwKtyl-io,8602
|
44
|
+
solana_agent-31.2.6.dist-info/LICENSE,sha256=BnSRc-NSFuyF2s496l_4EyrwAP6YimvxWcjPiJ0J7g4,1057
|
45
|
+
solana_agent-31.2.6.dist-info/METADATA,sha256=e8tQOCFEg87jPmG_e22ZsrgknGkqREuJn3LaHuYGOWw,31168
|
46
|
+
solana_agent-31.2.6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
47
|
+
solana_agent-31.2.6.dist-info/entry_points.txt,sha256=-AuT_mfqk8dlZ0pHuAjx1ouAWpTRjpqvEUa6YV3lmc0,53
|
48
|
+
solana_agent-31.2.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|