solana-agent 17.0.2__py3-none-any.whl → 17.0.4__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.
@@ -39,6 +39,7 @@ class AgentService(AgentServiceInterface):
39
39
  self.agent_repository = agent_repository
40
40
  self.organization_mission = organization_mission
41
41
  self.config = config or {}
42
+ self.last_text_response = ""
42
43
 
43
44
  # Initialize tool registry with concrete implementation
44
45
  if tool_registry:
@@ -247,6 +248,8 @@ class AgentService(AgentServiceInterface):
247
248
  if memory_context:
248
249
  system_prompt += f"\n\nMemory Context: {memory_context}"
249
250
 
251
+ # Keep track of the complete text response
252
+ complete_text_response = ""
250
253
  json_buffer = ""
251
254
  is_json = False
252
255
  text_buffer = ""
@@ -277,6 +280,9 @@ class AgentService(AgentServiceInterface):
277
280
  json_chunk=json_buffer
278
281
  )
279
282
 
283
+ # Add to complete text response
284
+ complete_text_response += response_text
285
+
280
286
  # Output response based on format
281
287
  if output_format == "audio":
282
288
  async for audio_chunk in self.llm_provider.tts(
@@ -288,7 +294,9 @@ class AgentService(AgentServiceInterface):
288
294
  else:
289
295
  yield response_text
290
296
  else:
291
- # Not a tool call, return as normal text
297
+ # For non-tool JSON, still capture the text
298
+ complete_text_response += json_buffer
299
+
292
300
  if output_format == "audio":
293
301
  async for audio_chunk in self.llm_provider.tts(
294
302
  text=json_buffer,
@@ -304,10 +312,12 @@ class AgentService(AgentServiceInterface):
304
312
  json_buffer = ""
305
313
 
306
314
  except json.JSONDecodeError:
307
- # Incomplete JSON, continue collecting
308
315
  pass
309
316
  else:
310
- # Regular text processing
317
+ # For regular text, always add to the complete response
318
+ complete_text_response += chunk
319
+
320
+ # Handle audio buffering or direct text output
311
321
  if output_format == "audio":
312
322
  text_buffer += chunk
313
323
  if any(punct in chunk for punct in ".!?"):
@@ -326,18 +336,25 @@ class AgentService(AgentServiceInterface):
326
336
  if text_buffer:
327
337
  remaining_text += text_buffer
328
338
  if is_json and json_buffer:
329
- # If we have incomplete JSON at the end, yield it as text
330
339
  remaining_text += json_buffer
331
340
 
332
- if remaining_text and output_format == "audio":
333
- async for audio_chunk in self.llm_provider.tts(
334
- text=remaining_text,
335
- voice=audio_voice,
336
- response_format=audio_output_format
337
- ):
338
- yield audio_chunk
339
- elif remaining_text:
340
- yield remaining_text
341
+ if remaining_text:
342
+ # Add remaining text to complete response
343
+ complete_text_response += remaining_text
344
+
345
+ if output_format == "audio":
346
+ async for audio_chunk in self.llm_provider.tts(
347
+ text=remaining_text,
348
+ voice=audio_voice,
349
+ response_format=audio_output_format
350
+ ):
351
+ yield audio_chunk
352
+ else:
353
+ yield remaining_text
354
+
355
+ # Store the complete text response for the caller to access
356
+ # This needs to be done in the query service using the self.last_text_response
357
+ self.last_text_response = complete_text_response
341
358
 
342
359
  except Exception as e:
343
360
  error_msg = f"I apologize, but I encountered an error: {str(e)}"
@@ -52,11 +52,8 @@ class QueryService(QueryServiceInterface):
52
52
  Args:
53
53
  user_id: User ID
54
54
  query: Text query or audio bytes
55
- output_format: Response format ("text" or "audio")
56
- audio_voice: Voice to use for audio output
57
- audio_instructions: Optional instructions for audio synthesis
58
- audio_output_format: Audio output format
59
- audio_input_format: Audio input format
55
+ output_format: Response format ("text" or "audio")
56
+ voice: Voice to use for audio output
60
57
 
61
58
  Yields:
62
59
  Response chunks (text strings or audio bytes)
@@ -74,7 +71,11 @@ class QueryService(QueryServiceInterface):
74
71
  if user_text.strip().lower() in ["test", "hello", "hi", "hey", "ping"]:
75
72
  response = "Hello! How can I help you today?"
76
73
  if output_format == "audio":
77
- async for chunk in self.agent_service.llm_provider.tts(response, instructions=audio_instructions, response_format=audio_output_format, voice=audio_voice):
74
+ async for chunk in self.agent_service.llm_provider.tts(
75
+ text=response,
76
+ voice=audio_voice,
77
+ response_format=audio_output_format
78
+ ):
78
79
  yield chunk
79
80
  else:
80
81
  yield response
@@ -91,25 +92,17 @@ class QueryService(QueryServiceInterface):
91
92
 
92
93
  # Route query to appropriate agent
93
94
  agent_name = await self.routing_service.route_query(user_text)
95
+ print(f"Routed to agent: {agent_name}")
94
96
 
95
- # Generate response using agent service
96
- full_response = ""
97
- async for chunk in self.agent_service.generate_response(
98
- agent_name=agent_name,
99
- user_id=user_id,
100
- query=user_text,
101
- memory_context=memory_context,
102
- output_format=output_format,
103
- audio_voice=audio_voice,
104
- audio_output_format=audio_output_format,
105
- ):
106
- yield chunk
107
- if output_format == "text":
108
- full_response += chunk
109
-
110
- # For audio responses, get transcription for storage
97
+ # For audio mode, we need to carefully handle the response to make sure
98
+ # tool calls are properly executed and formatted for audio
111
99
  if output_format == "audio":
112
- # Re-generate response in text format for storage
100
+ # Use the agent service to generate the response
101
+ text_response = ""
102
+
103
+ # First, get complete text response
104
+ # Note: This is a separate call from the audio generation
105
+ temp_response = ""
113
106
  async for chunk in self.agent_service.generate_response(
114
107
  agent_name=agent_name,
115
108
  user_id=user_id,
@@ -117,16 +110,61 @@ class QueryService(QueryServiceInterface):
117
110
  memory_context=memory_context,
118
111
  output_format="text"
119
112
  ):
120
- full_response += chunk
113
+ temp_response += chunk
121
114
 
122
- # Store conversation and extract insights
123
- if self.memory_provider:
124
- await self._store_conversation(user_id, user_text, full_response)
115
+ # Store the complete text for memory
116
+ text_response = temp_response
117
+
118
+ # Now generate audio from same request
119
+ async for audio_chunk in self.agent_service.generate_response(
120
+ agent_name=agent_name,
121
+ user_id=user_id,
122
+ query=user_text,
123
+ memory_context=memory_context,
124
+ output_format="audio",
125
+ audio_voice=audio_voice,
126
+ audio_input_format=audio_input_format,
127
+ audio_output_format=audio_output_format,
128
+ audio_instructions=audio_instructions
129
+ ):
130
+ yield audio_chunk
131
+
132
+ # Store conversation in memory
133
+ if self.memory_provider and text_response:
134
+ await self._store_conversation(
135
+ user_id=user_id,
136
+ user_message=user_text,
137
+ assistant_message=text_response
138
+ )
139
+ else:
140
+ # For text mode, we can collect the response and store it directly
141
+ full_text_response = ""
142
+ async for chunk in self.agent_service.generate_response(
143
+ agent_name=agent_name,
144
+ user_id=user_id,
145
+ query=user_text,
146
+ memory_context=memory_context,
147
+ output_format="text"
148
+ ):
149
+ yield chunk
150
+ full_text_response += chunk
151
+
152
+ # Store conversation in memory
153
+ if self.memory_provider and full_text_response:
154
+ await self._store_conversation(
155
+ user_id=user_id,
156
+ user_message=user_text,
157
+ assistant_message=full_text_response
158
+ )
125
159
 
126
160
  except Exception as e:
127
161
  error_msg = f"I apologize for the technical difficulty. {str(e)}"
128
162
  if output_format == "audio":
129
- async for chunk in self.agent_service.llm_provider.tts(error_msg, instructions=audio_instructions, response_format=audio_output_format, voice=audio_voice):
163
+ async for chunk in self.agent_service.llm_provider.tts(
164
+ text=error_msg,
165
+ voice=audio_voice,
166
+ response_format=audio_output_format
167
+ ):
130
168
  yield chunk
131
169
  else:
132
170
  yield error_msg
@@ -242,25 +280,26 @@ class QueryService(QueryServiceInterface):
242
280
  }
243
281
 
244
282
  async def _store_conversation(
245
- self, user_id: str, user_text: str, response_text: str
283
+ self, user_id: str, user_message: str, assistant_message: str
246
284
  ) -> None:
247
285
  """Store conversation history in memory provider.
248
286
 
249
287
  Args:
250
288
  user_id: User ID
251
- user_text: User message
252
- response_text: Assistant response
289
+ user_message: User message
290
+ assistant_message: Assistant message
253
291
  """
254
292
  if self.memory_provider:
255
293
  try:
256
294
  # Truncate excessively long responses
257
- truncated_response = self._truncate(response_text)
295
+ truncated_assistant_message = self._truncate(assistant_message)
296
+ truncated_user_message = self._truncate(user_message)
258
297
 
259
298
  await self.memory_provider.store(
260
299
  user_id,
261
300
  [
262
- {"role": "user", "content": user_text},
263
- {"role": "assistant", "content": truncated_response},
301
+ {"role": "user", "content": truncated_user_message},
302
+ {"role": "assistant", "content": truncated_assistant_message},
264
303
  ],
265
304
  )
266
305
  except Exception as e:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: solana-agent
3
- Version: 17.0.2
3
+ Version: 17.0.4
4
4
  Summary: The Future of Work
5
5
  License: MIT
6
6
  Keywords: ai,openai,ai agents,agi
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3.12
13
13
  Classifier: Programming Language :: Python :: 3.13
14
14
  Classifier: Programming Language :: Python :: 3 :: Only
15
15
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
- Requires-Dist: openai (>=1.68.0,<2.0.0)
16
+ Requires-Dist: openai (>=1.68.1,<2.0.0)
17
17
  Requires-Dist: pydantic (>=2.10.6,<3.0.0)
18
18
  Requires-Dist: pymongo (>=4.11.3,<5.0.0)
19
19
  Requires-Dist: zep-cloud (>=2.7.0,<3.0.0)
@@ -28,10 +28,10 @@ solana_agent/repositories/__init__.py,sha256=fP83w83CGzXLnSdq-C5wbw9EhWTYtqE2lQT
28
28
  solana_agent/repositories/agent.py,sha256=e1rnsQiigkKwJNLKro86a3b6TBiky3GMfmCRc5b_jPw,3187
29
29
  solana_agent/repositories/memory.py,sha256=GABGwaz00thjviHewLvb18NeKE8dkBROxy_stsiiWrE,4722
30
30
  solana_agent/services/__init__.py,sha256=ab_NXJmwYUCmCrCzuTlZ47bJZINW0Y0F5jfQ9OovidU,163
31
- solana_agent/services/agent.py,sha256=8pRl3_9SDtv3sN9TH91SqxARRALu_QDXkM2eD3fcUM0,16282
32
- solana_agent/services/query.py,sha256=N0RMcQm7o4B0MGrbFFrZ_Ar5z9r-UUDgn1xzgoxQtqg,10758
31
+ solana_agent/services/agent.py,sha256=j0aI_BGaY5Nhkb9ga0r4BqI3qMKu5TOc4QPQsU3NHyQ,17000
32
+ solana_agent/services/query.py,sha256=_RHcT7LDvaVhgie96--l7N4ktEtL6UDtgk1_2t25PtQ,12305
33
33
  solana_agent/services/routing.py,sha256=TPJ2Pas4acE93QzMEV6ZP670OtTNrVEPa76fz6urEV4,4996
34
- solana_agent-17.0.2.dist-info/LICENSE,sha256=BnSRc-NSFuyF2s496l_4EyrwAP6YimvxWcjPiJ0J7g4,1057
35
- solana_agent-17.0.2.dist-info/METADATA,sha256=8uenEIcctj_hWi4_sle2mOJxoUsQSGi1RmYwQhqrgNs,4888
36
- solana_agent-17.0.2.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
37
- solana_agent-17.0.2.dist-info/RECORD,,
34
+ solana_agent-17.0.4.dist-info/LICENSE,sha256=BnSRc-NSFuyF2s496l_4EyrwAP6YimvxWcjPiJ0J7g4,1057
35
+ solana_agent-17.0.4.dist-info/METADATA,sha256=_QLt1zJUJQ-wBy6qYBycjZ6w8bxvcpdwYrxbr2vZWZk,4888
36
+ solana_agent-17.0.4.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
37
+ solana_agent-17.0.4.dist-info/RECORD,,