sunholo 0.142.0__py3-none-any.whl → 0.143.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.
- sunholo/a2a/__init__.py +27 -0
- sunholo/a2a/agent_card.py +345 -0
- sunholo/a2a/task_manager.py +480 -0
- sunholo/a2a/vac_a2a_agent.py +383 -0
- sunholo/agents/flask/vac_routes.py +545 -1
- sunholo/mcp/__init__.py +20 -0
- sunholo/mcp/mcp_manager.py +98 -0
- sunholo/mcp/vac_mcp_server.py +259 -0
- {sunholo-0.142.0.dist-info → sunholo-0.143.3.dist-info}/METADATA +9 -6
- {sunholo-0.142.0.dist-info → sunholo-0.143.3.dist-info}/RECORD +14 -8
- {sunholo-0.142.0.dist-info → sunholo-0.143.3.dist-info}/WHEEL +0 -0
- {sunholo-0.142.0.dist-info → sunholo-0.143.3.dist-info}/entry_points.txt +0 -0
- {sunholo-0.142.0.dist-info → sunholo-0.143.3.dist-info}/licenses/LICENSE.txt +0 -0
- {sunholo-0.142.0.dist-info → sunholo-0.143.3.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Proper MCP integration for VACRoutes using the official MCP Python SDK.
|
|
3
|
+
This shows how to integrate MCP servers with your Flask/VACRoutes application.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Dict, Any, List, Optional
|
|
7
|
+
|
|
8
|
+
# Official MCP imports
|
|
9
|
+
from mcp import StdioServerParameters, ClientSession
|
|
10
|
+
from mcp.client.stdio import stdio_client
|
|
11
|
+
from mcp.types import Tool, Resource, TextContent, CallToolResult
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MCPClientManager:
|
|
15
|
+
"""Manages MCP client connections to various MCP servers."""
|
|
16
|
+
|
|
17
|
+
def __init__(self):
|
|
18
|
+
self.sessions: Dict[str, ClientSession] = {}
|
|
19
|
+
self.server_configs: Dict[str, Dict[str, Any]] = {}
|
|
20
|
+
|
|
21
|
+
async def connect_to_server(self, server_name: str, command: str, args: List[str] = None) -> ClientSession:
|
|
22
|
+
"""Connect to an MCP server via stdio."""
|
|
23
|
+
if server_name in self.sessions:
|
|
24
|
+
return self.sessions[server_name]
|
|
25
|
+
|
|
26
|
+
# Create server parameters
|
|
27
|
+
server_params = StdioServerParameters(
|
|
28
|
+
command=command,
|
|
29
|
+
args=args or []
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Connect to the server
|
|
33
|
+
async with stdio_client(server_params) as (read, write):
|
|
34
|
+
# Create and initialize client session directly
|
|
35
|
+
session = ClientSession(read, write)
|
|
36
|
+
await session.initialize()
|
|
37
|
+
self.sessions[server_name] = session
|
|
38
|
+
self.server_configs[server_name] = {
|
|
39
|
+
"command": command,
|
|
40
|
+
"args": args
|
|
41
|
+
}
|
|
42
|
+
return session
|
|
43
|
+
|
|
44
|
+
async def list_tools(self, server_name: Optional[str] = None) -> List[Tool]:
|
|
45
|
+
"""List available tools from one or all connected servers."""
|
|
46
|
+
if server_name:
|
|
47
|
+
session = self.sessions.get(server_name)
|
|
48
|
+
if session:
|
|
49
|
+
return await session.list_tools()
|
|
50
|
+
return []
|
|
51
|
+
|
|
52
|
+
# List from all servers
|
|
53
|
+
all_tools = []
|
|
54
|
+
for name, session in self.sessions.items():
|
|
55
|
+
tools = await session.list_tools()
|
|
56
|
+
# Add server name to tool metadata
|
|
57
|
+
for tool in tools:
|
|
58
|
+
tool.metadata = tool.metadata or {}
|
|
59
|
+
tool.metadata["server"] = name
|
|
60
|
+
all_tools.extend(tools)
|
|
61
|
+
return all_tools
|
|
62
|
+
|
|
63
|
+
async def call_tool(self, server_name: str, tool_name: str, arguments: Dict[str, Any]) -> CallToolResult:
|
|
64
|
+
"""Call a tool on a specific MCP server."""
|
|
65
|
+
session = self.sessions.get(server_name)
|
|
66
|
+
if not session:
|
|
67
|
+
raise ValueError(f"Not connected to server: {server_name}")
|
|
68
|
+
|
|
69
|
+
# Call the tool
|
|
70
|
+
result = await session.call_tool(tool_name, arguments)
|
|
71
|
+
return result
|
|
72
|
+
|
|
73
|
+
async def list_resources(self, server_name: Optional[str] = None) -> List[Resource]:
|
|
74
|
+
"""List available resources from servers."""
|
|
75
|
+
if server_name:
|
|
76
|
+
session = self.sessions.get(server_name)
|
|
77
|
+
if session:
|
|
78
|
+
return await session.list_resources()
|
|
79
|
+
return []
|
|
80
|
+
|
|
81
|
+
# List from all servers
|
|
82
|
+
all_resources = []
|
|
83
|
+
for name, session in self.sessions.items():
|
|
84
|
+
resources = await session.list_resources()
|
|
85
|
+
for resource in resources:
|
|
86
|
+
resource.metadata = resource.metadata or {}
|
|
87
|
+
resource.metadata["server"] = name
|
|
88
|
+
all_resources.extend(resources)
|
|
89
|
+
return all_resources
|
|
90
|
+
|
|
91
|
+
async def read_resource(self, server_name: str, uri: str) -> List[TextContent]:
|
|
92
|
+
"""Read a resource from an MCP server."""
|
|
93
|
+
session = self.sessions.get(server_name)
|
|
94
|
+
if not session:
|
|
95
|
+
raise ValueError(f"Not connected to server: {server_name}")
|
|
96
|
+
|
|
97
|
+
result = await session.read_resource(uri)
|
|
98
|
+
return result.contents
|
|
@@ -0,0 +1,259 @@
|
|
|
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
|
+
MCP Server wrapper for VAC functionality.
|
|
17
|
+
This module exposes VAC streaming capabilities as MCP tools.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from typing import Any, Sequence, Dict, List, Optional, Callable
|
|
21
|
+
import json
|
|
22
|
+
import asyncio
|
|
23
|
+
from functools import partial
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
from mcp.server import Server
|
|
27
|
+
from mcp.types import Tool, TextContent, ImageContent, EmbeddedResource
|
|
28
|
+
except ImportError:
|
|
29
|
+
Server = None
|
|
30
|
+
Tool = None
|
|
31
|
+
TextContent = None
|
|
32
|
+
|
|
33
|
+
from ..custom_logging import log
|
|
34
|
+
from ..streaming import start_streaming_chat_async
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class VACMCPServer:
|
|
38
|
+
"""MCP Server that exposes VAC functionality as tools."""
|
|
39
|
+
|
|
40
|
+
def __init__(self, stream_interpreter: Callable, vac_interpreter: Callable = None):
|
|
41
|
+
"""
|
|
42
|
+
Initialize the VAC MCP Server.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
stream_interpreter: The streaming interpreter function
|
|
46
|
+
vac_interpreter: The static VAC interpreter function (optional)
|
|
47
|
+
"""
|
|
48
|
+
if Server is None:
|
|
49
|
+
raise ImportError("MCP server requires `pip install sunholo[anthropic]`")
|
|
50
|
+
|
|
51
|
+
self.stream_interpreter = stream_interpreter
|
|
52
|
+
self.vac_interpreter = vac_interpreter
|
|
53
|
+
self.server = Server("sunholo-vac-server")
|
|
54
|
+
|
|
55
|
+
# Set up handlers
|
|
56
|
+
self._setup_handlers()
|
|
57
|
+
|
|
58
|
+
def _setup_handlers(self):
|
|
59
|
+
"""Set up MCP protocol handlers."""
|
|
60
|
+
|
|
61
|
+
@self.server.list_tools()
|
|
62
|
+
async def list_tools() -> List[Tool]:
|
|
63
|
+
"""List available VAC tools."""
|
|
64
|
+
tools = [
|
|
65
|
+
Tool(
|
|
66
|
+
name="vac_stream",
|
|
67
|
+
description="Stream responses from a Sunholo VAC (Virtual Agent Computer)",
|
|
68
|
+
inputSchema={
|
|
69
|
+
"type": "object",
|
|
70
|
+
"properties": {
|
|
71
|
+
"vector_name": {
|
|
72
|
+
"type": "string",
|
|
73
|
+
"description": "Name of the VAC to interact with"
|
|
74
|
+
},
|
|
75
|
+
"user_input": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"description": "The user's question or input"
|
|
78
|
+
},
|
|
79
|
+
"chat_history": {
|
|
80
|
+
"type": "array",
|
|
81
|
+
"description": "Previous conversation history",
|
|
82
|
+
"items": {
|
|
83
|
+
"type": "object",
|
|
84
|
+
"properties": {
|
|
85
|
+
"human": {"type": "string"},
|
|
86
|
+
"ai": {"type": "string"}
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"default": []
|
|
90
|
+
},
|
|
91
|
+
"stream_wait_time": {
|
|
92
|
+
"type": "number",
|
|
93
|
+
"description": "Time to wait between stream chunks",
|
|
94
|
+
"default": 7
|
|
95
|
+
},
|
|
96
|
+
"stream_timeout": {
|
|
97
|
+
"type": "number",
|
|
98
|
+
"description": "Maximum time to wait for response",
|
|
99
|
+
"default": 120
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"required": ["vector_name", "user_input"]
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
# Add static VAC tool if interpreter is provided
|
|
108
|
+
if self.vac_interpreter:
|
|
109
|
+
tools.append(
|
|
110
|
+
Tool(
|
|
111
|
+
name="vac_query",
|
|
112
|
+
description="Query a Sunholo VAC (non-streaming)",
|
|
113
|
+
inputSchema={
|
|
114
|
+
"type": "object",
|
|
115
|
+
"properties": {
|
|
116
|
+
"vector_name": {
|
|
117
|
+
"type": "string",
|
|
118
|
+
"description": "Name of the VAC to interact with"
|
|
119
|
+
},
|
|
120
|
+
"user_input": {
|
|
121
|
+
"type": "string",
|
|
122
|
+
"description": "The user's question or input"
|
|
123
|
+
},
|
|
124
|
+
"chat_history": {
|
|
125
|
+
"type": "array",
|
|
126
|
+
"description": "Previous conversation history",
|
|
127
|
+
"items": {
|
|
128
|
+
"type": "object",
|
|
129
|
+
"properties": {
|
|
130
|
+
"human": {"type": "string"},
|
|
131
|
+
"ai": {"type": "string"}
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
"default": []
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"required": ["vector_name", "user_input"]
|
|
138
|
+
}
|
|
139
|
+
)
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
return tools
|
|
143
|
+
|
|
144
|
+
@self.server.call_tool()
|
|
145
|
+
async def call_tool(
|
|
146
|
+
name: str,
|
|
147
|
+
arguments: Any
|
|
148
|
+
) -> Sequence[TextContent | ImageContent | EmbeddedResource]:
|
|
149
|
+
"""Handle tool calls for VAC interactions."""
|
|
150
|
+
|
|
151
|
+
if name == "vac_stream":
|
|
152
|
+
return await self._handle_vac_stream(arguments)
|
|
153
|
+
elif name == "vac_query" and self.vac_interpreter:
|
|
154
|
+
return await self._handle_vac_query(arguments)
|
|
155
|
+
else:
|
|
156
|
+
raise ValueError(f"Unknown tool: {name}")
|
|
157
|
+
|
|
158
|
+
async def _handle_vac_stream(self, arguments: Dict[str, Any]) -> Sequence[TextContent]:
|
|
159
|
+
"""Handle streaming VAC requests."""
|
|
160
|
+
vector_name = arguments.get("vector_name")
|
|
161
|
+
user_input = arguments.get("user_input")
|
|
162
|
+
chat_history = arguments.get("chat_history", [])
|
|
163
|
+
stream_wait_time = arguments.get("stream_wait_time", 7)
|
|
164
|
+
stream_timeout = arguments.get("stream_timeout", 120)
|
|
165
|
+
|
|
166
|
+
if not vector_name or not user_input:
|
|
167
|
+
raise ValueError("Missing required arguments: vector_name and user_input")
|
|
168
|
+
|
|
169
|
+
log.info(f"MCP streaming request for VAC '{vector_name}': {user_input}")
|
|
170
|
+
|
|
171
|
+
try:
|
|
172
|
+
# Collect streaming responses
|
|
173
|
+
full_response = ""
|
|
174
|
+
|
|
175
|
+
async for chunk in start_streaming_chat_async(
|
|
176
|
+
question=user_input,
|
|
177
|
+
vector_name=vector_name,
|
|
178
|
+
qna_func_async=self.stream_interpreter,
|
|
179
|
+
chat_history=chat_history,
|
|
180
|
+
wait_time=stream_wait_time,
|
|
181
|
+
timeout=stream_timeout
|
|
182
|
+
):
|
|
183
|
+
if isinstance(chunk, dict) and 'answer' in chunk:
|
|
184
|
+
full_response = chunk['answer']
|
|
185
|
+
elif isinstance(chunk, str):
|
|
186
|
+
full_response += chunk
|
|
187
|
+
|
|
188
|
+
return [
|
|
189
|
+
TextContent(
|
|
190
|
+
type="text",
|
|
191
|
+
text=full_response or "No response generated"
|
|
192
|
+
)
|
|
193
|
+
]
|
|
194
|
+
|
|
195
|
+
except Exception as e:
|
|
196
|
+
log.error(f"Error in MCP VAC stream: {str(e)}")
|
|
197
|
+
return [
|
|
198
|
+
TextContent(
|
|
199
|
+
type="text",
|
|
200
|
+
text=f"Error: {str(e)}"
|
|
201
|
+
)
|
|
202
|
+
]
|
|
203
|
+
|
|
204
|
+
async def _handle_vac_query(self, arguments: Dict[str, Any]) -> Sequence[TextContent]:
|
|
205
|
+
"""Handle non-streaming VAC requests."""
|
|
206
|
+
vector_name = arguments.get("vector_name")
|
|
207
|
+
user_input = arguments.get("user_input")
|
|
208
|
+
chat_history = arguments.get("chat_history", [])
|
|
209
|
+
|
|
210
|
+
if not vector_name or not user_input:
|
|
211
|
+
raise ValueError("Missing required arguments: vector_name and user_input")
|
|
212
|
+
|
|
213
|
+
log.info(f"MCP query request for VAC '{vector_name}': {user_input}")
|
|
214
|
+
|
|
215
|
+
try:
|
|
216
|
+
# Run in executor if not async
|
|
217
|
+
if asyncio.iscoroutinefunction(self.vac_interpreter):
|
|
218
|
+
result = await self.vac_interpreter(
|
|
219
|
+
question=user_input,
|
|
220
|
+
vector_name=vector_name,
|
|
221
|
+
chat_history=chat_history
|
|
222
|
+
)
|
|
223
|
+
else:
|
|
224
|
+
loop = asyncio.get_event_loop()
|
|
225
|
+
result = await loop.run_in_executor(
|
|
226
|
+
None,
|
|
227
|
+
partial(
|
|
228
|
+
self.vac_interpreter,
|
|
229
|
+
question=user_input,
|
|
230
|
+
vector_name=vector_name,
|
|
231
|
+
chat_history=chat_history
|
|
232
|
+
)
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
# Extract answer from result
|
|
236
|
+
if isinstance(result, dict):
|
|
237
|
+
answer = result.get("answer", str(result))
|
|
238
|
+
else:
|
|
239
|
+
answer = str(result)
|
|
240
|
+
|
|
241
|
+
return [
|
|
242
|
+
TextContent(
|
|
243
|
+
type="text",
|
|
244
|
+
text=answer
|
|
245
|
+
)
|
|
246
|
+
]
|
|
247
|
+
|
|
248
|
+
except Exception as e:
|
|
249
|
+
log.error(f"Error in MCP VAC query: {str(e)}")
|
|
250
|
+
return [
|
|
251
|
+
TextContent(
|
|
252
|
+
type="text",
|
|
253
|
+
text=f"Error: {str(e)}"
|
|
254
|
+
)
|
|
255
|
+
]
|
|
256
|
+
|
|
257
|
+
def get_server(self) -> Server:
|
|
258
|
+
"""Get the underlying MCP server instance."""
|
|
259
|
+
return self.server
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sunholo
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.143.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
|
|
@@ -15,14 +15,16 @@ Classifier: Programming Language :: Python :: 3
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.10
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
-
Requires-Python: >=3.
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
License-File: LICENSE.txt
|
|
21
|
+
Requires-Dist: a2a-python>=0.0.1
|
|
21
22
|
Requires-Dist: aiohttp
|
|
23
|
+
Requires-Dist: flask>=3.1.0
|
|
22
24
|
Requires-Dist: google-auth
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist: pillow>=11.0.0
|
|
25
|
+
Requires-Dist: mcp>=1.1.1
|
|
25
26
|
Requires-Dist: pydantic
|
|
27
|
+
Requires-Dist: pytest-asyncio>=1.0.0
|
|
26
28
|
Requires-Dist: requests
|
|
27
29
|
Requires-Dist: ruamel.yaml
|
|
28
30
|
Requires-Dist: tenacity
|
|
@@ -69,7 +71,7 @@ Requires-Dist: langchain-anthropic>=0.1.23; extra == "all"
|
|
|
69
71
|
Requires-Dist: langchain-google-vertexai; extra == "all"
|
|
70
72
|
Requires-Dist: langchain-unstructured; extra == "all"
|
|
71
73
|
Requires-Dist: langfuse; extra == "all"
|
|
72
|
-
Requires-Dist: mcp; extra == "all"
|
|
74
|
+
Requires-Dist: mcp>=1.1.1; extra == "all"
|
|
73
75
|
Requires-Dist: numpy; extra == "all"
|
|
74
76
|
Requires-Dist: opencv-python; extra == "all"
|
|
75
77
|
Requires-Dist: pg8000; extra == "all"
|
|
@@ -125,6 +127,7 @@ Requires-Dist: pytesseract; extra == "pipeline"
|
|
|
125
127
|
Requires-Dist: tabulate; extra == "pipeline"
|
|
126
128
|
Requires-Dist: unstructured[all-docs,local-inference]; extra == "pipeline"
|
|
127
129
|
Provides-Extra: gcp
|
|
130
|
+
Requires-Dist: a2a-python; extra == "gcp"
|
|
128
131
|
Requires-Dist: aiofiles; extra == "gcp"
|
|
129
132
|
Requires-Dist: anthropic[vertex]; extra == "gcp"
|
|
130
133
|
Requires-Dist: google-api-python-client; extra == "gcp"
|
|
@@ -155,7 +158,7 @@ Requires-Dist: langchain-openai>=0.3.2; extra == "openai"
|
|
|
155
158
|
Requires-Dist: tiktoken; extra == "openai"
|
|
156
159
|
Provides-Extra: anthropic
|
|
157
160
|
Requires-Dist: langchain-anthropic>=0.1.23; extra == "anthropic"
|
|
158
|
-
Requires-Dist: mcp; extra == "anthropic"
|
|
161
|
+
Requires-Dist: mcp>=1.1.1; extra == "anthropic"
|
|
159
162
|
Provides-Extra: tools
|
|
160
163
|
Requires-Dist: openapi-spec-validator; extra == "tools"
|
|
161
164
|
Requires-Dist: playwright; extra == "tools"
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
sunholo/__init__.py,sha256=InRbX4V0-qdNHo9zYH3GEye7ASLR6LX8-SMvPV4Jsaw,1212
|
|
2
2
|
sunholo/custom_logging.py,sha256=JXZTnXp_DixP3jwYfKw4LYRDS9IuTq7ctCgfZbI2rxA,22023
|
|
3
3
|
sunholo/langchain_types.py,sha256=uZ4zvgej_f7pLqjtu4YP7qMC_eZD5ym_5x4pyvA1Ih4,1834
|
|
4
|
+
sunholo/a2a/__init__.py,sha256=ohwR-3_toRUdyj3ACNCVPrd_V2lzR5tmL5Hwn1ChSSU,1049
|
|
5
|
+
sunholo/a2a/agent_card.py,sha256=TJOgZ5FZJGgapyFXzBIRnnocUWcfSLah7fjvl0fLYJ4,13387
|
|
6
|
+
sunholo/a2a/task_manager.py,sha256=Ox1oAHarqYdcWku_JFcYDt2pQG3gwfuBTO7WCakE-U0,17670
|
|
7
|
+
sunholo/a2a/vac_a2a_agent.py,sha256=vL-sQceVRBE9d3kjx9m8zGWK1S9J1sHUybAH3tSbVFg,13344
|
|
4
8
|
sunholo/agents/__init__.py,sha256=AauG3l0y4r5Fzx1zJfZ634M4o-0o7B7J5T8k_gPvNqE,370
|
|
5
9
|
sunholo/agents/chat_history.py,sha256=gRuIUyU-53A72Q17SmSgf6Ok3YO8hKAZhsc64976018,17782
|
|
6
10
|
sunholo/agents/dispatch_to_qa.py,sha256=NHihwAoCJ5_Lk11e_jZnucVUGQyZHCB-YpkfMHBCpQk,8882
|
|
@@ -14,7 +18,7 @@ sunholo/agents/fastapi/base.py,sha256=W-cyF8ZDUH40rc-c-Apw3-_8IIi2e4Y9qRtnoVnsc1
|
|
|
14
18
|
sunholo/agents/fastapi/qna_routes.py,sha256=lKHkXPmwltu9EH3RMwmD153-J6pE7kWQ4BhBlV3to-s,3864
|
|
15
19
|
sunholo/agents/flask/__init__.py,sha256=dEoByI3gDNUOjpX1uVKP7uPjhfFHJubbiaAv3xLopnk,63
|
|
16
20
|
sunholo/agents/flask/base.py,sha256=vnpxFEOnCmt9humqj-jYPLfJcdwzsop9NorgkJ-tSaU,1756
|
|
17
|
-
sunholo/agents/flask/vac_routes.py,sha256=
|
|
21
|
+
sunholo/agents/flask/vac_routes.py,sha256=4Wenjq1Mg9gnmVt_5nHH3Uzhvio269lo2N9v38VxT48,53850
|
|
18
22
|
sunholo/archive/__init__.py,sha256=qNHWm5rGPVOlxZBZCpA1wTYPbalizRT7f8X4rs2t290,31
|
|
19
23
|
sunholo/archive/archive.py,sha256=PxVfDtO2_2ZEEbnhXSCbXLdeoHoQVImo4y3Jr2XkCFY,1204
|
|
20
24
|
sunholo/auth/__init__.py,sha256=TeP-OY0XGxYV_8AQcVGoh35bvyWhNUcMRfhuD5l44Sk,91
|
|
@@ -110,8 +114,10 @@ sunholo/llamaindex/llamaindex_class.py,sha256=PnpPoc7LpP7xvKIXYu-UvI4ehj67pGhE1E
|
|
|
110
114
|
sunholo/llamaindex/user_history.py,sha256=ZtkecWuF9ORduyGB8kF8gP66bm9DdvCI-ZiK6Kt-cSE,2265
|
|
111
115
|
sunholo/lookup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
112
116
|
sunholo/lookup/model_lookup.yaml,sha256=O7o-jP53MLA06C8pI-ILwERShO-xf6z_258wtpZBv6A,739
|
|
113
|
-
sunholo/mcp/__init__.py,sha256=
|
|
117
|
+
sunholo/mcp/__init__.py,sha256=GmKB8Z0ecXUzpuzYEOXSI0aaZP7LZJc7yTCMEFdAmi4,791
|
|
114
118
|
sunholo/mcp/cli.py,sha256=d24nnVzhZYz4AWgTqmN-qjKG4rPbf8RhdmEOHZkBHy8,10570
|
|
119
|
+
sunholo/mcp/mcp_manager.py,sha256=ooa_2JSNaKIuK9azEV0OaPVf5Mp_tL_DHaYEyFCmgKY,3752
|
|
120
|
+
sunholo/mcp/vac_mcp_server.py,sha256=fRcerTqp_pTK8AVITpGPhrez_IaDuUDr4WnVUHPv8GM,10114
|
|
115
121
|
sunholo/ollama/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
116
122
|
sunholo/ollama/ollama_images.py,sha256=H2cpcNu88R4TwyfL_nnqkQhdvBQ2FPCAy4Ok__0yQmo,2351
|
|
117
123
|
sunholo/pubsub/__init__.py,sha256=DfTEk4zmCfqn6gFxRrqDO0pOrvXTDqH-medpgYO4PGw,117
|
|
@@ -169,9 +175,9 @@ sunholo/vertex/init.py,sha256=1OQwcPBKZYBTDPdyU7IM4X4OmiXLdsNV30C-fee2scQ,2875
|
|
|
169
175
|
sunholo/vertex/memory_tools.py,sha256=tBZxqVZ4InTmdBvLlOYwoSEWu4-kGquc-gxDwZCC4FA,7667
|
|
170
176
|
sunholo/vertex/safety.py,sha256=S9PgQT1O_BQAkcqauWncRJaydiP8Q_Jzmu9gxYfy1VA,2482
|
|
171
177
|
sunholo/vertex/type_dict_to_json.py,sha256=uTzL4o9tJRao4u-gJOFcACgWGkBOtqACmb6ihvCErL8,4694
|
|
172
|
-
sunholo-0.
|
|
173
|
-
sunholo-0.
|
|
174
|
-
sunholo-0.
|
|
175
|
-
sunholo-0.
|
|
176
|
-
sunholo-0.
|
|
177
|
-
sunholo-0.
|
|
178
|
+
sunholo-0.143.3.dist-info/licenses/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
|
|
179
|
+
sunholo-0.143.3.dist-info/METADATA,sha256=d36VCf5W1j1lyZ7HIe_vBHxOPyQ_f_UNhTD1X6_FjiQ,18413
|
|
180
|
+
sunholo-0.143.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
181
|
+
sunholo-0.143.3.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
|
|
182
|
+
sunholo-0.143.3.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
|
|
183
|
+
sunholo-0.143.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|