sunholo 0.144.1__py3-none-any.whl → 0.144.3__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.
@@ -0,0 +1,250 @@
1
+ # Copyright [2024] [Holosun ApS]
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """
16
+ Built-in VAC tools for MCP server integration.
17
+ Provides core Sunholo VAC functionality as MCP tools.
18
+ """
19
+
20
+ import asyncio
21
+ import os
22
+ import sys
23
+ from typing import Dict, List, Optional, Any
24
+
25
+ try:
26
+ from fastmcp import FastMCP
27
+ FASTMCP_AVAILABLE = True
28
+ except ImportError:
29
+ FastMCP = None
30
+ FASTMCP_AVAILABLE = False
31
+
32
+ from ..custom_logging import log
33
+
34
+ # Import with fallbacks for optional dependencies
35
+ try:
36
+ from ..utils import ConfigManager
37
+ CONFIG_AVAILABLE = True
38
+ except ImportError:
39
+ ConfigManager = None
40
+ CONFIG_AVAILABLE = False
41
+
42
+ try:
43
+ from ..streaming import start_streaming_chat_async
44
+ STREAMING_AVAILABLE = True
45
+ except ImportError:
46
+ start_streaming_chat_async = None
47
+ STREAMING_AVAILABLE = False
48
+
49
+
50
+ def get_vac_config(vector_name: str = None) -> 'ConfigManager':
51
+ """Get VAC configuration for the specified vector name."""
52
+ if not CONFIG_AVAILABLE:
53
+ raise ImportError("ConfigManager not available. Install sunholo with appropriate extras.")
54
+
55
+ default_vac = os.getenv("DEFAULT_VAC_NAME", "demo")
56
+ vac_name = vector_name or default_vac
57
+ vac_config_folder = os.getenv("VAC_CONFIG_FOLDER")
58
+
59
+ if vac_config_folder:
60
+ return ConfigManager(vac_name, config_folder=vac_config_folder)
61
+ else:
62
+ return ConfigManager(vac_name)
63
+
64
+
65
+ async def call_vac_async(question: str, vector_name: str, chat_history: List[Dict[str, str]] = None) -> str:
66
+ """
67
+ Call VAC asynchronously using the streaming interface.
68
+
69
+ Args:
70
+ question: The user's question
71
+ vector_name: Name of the VAC to query
72
+ chat_history: Previous conversation history
73
+
74
+ Returns:
75
+ The VAC's response
76
+ """
77
+ if not STREAMING_AVAILABLE:
78
+ raise ImportError("Streaming functionality not available. Install sunholo with streaming support.")
79
+
80
+ if chat_history is None:
81
+ chat_history = []
82
+
83
+ try:
84
+ config = get_vac_config(vector_name)
85
+
86
+ # Import the appropriate QNA function based on configuration
87
+ llm_str = config.vacConfig('llm')
88
+
89
+ if llm_str and 'anthropic' in llm_str.lower():
90
+ try:
91
+ from ..agents.langchain.vertex_genai2 import qna_async
92
+ except ImportError:
93
+ log.warning("Anthropic integration not available, falling back to default")
94
+ from ..agents.langchain.vertex_genai2 import qna_async
95
+ elif llm_str and 'openai' in llm_str.lower():
96
+ try:
97
+ from ..agents.langchain.vertex_genai2 import qna_async
98
+ except ImportError:
99
+ log.warning("OpenAI integration not available, falling back to default")
100
+ from ..agents.langchain.vertex_genai2 import qna_async
101
+ else:
102
+ # Default to vertex AI
103
+ from ..agents.langchain.vertex_genai2 import qna_async
104
+
105
+ # Use streaming interface to get response
106
+ full_response = ""
107
+ async for chunk in start_streaming_chat_async(
108
+ question=question,
109
+ vector_name=vector_name,
110
+ qna_func_async=qna_async,
111
+ chat_history=chat_history
112
+ ):
113
+ if isinstance(chunk, dict) and 'answer' in chunk:
114
+ full_response = chunk['answer']
115
+ elif isinstance(chunk, str):
116
+ full_response += chunk
117
+
118
+ return full_response or "No response generated"
119
+
120
+ except Exception as e:
121
+ log.error(f"Error calling VAC {vector_name}: {str(e)}")
122
+ return f"Error: {str(e)}"
123
+
124
+
125
+ def register_vac_tools(server: 'FastMCP', registry: 'MCPToolRegistry' = None):
126
+ """
127
+ Register built-in VAC tools with a FastMCP server.
128
+
129
+ Args:
130
+ server: FastMCP server instance
131
+ registry: Optional registry to track tools
132
+ """
133
+
134
+ @server.tool
135
+ async def vac_stream(
136
+ vector_name: str,
137
+ user_input: str,
138
+ chat_history: Optional[List[Dict[str, str]]] = None,
139
+ stream_wait_time: float = 7,
140
+ stream_timeout: float = 120
141
+ ) -> str:
142
+ """
143
+ Stream responses from a Sunholo VAC (Virtual Agent Computer).
144
+
145
+ Args:
146
+ vector_name: Name of the VAC to interact with
147
+ user_input: The user's question or input
148
+ chat_history: Previous conversation history
149
+ stream_wait_time: Time to wait between stream chunks (default: 7)
150
+ stream_timeout: Maximum time to wait for response (default: 120)
151
+
152
+ Returns:
153
+ The streamed response from the VAC
154
+ """
155
+ if chat_history is None:
156
+ chat_history = []
157
+
158
+ log.info(f"MCP streaming request for VAC '{vector_name}': {user_input}")
159
+
160
+ try:
161
+ return await call_vac_async(user_input, vector_name, chat_history)
162
+ except Exception as e:
163
+ log.error(f"Error in MCP VAC stream: {str(e)}")
164
+ return f"Error: {str(e)}"
165
+
166
+ @server.tool
167
+ async def vac_query(
168
+ vector_name: str,
169
+ user_input: str,
170
+ chat_history: Optional[List[Dict[str, str]]] = None
171
+ ) -> str:
172
+ """
173
+ Query a Sunholo VAC (non-streaming).
174
+
175
+ Args:
176
+ vector_name: Name of the VAC to interact with
177
+ user_input: The user's question or input
178
+ chat_history: Previous conversation history
179
+
180
+ Returns:
181
+ The response from the VAC
182
+ """
183
+ if chat_history is None:
184
+ chat_history = []
185
+
186
+ log.info(f"MCP query request for VAC '{vector_name}': {user_input}")
187
+
188
+ try:
189
+ return await call_vac_async(user_input, vector_name, chat_history)
190
+ except Exception as e:
191
+ log.error(f"Error in MCP VAC query: {str(e)}")
192
+ return f"Error: {str(e)}"
193
+
194
+ @server.tool
195
+ def list_available_vacs() -> List[str]:
196
+ """
197
+ List all available VAC configurations.
198
+
199
+ Returns:
200
+ List of available VAC names
201
+ """
202
+ try:
203
+ config = get_vac_config()
204
+ # Try to get available VACs from config
205
+ all_configs = config.load_all_configs()
206
+ if 'vacConfig' in all_configs and 'vac' in all_configs['vacConfig']:
207
+ return list(all_configs['vacConfig']['vac'].keys())
208
+ else:
209
+ return [os.getenv("DEFAULT_VAC_NAME", "demo")]
210
+ except Exception as e:
211
+ log.error(f"Error listing VACs: {str(e)}")
212
+ return [os.getenv("DEFAULT_VAC_NAME", "demo")]
213
+
214
+ @server.tool
215
+ def get_vac_info(vector_name: str) -> Dict[str, Any]:
216
+ """
217
+ Get information about a specific VAC configuration.
218
+
219
+ Args:
220
+ vector_name: Name of the VAC to get info for
221
+
222
+ Returns:
223
+ Dictionary containing VAC configuration details
224
+ """
225
+ try:
226
+ config = get_vac_config(vector_name)
227
+ return {
228
+ "name": vector_name,
229
+ "llm": config.vacConfig('llm'),
230
+ "model": config.vacConfig('model'),
231
+ "description": f"VAC configuration for {vector_name}",
232
+ "available": True
233
+ }
234
+ except Exception as e:
235
+ log.error(f"Error getting VAC info for {vector_name}: {str(e)}")
236
+ return {
237
+ "name": vector_name,
238
+ "error": str(e),
239
+ "available": False
240
+ }
241
+
242
+ # Register tools in registry if provided
243
+ if registry:
244
+ # Extract the underlying function from FunctionTool objects
245
+ registry.register_tool("vac_stream", vac_stream.fn if hasattr(vac_stream, 'fn') else vac_stream)
246
+ registry.register_tool("vac_query", vac_query.fn if hasattr(vac_query, 'fn') else vac_query)
247
+ registry.register_tool("list_available_vacs", list_available_vacs.fn if hasattr(list_available_vacs, 'fn') else list_available_vacs)
248
+ registry.register_tool("get_vac_info", get_vac_info.fn if hasattr(get_vac_info, 'fn') else get_vac_info)
249
+
250
+ log.info("Registered built-in VAC tools with MCP server")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sunholo
3
- Version: 0.144.1
3
+ Version: 0.144.3
4
4
  Summary: AI DevOps - a package to help deploy GenAI to the Cloud.
