solana-agent 28.1.1__py3-none-any.whl → 28.2.1__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/adapters/openai_adapter.py +59 -44
- solana_agent/adapters/pinecone_adapter.py +76 -57
- solana_agent/cli.py +128 -0
- solana_agent/factories/agent_factory.py +35 -16
- solana_agent/plugins/manager.py +24 -8
- solana_agent/plugins/registry.py +23 -10
- solana_agent/repositories/memory.py +18 -10
- solana_agent/services/knowledge_base.py +91 -41
- solana_agent/services/routing.py +14 -9
- {solana_agent-28.1.1.dist-info → solana_agent-28.2.1.dist-info}/METADATA +45 -2
- {solana_agent-28.1.1.dist-info → solana_agent-28.2.1.dist-info}/RECORD +14 -12
- solana_agent-28.2.1.dist-info/entry_points.txt +3 -0
- {solana_agent-28.1.1.dist-info → solana_agent-28.2.1.dist-info}/LICENSE +0 -0
- {solana_agent-28.1.1.dist-info → solana_agent-28.2.1.dist-info}/WHEEL +0 -0
@@ -1,3 +1,4 @@
|
|
1
|
+
import logging
|
1
2
|
from datetime import datetime as dt
|
2
3
|
from typing import Dict, List, Any, Optional, Union
|
3
4
|
import uuid
|
@@ -16,6 +17,9 @@ from solana_agent.interfaces.services.knowledge_base import (
|
|
16
17
|
KnowledgeBaseService as KnowledgeBaseInterface,
|
17
18
|
)
|
18
19
|
|
20
|
+
# Setup logger for this module
|
21
|
+
logger = logging.getLogger(__name__)
|
22
|
+
|
19
23
|
|
20
24
|
class KnowledgeBaseService(KnowledgeBaseInterface):
|
21
25
|
"""
|
@@ -76,8 +80,8 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
76
80
|
raise ValueError(
|
77
81
|
f"Cannot determine dimension for unknown OpenAI model '{openai_model_name}' and Pinecone dimension not configured."
|
78
82
|
)
|
79
|
-
|
80
|
-
f"
|
83
|
+
logger.warning( # Use logger.warning
|
84
|
+
f"Unknown OpenAI model '{openai_model_name}'. Using dimension {openai_dimensions} from Pinecone config. Ensure this is correct."
|
81
85
|
)
|
82
86
|
|
83
87
|
# Instantiate OpenAIEmbedding
|
@@ -90,7 +94,7 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
90
94
|
# embed_batch_size=10 # Optional: Adjust batch size if needed
|
91
95
|
)
|
92
96
|
except Exception as e:
|
93
|
-
|
97
|
+
logger.error(f"Error initializing OpenAIEmbedding: {e}") # Use logger.error
|
94
98
|
raise
|
95
99
|
|
96
100
|
self.semantic_splitter = SemanticSplitterNodeParser(
|
@@ -108,7 +112,9 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
108
112
|
"""Set up MongoDB collection with appropriate indexes."""
|
109
113
|
if not self.mongo.collection_exists(self.collection):
|
110
114
|
self.mongo.create_collection(self.collection)
|
111
|
-
|
115
|
+
logger.info(
|
116
|
+
f"Created MongoDB collection: {self.collection}"
|
117
|
+
) # Use logger.info
|
112
118
|
|
113
119
|
# Indexes for retrieval and filtering
|
114
120
|
self.mongo.create_index(self.collection, [("document_id", 1)], unique=True)
|
@@ -117,7 +123,9 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
117
123
|
self.mongo.create_index(self.collection, [("created_at", -1)])
|
118
124
|
self.mongo.create_index(self.collection, [("tags", 1)])
|
119
125
|
self.mongo.create_index(self.collection, [("is_chunk", 1)])
|
120
|
-
|
126
|
+
logger.info(
|
127
|
+
f"Ensured indexes exist for MongoDB collection: {self.collection}"
|
128
|
+
) # Use logger.info
|
121
129
|
|
122
130
|
async def add_document(
|
123
131
|
self,
|
@@ -156,7 +164,9 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
156
164
|
try:
|
157
165
|
self.mongo.insert_one(self.collection, mongo_doc)
|
158
166
|
except Exception as e:
|
159
|
-
|
167
|
+
logger.error(
|
168
|
+
f"Error inserting document {doc_id} into MongoDB: {e}"
|
169
|
+
) # Use logger.error
|
160
170
|
raise
|
161
171
|
|
162
172
|
# Embed text using OpenAIEmbedding
|
@@ -164,7 +174,7 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
164
174
|
try:
|
165
175
|
embedding = await embed_model.aget_text_embedding(text)
|
166
176
|
except Exception as e:
|
167
|
-
|
177
|
+
logger.error( # Use logger.error
|
168
178
|
f"Error embedding document {doc_id} using {self.openai_model_name}: {e}"
|
169
179
|
)
|
170
180
|
# Decide how to handle - Mongo insert succeeded, embedding failed
|
@@ -190,7 +200,9 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
190
200
|
namespace=namespace,
|
191
201
|
)
|
192
202
|
except Exception as e:
|
193
|
-
|
203
|
+
logger.error(
|
204
|
+
f"Error upserting vector for {doc_id} to Pinecone: {e}"
|
205
|
+
) # Use logger.error
|
194
206
|
# Decide how to handle - Mongo insert succeeded, Pinecone failed
|
195
207
|
raise # Re-raise for now
|
196
208
|
|
@@ -234,9 +246,13 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
234
246
|
reader = pypdf.PdfReader(io.BytesIO(pdf_bytes))
|
235
247
|
extracted_text = "".join(page.extract_text() or "" for page in reader.pages)
|
236
248
|
if not extracted_text.strip():
|
237
|
-
|
249
|
+
logger.warning(
|
250
|
+
f"No text extracted from PDF {parent_doc_id}."
|
251
|
+
) # Use logger.warning
|
238
252
|
except Exception as e:
|
239
|
-
|
253
|
+
logger.error(
|
254
|
+
f"Error reading or extracting text from PDF {parent_doc_id}: {e}"
|
255
|
+
) # Use logger.error
|
240
256
|
raise
|
241
257
|
|
242
258
|
# --- 2. Store Full PDF and Metadata in MongoDB ---
|
@@ -254,16 +270,18 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
254
270
|
}
|
255
271
|
try:
|
256
272
|
self.mongo.insert_one(self.collection, mongo_parent_doc)
|
257
|
-
|
273
|
+
logger.info(
|
274
|
+
f"Stored full PDF {parent_doc_id} in MongoDB."
|
275
|
+
) # Use logger.info
|
258
276
|
except Exception as e: # pragma: no cover
|
259
|
-
|
277
|
+
logger.error( # Use logger.error
|
260
278
|
f"Error inserting parent PDF {parent_doc_id} into MongoDB: {e}"
|
261
279
|
) # pragma: no cover
|
262
280
|
raise # pragma: no cover
|
263
281
|
|
264
282
|
# --- 3. Semantic Chunking ---
|
265
283
|
if not extracted_text.strip():
|
266
|
-
|
284
|
+
logger.info( # Use logger.info
|
267
285
|
f"Skipping chunking for PDF {parent_doc_id} due to no extracted text."
|
268
286
|
)
|
269
287
|
return parent_doc_id
|
@@ -274,16 +292,22 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
274
292
|
nodes = await asyncio.to_thread(
|
275
293
|
self.semantic_splitter.get_nodes_from_documents, [llama_doc]
|
276
294
|
)
|
277
|
-
|
295
|
+
logger.info(
|
296
|
+
f"Generated {len(nodes)} semantic chunks for PDF {parent_doc_id}."
|
297
|
+
) # Use logger.info
|
278
298
|
except Exception as e:
|
279
|
-
|
299
|
+
logger.error(
|
300
|
+
f"Error during semantic chunking for PDF {parent_doc_id}: {e}"
|
301
|
+
) # Use logger.error
|
280
302
|
raise
|
281
303
|
|
282
304
|
# --- 4. Embed Chunks and Batch Upsert to Pinecone ---
|
283
305
|
if not nodes:
|
284
306
|
return parent_doc_id # No chunks generated
|
285
307
|
|
286
|
-
|
308
|
+
logger.info(
|
309
|
+
f"Embedding {len(nodes)} chunks using {self.openai_model_name}..."
|
310
|
+
) # Use logger.info
|
287
311
|
chunk_texts = [node.get_content() for node in nodes]
|
288
312
|
embed_model: OpenAIEmbedding = self.semantic_splitter.embed_model
|
289
313
|
all_chunk_embeddings = []
|
@@ -297,10 +321,14 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
297
321
|
chunk_texts, show_progress=True
|
298
322
|
)
|
299
323
|
except Exception as e:
|
300
|
-
|
324
|
+
logger.error(
|
325
|
+
f"Error embedding chunks for PDF {parent_doc_id}: {e}"
|
326
|
+
) # Use logger.error
|
301
327
|
raise # Stop if embedding fails
|
302
328
|
|
303
|
-
|
329
|
+
logger.info(
|
330
|
+
"Embedding complete. Preparing vectors for Pinecone."
|
331
|
+
) # Use logger.info
|
304
332
|
pinecone_vectors = []
|
305
333
|
for i, node in enumerate(nodes):
|
306
334
|
chunk_id = f"{parent_doc_id}_chunk_{i}"
|
@@ -325,7 +353,7 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
325
353
|
)
|
326
354
|
|
327
355
|
# Upsert vectors in batches using the generic upsert method
|
328
|
-
|
356
|
+
logger.info( # Use logger.info
|
329
357
|
f"Upserting {len(pinecone_vectors)} vectors to Pinecone in batches of {chunk_batch_size}..."
|
330
358
|
)
|
331
359
|
upsert_tasks = []
|
@@ -344,10 +372,12 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
344
372
|
# Check for errors during upsert
|
345
373
|
for idx, result in enumerate(results):
|
346
374
|
if isinstance(result, Exception):
|
347
|
-
|
375
|
+
logger.error(
|
376
|
+
f"Error upserting vector batch {idx + 1} to Pinecone: {result}"
|
377
|
+
) # Use logger.error
|
348
378
|
# Decide on error handling: log, raise, etc.
|
349
379
|
|
350
|
-
|
380
|
+
logger.info(f"Finished processing PDF {parent_doc_id}.") # Use logger.info
|
351
381
|
return parent_doc_id
|
352
382
|
|
353
383
|
async def query(
|
@@ -383,7 +413,9 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
383
413
|
try:
|
384
414
|
query_vector = await embed_model.aget_query_embedding(query_text)
|
385
415
|
except Exception as e:
|
386
|
-
|
416
|
+
logger.error(
|
417
|
+
f"Error embedding query text '{query_text}': {e}"
|
418
|
+
) # Use logger.error
|
387
419
|
return []
|
388
420
|
|
389
421
|
# --- Query Pinecone using the vector ---
|
@@ -399,7 +431,7 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
399
431
|
include_metadata=True, # Need metadata for linking
|
400
432
|
)
|
401
433
|
except Exception as e:
|
402
|
-
|
434
|
+
logger.error(f"Error querying Pinecone: {e}") # Use logger.error
|
403
435
|
return []
|
404
436
|
|
405
437
|
if not pinecone_results:
|
@@ -433,7 +465,9 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
433
465
|
)
|
434
466
|
mongo_docs_map = {doc["document_id"]: doc for doc in mongo_docs}
|
435
467
|
except Exception as e:
|
436
|
-
|
468
|
+
logger.error(
|
469
|
+
f"Error fetching documents from MongoDB: {e}"
|
470
|
+
) # Use logger.error
|
437
471
|
# Proceed with potentially missing Mongo data
|
438
472
|
|
439
473
|
# --- Combine Results ---
|
@@ -520,7 +554,7 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
520
554
|
Returns:
|
521
555
|
True if deletion was successful (or partially successful).
|
522
556
|
"""
|
523
|
-
|
557
|
+
logger.info( # Use logger.info
|
524
558
|
f"Attempting to delete document and associated data for ID: {document_id}"
|
525
559
|
)
|
526
560
|
mongo_deleted_count = 0
|
@@ -548,8 +582,8 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
548
582
|
for doc in docs_to_delete_mongo:
|
549
583
|
mongo_ids_to_delete.add(doc["document_id"])
|
550
584
|
except Exception as e:
|
551
|
-
|
552
|
-
f"
|
585
|
+
logger.warning( # Use logger.warning
|
586
|
+
f"Error finding documents in MongoDB for deletion ({document_id}): {e}. Proceeding with main ID only."
|
553
587
|
)
|
554
588
|
|
555
589
|
pinecone_ids_to_delete = list(mongo_ids_to_delete)
|
@@ -560,12 +594,14 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
560
594
|
await self.pinecone.delete(
|
561
595
|
ids=pinecone_ids_to_delete, namespace=namespace
|
562
596
|
)
|
563
|
-
|
597
|
+
logger.info( # Use logger.info
|
564
598
|
f"Deleted {len(pinecone_ids_to_delete)} vectors from Pinecone for parent {document_id}."
|
565
599
|
)
|
566
600
|
pinecone_deleted = True
|
567
601
|
except Exception as e:
|
568
|
-
|
602
|
+
logger.error(
|
603
|
+
f"Error deleting vectors from Pinecone for {document_id}: {e}"
|
604
|
+
) # Use logger.error
|
569
605
|
|
570
606
|
# --- 3. Delete from MongoDB ---
|
571
607
|
# Use the IDs confirmed to be in Mongo
|
@@ -576,11 +612,13 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
576
612
|
self.collection, {"document_id": {"$in": mongo_ids_found_in_db}}
|
577
613
|
)
|
578
614
|
mongo_deleted_count = delete_result.deleted_count
|
579
|
-
|
615
|
+
logger.info( # Use logger.info
|
580
616
|
f"Deleted {mongo_deleted_count} documents from MongoDB for parent {document_id}."
|
581
617
|
)
|
582
618
|
except Exception as e:
|
583
|
-
|
619
|
+
logger.error(
|
620
|
+
f"Error deleting documents from MongoDB for {document_id}: {e}"
|
621
|
+
) # Use logger.error
|
584
622
|
|
585
623
|
return pinecone_deleted or mongo_deleted_count > 0
|
586
624
|
|
@@ -606,14 +644,20 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
606
644
|
"""
|
607
645
|
current_doc = self.mongo.find_one(self.collection, {"document_id": document_id})
|
608
646
|
if not current_doc:
|
609
|
-
|
647
|
+
logger.warning(
|
648
|
+
f"Document {document_id} not found for update."
|
649
|
+
) # Use logger.warning
|
610
650
|
return False
|
611
651
|
|
612
652
|
if current_doc.get("is_chunk"):
|
613
|
-
|
653
|
+
logger.warning(
|
654
|
+
f"Cannot update chunk {document_id} directly."
|
655
|
+
) # Use logger.warning
|
614
656
|
return False
|
615
657
|
if current_doc.get("pdf_data") and text is not None:
|
616
|
-
|
658
|
+
logger.warning(
|
659
|
+
"Cannot update PDF content via this method. Delete and re-add."
|
660
|
+
) # Use logger.warning
|
617
661
|
return False
|
618
662
|
|
619
663
|
update_text = text is not None and not current_doc.get("pdf_data")
|
@@ -637,7 +681,9 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
637
681
|
)
|
638
682
|
mongo_updated = update_result.modified_count > 0
|
639
683
|
except Exception as e:
|
640
|
-
|
684
|
+
logger.error(
|
685
|
+
f"Error updating document {document_id} in MongoDB: {e}"
|
686
|
+
) # Use logger.error
|
641
687
|
# Decide if we should proceed to Pinecone update if Mongo failed
|
642
688
|
return False # Return False if Mongo update fails
|
643
689
|
|
@@ -649,7 +695,9 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
649
695
|
try:
|
650
696
|
embedding = await embed_model.aget_text_embedding(text_content)
|
651
697
|
except Exception as e:
|
652
|
-
|
698
|
+
logger.error(
|
699
|
+
f"Error embedding updated text for {document_id}: {e}"
|
700
|
+
) # Use logger.error
|
653
701
|
# Mongo update might have succeeded, but embedding failed
|
654
702
|
return mongo_updated # Return based on Mongo success
|
655
703
|
|
@@ -685,7 +733,7 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
685
733
|
)
|
686
734
|
pinecone_updated = True
|
687
735
|
except Exception as e:
|
688
|
-
|
736
|
+
logger.error( # Use logger.error
|
689
737
|
f"Error upserting updated vector in Pinecone for {document_id}: {e}"
|
690
738
|
)
|
691
739
|
# Mongo update succeeded, Pinecone failed
|
@@ -750,7 +798,7 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
750
798
|
try:
|
751
799
|
self.mongo.insert_many(self.collection, mongo_batch)
|
752
800
|
except Exception as e:
|
753
|
-
|
801
|
+
logger.error( # Use logger.error
|
754
802
|
f"Error inserting batch {i // batch_size + 1} into MongoDB: {e}"
|
755
803
|
)
|
756
804
|
# Decide if we should skip Pinecone for this batch
|
@@ -762,7 +810,7 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
762
810
|
batch_texts, show_progress=True
|
763
811
|
)
|
764
812
|
except Exception as e:
|
765
|
-
|
813
|
+
logger.error( # Use logger.error
|
766
814
|
f"Error embedding batch {i // batch_size + 1} using {self.openai_model_name}: {e}"
|
767
815
|
)
|
768
816
|
continue # Skip Pinecone upsert for this batch
|
@@ -795,7 +843,7 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
795
843
|
vectors=pinecone_vectors, namespace=namespace
|
796
844
|
)
|
797
845
|
except Exception as e:
|
798
|
-
|
846
|
+
logger.error( # Use logger.error
|
799
847
|
f"Error upserting vector batch {i // batch_size + 1} to Pinecone: {e}"
|
800
848
|
)
|
801
849
|
|
@@ -818,5 +866,7 @@ class KnowledgeBaseService(KnowledgeBaseInterface):
|
|
818
866
|
try:
|
819
867
|
return self.mongo.find_one(self.collection, {"document_id": document_id})
|
820
868
|
except Exception as e:
|
821
|
-
|
869
|
+
logger.error(
|
870
|
+
f"Error retrieving full document {document_id} from MongoDB: {e}"
|
871
|
+
) # Use logger.error
|
822
872
|
return None
|
solana_agent/services/routing.py
CHANGED
@@ -5,6 +5,7 @@ This service manages query routing to appropriate agents based on
|
|
5
5
|
specializations and query analysis.
|
6
6
|
"""
|
7
7
|
|
8
|
+
import logging
|
8
9
|
from typing import Dict, List, Optional, Any
|
9
10
|
from solana_agent.interfaces.services.routing import (
|
10
11
|
RoutingService as RoutingServiceInterface,
|
@@ -13,6 +14,9 @@ from solana_agent.interfaces.services.agent import AgentService
|
|
13
14
|
from solana_agent.interfaces.providers.llm import LLMProvider
|
14
15
|
from solana_agent.domains.routing import QueryAnalysis
|
15
16
|
|
17
|
+
# Setup logger for this module
|
18
|
+
logger = logging.getLogger(__name__)
|
19
|
+
|
16
20
|
|
17
21
|
class RoutingService(RoutingServiceInterface):
|
18
22
|
"""Service for routing queries to appropriate agents."""
|
@@ -67,19 +71,19 @@ class RoutingService(RoutingServiceInterface):
|
|
67
71
|
|
68
72
|
prompt = f"""
|
69
73
|
Analyze this user query and determine which agent would be best suited to answer it.
|
70
|
-
|
74
|
+
|
71
75
|
AVAILABLE AGENTS AND THEIR SPECIALIZATIONS:
|
72
76
|
{specializations_text}
|
73
|
-
|
77
|
+
|
74
78
|
USER QUERY: {query}
|
75
|
-
|
79
|
+
|
76
80
|
Please determine:
|
77
81
|
1. Which agent is the primary best match for this query (must be one of the listed agents)
|
78
82
|
2. Any secondary agents that might be helpful (must be from the listed agents)
|
79
83
|
3. The complexity level (1-5, where 5 is most complex)
|
80
84
|
4. Any key topics or technologies mentioned
|
81
|
-
|
82
|
-
Think carefully about whether the query is more technical/development-focused or more
|
85
|
+
|
86
|
+
Think carefully about whether the query is more technical/development-focused or more
|
83
87
|
financial/market-focused to match with the appropriate agent.
|
84
88
|
"""
|
85
89
|
|
@@ -101,7 +105,7 @@ class RoutingService(RoutingServiceInterface):
|
|
101
105
|
"confidence": analysis.confidence,
|
102
106
|
}
|
103
107
|
except Exception as e:
|
104
|
-
|
108
|
+
logger.error(f"Error analyzing query: {e}") # Use logger.error
|
105
109
|
# Return default analysis on error
|
106
110
|
return {
|
107
111
|
"primary_specialization": list(agents.keys())[0]
|
@@ -125,8 +129,9 @@ class RoutingService(RoutingServiceInterface):
|
|
125
129
|
# If only one agent - use that agent
|
126
130
|
agents = self.agent_service.get_all_ai_agents()
|
127
131
|
if len(agents) == 1:
|
128
|
-
|
129
|
-
|
132
|
+
agent_name = next(iter(agents.keys()))
|
133
|
+
logger.info(f"Only one agent available: {agent_name}") # Use logger.info
|
134
|
+
return agent_name
|
130
135
|
|
131
136
|
# Analyze query
|
132
137
|
analysis = await self._analyze_query(query)
|
@@ -190,7 +195,7 @@ class RoutingService(RoutingServiceInterface):
|
|
190
195
|
|
191
196
|
# Sort by score
|
192
197
|
agent_scores.sort(key=lambda x: x[1], reverse=True)
|
193
|
-
|
198
|
+
logger.debug(f"Agent scores: {agent_scores}") # Use logger.debug
|
194
199
|
|
195
200
|
# Return the highest scoring agent, if any
|
196
201
|
if agent_scores and agent_scores[0][1] > 0:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: solana-agent
|
3
|
-
Version: 28.
|
3
|
+
Version: 28.2.1
|
4
4
|
Summary: AI Agents for Solana
|
5
5
|
License: MIT
|
6
6
|
Keywords: solana,solana ai,solana agent,ai,ai agent,ai agents
|
@@ -23,7 +23,9 @@ Requires-Dist: pinecone (>=6.0.2,<7.0.0)
|
|
23
23
|
Requires-Dist: pydantic (>=2)
|
24
24
|
Requires-Dist: pymongo (>=4.12.0,<5.0.0)
|
25
25
|
Requires-Dist: pypdf (>=5.4.0,<6.0.0)
|
26
|
+
Requires-Dist: rich (>=13)
|
26
27
|
Requires-Dist: scrubadub (>=2.0.1,<3.0.0)
|
28
|
+
Requires-Dist: typer (>=0.15.2,<0.16.0)
|
27
29
|
Requires-Dist: zep-cloud (>=2.10.1,<3.0.0)
|
28
30
|
Project-URL: Documentation, https://docs.solana-agent.com
|
29
31
|
Project-URL: Homepage, https://solana-agent.com
|
@@ -284,6 +286,47 @@ async for response in solana_agent.process("user123", audio_content, audio_input
|
|
284
286
|
print(response, end="")
|
285
287
|
```
|
286
288
|
|
289
|
+
### Command Line Interface (CLI)
|
290
|
+
|
291
|
+
Solana Agent includes a command-line interface (CLI) for text-based chat using a configuration file.
|
292
|
+
|
293
|
+
Ensure you have a valid configuration file (e.g., `config.json`) containing at least your OpenAI API key and agent definitions.
|
294
|
+
|
295
|
+
**./config.json**
|
296
|
+
```json
|
297
|
+
{
|
298
|
+
"openai": {
|
299
|
+
"api_key": "your-openai-api-key"
|
300
|
+
},
|
301
|
+
"agents": [
|
302
|
+
{
|
303
|
+
"name": "default_agent",
|
304
|
+
"instructions": "You are a helpful AI assistant.",
|
305
|
+
"specialization": "general"
|
306
|
+
}
|
307
|
+
]
|
308
|
+
}
|
309
|
+
```
|
310
|
+
|
311
|
+
Also ensure that you have `pip install uv` to call `uvx`.
|
312
|
+
|
313
|
+
```bash
|
314
|
+
uvx solana-agent [OPTIONS]
|
315
|
+
|
316
|
+
Options:
|
317
|
+
|
318
|
+
--user-id TEXT: The user ID for the conversation (default: cli_user).
|
319
|
+
--config TEXT: Path to the configuration JSON file (default: config.json).
|
320
|
+
--prompt TEXT: Optional system prompt override for the agent.
|
321
|
+
--help: Show help message and exit.
|
322
|
+
|
323
|
+
# Using default config.json and user_id
|
324
|
+
uvx solana-agent
|
325
|
+
|
326
|
+
# Specifying user ID and config path
|
327
|
+
uvx solana-agent --user-id my_cli_session --config ./my_agent_config.json
|
328
|
+
```
|
329
|
+
|
287
330
|
## Optional Feature Configs
|
288
331
|
|
289
332
|
### Business Alignment
|
@@ -542,7 +585,7 @@ config = {
|
|
542
585
|
"rpc_url": "your-solana-rpc-url",
|
543
586
|
},
|
544
587
|
},
|
545
|
-
"
|
588
|
+
"agents": [
|
546
589
|
{
|
547
590
|
"name": "solana_expert",
|
548
591
|
"instructions": "You are an expert Solana blockchain assistant. You always use the Solana tool to perform actions on the Solana blockchain.",
|
@@ -1,15 +1,16 @@
|
|
1
1
|
solana_agent/__init__.py,sha256=g83qhMOCwcWL19V4CYbQwl0Ykpb0xn49OUh05i-pu3g,1001
|
2
2
|
solana_agent/adapters/__init__.py,sha256=tiEEuuy0NF3ngc_tGEcRTt71zVI58v3dYY9RvMrF2Cg,204
|
3
3
|
solana_agent/adapters/mongodb_adapter.py,sha256=0KWIa6kaFbUFvtKUzuV_0p0RFlPPGKrDVIEU2McVY3k,2734
|
4
|
-
solana_agent/adapters/openai_adapter.py,sha256=
|
5
|
-
solana_agent/adapters/pinecone_adapter.py,sha256=
|
4
|
+
solana_agent/adapters/openai_adapter.py,sha256=rSa1yYYIpr5ES3Zw0DZm7iGp59p0WYBQXH0EQ1UDAB4,13594
|
5
|
+
solana_agent/adapters/pinecone_adapter.py,sha256=XlfOpoKHwzpaU4KZnovO2TnEYbsw-3B53ZKQDtBeDgU,23847
|
6
|
+
solana_agent/cli.py,sha256=FGvTIQmKLp6XsQdyKtuhIIfbBtMmcCCXfigNrj4bzMc,4704
|
6
7
|
solana_agent/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
8
|
solana_agent/client/solana_agent.py,sha256=jUGWxYJL9ZWxGsVX9C6FrRQyX7r6Cep0ijcfm7cbkJI,10098
|
8
9
|
solana_agent/domains/__init__.py,sha256=HiC94wVPRy-QDJSSRywCRrhrFfTBeHjfi5z-QfZv46U,168
|
9
10
|
solana_agent/domains/agent.py,sha256=3Q1wg4eIul0CPpaYBOjEthKTfcdhf1SAiWc2R-IMGO8,2561
|
10
11
|
solana_agent/domains/routing.py,sha256=1yR4IswGcmREGgbOOI6TKCfuM7gYGOhQjLkBqnZ-rNo,582
|
11
12
|
solana_agent/factories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
|
-
solana_agent/factories/agent_factory.py,sha256=
|
13
|
+
solana_agent/factories/agent_factory.py,sha256=kduhtCMAxiPmCW_wx-hGGlhehRRGt4OBKY8r-R-LZnI,13246
|
13
14
|
solana_agent/guardrails/pii.py,sha256=FCz1IC3mmkr41QFFf5NaC0fwJrVkwFsxgyOCS2POO5I,4428
|
14
15
|
solana_agent/interfaces/__init__.py,sha256=IQs1WIM1FeKP1-kY2FEfyhol_dB-I-VAe2rD6jrVF6k,355
|
15
16
|
solana_agent/interfaces/client/client.py,sha256=hsvaQiQdz3MLMNc77oD6ocvvnyl7Ez2n087ptFDA19M,3687
|
@@ -24,18 +25,19 @@ solana_agent/interfaces/services/knowledge_base.py,sha256=HsU4fAMc_oOUCqCX2z76_I
|
|
24
25
|
solana_agent/interfaces/services/query.py,sha256=QfpBA3hrv8pQdNbK05hbu3Vh3-53F46IFcoUjwj5J9w,1568
|
25
26
|
solana_agent/interfaces/services/routing.py,sha256=Qbn3-DQGVSQKaegHDekSFmn_XCklA0H2f0XUx9-o3wA,367
|
26
27
|
solana_agent/plugins/__init__.py,sha256=coZdgJKq1ExOaj6qB810i3rEhbjdVlrkN76ozt_Ojgo,193
|
27
|
-
solana_agent/plugins/manager.py,sha256=
|
28
|
-
solana_agent/plugins/registry.py,sha256=
|
28
|
+
solana_agent/plugins/manager.py,sha256=mO_dKSVJ8GToD3wZflMcpKDEBXRoaaMRtY267HENCI0,5542
|
29
|
+
solana_agent/plugins/registry.py,sha256=VAG0BWdUUIsEE-VpATtHi8qat7ziPuh7pKuzGXauwgc,4173
|
29
30
|
solana_agent/plugins/tools/__init__.py,sha256=VDjJxvUjefIy10VztQ9WDKgIegvDbIXBQWsHLhxdZ3o,125
|
30
31
|
solana_agent/plugins/tools/auto_tool.py,sha256=uihijtlc9CCqCIaRcwPuuN7o1SHIpWL2GV3vr33GG3E,1576
|
31
32
|
solana_agent/repositories/__init__.py,sha256=fP83w83CGzXLnSdq-C5wbw9EhWTYtqE2lQTgp46-X_4,163
|
32
|
-
solana_agent/repositories/memory.py,sha256=
|
33
|
+
solana_agent/repositories/memory.py,sha256=e-27ju6wmurxSxULzr_uDHxxdnvw8KrJt9NWyvAz-i4,7684
|
33
34
|
solana_agent/services/__init__.py,sha256=iko0c2MlF8b_SA_nuBGFllr2E3g_JowOrOzGcnU9tkA,162
|
34
35
|
solana_agent/services/agent.py,sha256=9FB1Tj7v8JwJVVmZwK8IOSrBbgbV4iFZOtFHzw3gcEs,41780
|
35
|
-
solana_agent/services/knowledge_base.py,sha256=
|
36
|
+
solana_agent/services/knowledge_base.py,sha256=D4QNGC3Z8E7iX-CEGpRks0lW4wWJt-WorO3J8mu6ayU,35318
|
36
37
|
solana_agent/services/query.py,sha256=bAoUfe_2EBVEVeh99-2E9KZ0zaHUzf7Lqel3rlHyNX8,17459
|
37
|
-
solana_agent/services/routing.py,sha256
|
38
|
-
solana_agent-28.
|
39
|
-
solana_agent-28.
|
40
|
-
solana_agent-28.
|
41
|
-
solana_agent-28.
|
38
|
+
solana_agent/services/routing.py,sha256=C5Ku4t9TqvY7S8wlUPMTC04HCrT4Ib3E8Q8yX0lVU_s,7137
|
39
|
+
solana_agent-28.2.1.dist-info/LICENSE,sha256=BnSRc-NSFuyF2s496l_4EyrwAP6YimvxWcjPiJ0J7g4,1057
|
40
|
+
solana_agent-28.2.1.dist-info/METADATA,sha256=2tCGkpcfk_gc4uK-0yk5xUIVwUmlWpDIvYgeX45N-9E,28283
|
41
|
+
solana_agent-28.2.1.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
42
|
+
solana_agent-28.2.1.dist-info/entry_points.txt,sha256=-AuT_mfqk8dlZ0pHuAjx1ouAWpTRjpqvEUa6YV3lmc0,53
|
43
|
+
solana_agent-28.2.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|