5
5
  Author-email: Holosun ApS <multivac@sunholo.com>
6
6
  License: Apache License, Version 2.0
@@ -16,7 +16,7 @@ sunholo/agents/swagger.py,sha256=2tzGmpveUMmTREykZvVnDj3j295wyOMu7mUFDnXdY3c,106
16
16
  sunholo/agents/fastapi/__init__.py,sha256=f7x7kiEjaNyBiOwJHLJ4vdOiePqkXdI52sIAAHtS-ms,141
17
17
  sunholo/agents/fastapi/base.py,sha256=W-cyF8ZDUH40rc-c-Apw3-_8IIi2e4Y9qRtnoVnsc1Q,2521
18
18
  sunholo/agents/fastapi/qna_routes.py,sha256=lKHkXPmwltu9EH3RMwmD153-J6pE7kWQ4BhBlV3to-s,3864
19
- sunholo/agents/fastapi/vac_routes.py,sha256=sK2FuJsOBgc8sIKtTOYuyhNql5JX63U_hMpQQ-nLcug,42985
19
+ sunholo/agents/fastapi/vac_routes.py,sha256=s0wzGupaIsfQqJlDA1f8MXoVY8LGsHr0VP2xeRQOzM0,59860
20
20
  sunholo/agents/flask/__init__.py,sha256=dEoByI3gDNUOjpX1uVKP7uPjhfFHJubbiaAv3xLopnk,63
21
21
  sunholo/agents/flask/base.py,sha256=vnpxFEOnCmt9humqj-jYPLfJcdwzsop9NorgkJ-tSaU,1756
22
22
  sunholo/agents/flask/vac_routes.py,sha256=kaPUDyIH5KhCgeCEtag97qErGVZfqpY1ZEiX3y1_r-s,57505
@@ -118,10 +118,12 @@ sunholo/lookup/model_lookup.yaml,sha256=O7o-jP53MLA06C8pI-ILwERShO-xf6z_258wtpZB
118
118
  sunholo/mcp/__init__.py,sha256=Bi0ZYMvWuf1AL_QSrMAREVVdTZFiIokGwrytBXKBJyc,1028
119
119
  sunholo/mcp/cli.py,sha256=RyTrTBQMUaNMAZ1Nyh-XKb9qGnCA5hMxpKp5-9lqfrI,821
120
120
  sunholo/mcp/cli_fastmcp.py,sha256=MWx7kJ4RHX0tTygWs247aOYr4bCKOwjnmccOPjcTVnc,6104
121
+ sunholo/mcp/extensible_mcp_server.py,sha256=docJT800-wJLApU6kEa3lwu9FHyy1yvtJIk8JI05Z3o,8960
121
122
  sunholo/mcp/mcp_manager.py,sha256=g75vv6XvM24U7uz366slE-p76Qs4AvVcsarHSF9qIvE,5061
122
123
  sunholo/mcp/stdio_http_bridge.py,sha256=IunHOtnjKAkRWef3SJnqnAL2r2qBRpCH2k_Q_y0Tdf8,3237
123
124
  sunholo/mcp/vac_mcp_server.py,sha256=MotoCw5lDsxCeVtwh1499yGFku9w-78xXhGkIHTUo3w,838
124
- sunholo/mcp/vac_mcp_server_fastmcp.py,sha256=Po8Uvs1iSYKNfB5Qz5B7URU9i4jEW70wPpJZDEbAO1U,7430
125
+ sunholo/mcp/vac_mcp_server_fastmcp.py,sha256=R95GDWRbVyAVqVhWVkJv9wd5gH1bWKiz69IU5rWPnIc,4451
126
+ sunholo/mcp/vac_tools.py,sha256=pTtHxPHD5k80wRnmJw1-RJK8L8IOOCWpGyTL1W2M934,8744
125
127
  sunholo/ollama/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
126
128
  sunholo/ollama/ollama_images.py,sha256=H2cpcNu88R4TwyfL_nnqkQhdvBQ2FPCAy4Ok__0yQmo,2351
127
129
  sunholo/pubsub/__init__.py,sha256=DfTEk4zmCfqn6gFxRrqDO0pOrvXTDqH-medpgYO4PGw,117
@@ -179,9 +181,9 @@ sunholo/vertex/init.py,sha256=1OQwcPBKZYBTDPdyU7IM4X4OmiXLdsNV30C-fee2scQ,2875
179
181
  sunholo/vertex/memory_tools.py,sha256=tBZxqVZ4InTmdBvLlOYwoSEWu4-kGquc-gxDwZCC4FA,7667
180
182
  sunholo/vertex/safety.py,sha256=S9PgQT1O_BQAkcqauWncRJaydiP8Q_Jzmu9gxYfy1VA,2482
181
183
  sunholo/vertex/type_dict_to_json.py,sha256=uTzL4o9tJRao4u-gJOFcACgWGkBOtqACmb6ihvCErL8,4694
182
- sunholo-0.144.1.dist-info/licenses/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
183
- sunholo-0.144.1.dist-info/METADATA,sha256=ia-s14a5R5yxApJZGGqqeT2ebAlxEyc5AJhniD9xtxg,18700
184
- sunholo-0.144.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
185
- sunholo-0.144.1.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
186
- sunholo-0.144.1.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
187
- sunholo-0.144.1.dist-info/RECORD,,
184
+ sunholo-0.144.3.dist-info/licenses/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
185
+ sunholo-0.144.3.dist-info/METADATA,sha256=RObZwvRVw98mi-1RzJMaNtiLKZ0mui7wnNsaqf-oYmI,18700
186
+ sunholo-0.144.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
187
+ sunholo-0.144.3.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
188
+ sunholo-0.144.3.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
189
+ sunholo-0.144.3.dist-info/RECORD,,