chuk-tool-processor 0.6.5__py3-none-any.whl → 0.6.7__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.
Potentially problematic release.
This version of chuk-tool-processor might be problematic. Click here for more details.
- chuk_tool_processor/mcp/stream_manager.py +24 -5
- chuk_tool_processor/mcp/transport/sse_transport.py +41 -3
- {chuk_tool_processor-0.6.5.dist-info → chuk_tool_processor-0.6.7.dist-info}/METADATA +1 -1
- {chuk_tool_processor-0.6.5.dist-info → chuk_tool_processor-0.6.7.dist-info}/RECORD +6 -6
- {chuk_tool_processor-0.6.5.dist-info → chuk_tool_processor-0.6.7.dist-info}/WHEEL +0 -0
- {chuk_tool_processor-0.6.5.dist-info → chuk_tool_processor-0.6.7.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# chuk_tool_processor/mcp/stream_manager.py
|
|
2
2
|
"""
|
|
3
|
-
StreamManager for CHUK Tool Processor - Enhanced with robust shutdown handling
|
|
3
|
+
StreamManager for CHUK Tool Processor - Enhanced with robust shutdown handling and headers support
|
|
4
4
|
"""
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
@@ -27,12 +27,12 @@ class StreamManager:
|
|
|
27
27
|
"""
|
|
28
28
|
Manager for MCP server streams with support for multiple transport types.
|
|
29
29
|
|
|
30
|
-
Enhanced with robust shutdown handling
|
|
30
|
+
Enhanced with robust shutdown handling and proper headers support.
|
|
31
31
|
|
|
32
32
|
Updated to support the latest transports:
|
|
33
33
|
- STDIO (process-based)
|
|
34
|
-
- SSE (Server-Sent Events)
|
|
35
|
-
- HTTP Streamable (modern replacement for SSE, spec 2025-03-26)
|
|
34
|
+
- SSE (Server-Sent Events) with headers support
|
|
35
|
+
- HTTP Streamable (modern replacement for SSE, spec 2025-03-26) with headers support
|
|
36
36
|
"""
|
|
37
37
|
|
|
38
38
|
def __init__(self) -> None:
|
|
@@ -193,14 +193,17 @@ class StreamManager:
|
|
|
193
193
|
if isinstance(params, dict) and 'url' in params:
|
|
194
194
|
sse_url = params['url']
|
|
195
195
|
api_key = params.get('api_key')
|
|
196
|
+
headers = params.get('headers', {})
|
|
196
197
|
else:
|
|
197
198
|
sse_url = "http://localhost:8000"
|
|
198
199
|
api_key = None
|
|
200
|
+
headers = {}
|
|
199
201
|
logger.warning("No URL configured for SSE transport, using default: %s", sse_url)
|
|
200
202
|
|
|
201
203
|
transport = SSETransport(
|
|
202
204
|
sse_url,
|
|
203
205
|
api_key,
|
|
206
|
+
headers=headers,
|
|
204
207
|
default_timeout=default_timeout
|
|
205
208
|
)
|
|
206
209
|
elif transport_type == "http_streamable":
|
|
@@ -210,16 +213,19 @@ class StreamManager:
|
|
|
210
213
|
if isinstance(params, dict) and 'url' in params:
|
|
211
214
|
http_url = params['url']
|
|
212
215
|
api_key = params.get('api_key')
|
|
216
|
+
headers = params.get('headers', {})
|
|
213
217
|
session_id = params.get('session_id')
|
|
214
218
|
else:
|
|
215
219
|
http_url = "http://localhost:8000"
|
|
216
220
|
api_key = None
|
|
221
|
+
headers = {}
|
|
217
222
|
session_id = None
|
|
218
223
|
logger.warning("No URL configured for HTTP Streamable transport, using default: %s", http_url)
|
|
219
224
|
|
|
220
225
|
transport = HTTPStreamableTransport(
|
|
221
226
|
http_url,
|
|
222
227
|
api_key,
|
|
228
|
+
headers=headers,
|
|
223
229
|
default_timeout=default_timeout,
|
|
224
230
|
session_id=session_id
|
|
225
231
|
)
|
|
@@ -271,6 +277,7 @@ class StreamManager:
|
|
|
271
277
|
connection_timeout: float = 10.0,
|
|
272
278
|
default_timeout: float = 30.0,
|
|
273
279
|
) -> None:
|
|
280
|
+
"""Initialize with SSE transport with headers support."""
|
|
274
281
|
if self._closed:
|
|
275
282
|
raise RuntimeError("Cannot initialize a closed StreamManager")
|
|
276
283
|
|
|
@@ -283,9 +290,15 @@ class StreamManager:
|
|
|
283
290
|
logger.error("Bad server config: %s", cfg)
|
|
284
291
|
continue
|
|
285
292
|
try:
|
|
293
|
+
# FIXED: Extract and pass headers from server config
|
|
294
|
+
headers = cfg.get("headers", {})
|
|
295
|
+
if headers:
|
|
296
|
+
logger.debug("SSE %s: Using configured headers: %s", name, list(headers.keys()))
|
|
297
|
+
|
|
286
298
|
transport = SSETransport(
|
|
287
299
|
url,
|
|
288
300
|
cfg.get("api_key"),
|
|
301
|
+
headers=headers, # ← FIXED: Pass headers
|
|
289
302
|
connection_timeout=connection_timeout,
|
|
290
303
|
default_timeout=default_timeout
|
|
291
304
|
)
|
|
@@ -326,7 +339,7 @@ class StreamManager:
|
|
|
326
339
|
connection_timeout: float = 30.0,
|
|
327
340
|
default_timeout: float = 30.0,
|
|
328
341
|
) -> None:
|
|
329
|
-
"""Initialize with HTTP Streamable transport
|
|
342
|
+
"""Initialize with HTTP Streamable transport with headers support."""
|
|
330
343
|
if self._closed:
|
|
331
344
|
raise RuntimeError("Cannot initialize a closed StreamManager")
|
|
332
345
|
|
|
@@ -339,9 +352,15 @@ class StreamManager:
|
|
|
339
352
|
logger.error("Bad server config: %s", cfg)
|
|
340
353
|
continue
|
|
341
354
|
try:
|
|
355
|
+
# FIXED: Extract and pass headers from server config
|
|
356
|
+
headers = cfg.get("headers", {})
|
|
357
|
+
if headers:
|
|
358
|
+
logger.debug("HTTP Streamable %s: Using configured headers: %s", name, list(headers.keys()))
|
|
359
|
+
|
|
342
360
|
transport = HTTPStreamableTransport(
|
|
343
361
|
url,
|
|
344
362
|
cfg.get("api_key"),
|
|
363
|
+
headers=headers, # ← FIXED: Pass headers (requires HTTPStreamableTransport to be updated)
|
|
345
364
|
connection_timeout=connection_timeout,
|
|
346
365
|
default_timeout=default_timeout,
|
|
347
366
|
session_id=cfg.get("session_id")
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# chuk_tool_processor/mcp/transport/sse_transport.py
|
|
2
2
|
"""
|
|
3
3
|
Fixed SSE transport that matches your server's actual behavior.
|
|
4
|
-
Based on your working debug script.
|
|
4
|
+
Based on your working debug script with smart URL detection.
|
|
5
5
|
"""
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
@@ -26,13 +26,21 @@ class SSETransport(MCPBaseTransport):
|
|
|
26
26
|
"""
|
|
27
27
|
|
|
28
28
|
def __init__(self, url: str, api_key: Optional[str] = None,
|
|
29
|
+
headers: Optional[Dict[str, str]] = None,
|
|
29
30
|
connection_timeout: float = 30.0, default_timeout: float = 30.0):
|
|
30
31
|
"""Initialize SSE transport."""
|
|
31
32
|
self.url = url.rstrip('/')
|
|
32
33
|
self.api_key = api_key
|
|
34
|
+
self.configured_headers = headers or {}
|
|
33
35
|
self.connection_timeout = connection_timeout
|
|
34
36
|
self.default_timeout = default_timeout
|
|
35
37
|
|
|
38
|
+
# DEBUG: Log what we received
|
|
39
|
+
logger.debug("SSE Transport initialized with:")
|
|
40
|
+
logger.debug(" URL: %s", self.url)
|
|
41
|
+
logger.debug(" API Key: %s", "***" if api_key else None)
|
|
42
|
+
logger.debug(" Headers: %s", {k: v[:10] + "..." if len(v) > 10 else v for k, v in self.configured_headers.items()})
|
|
43
|
+
|
|
36
44
|
# State
|
|
37
45
|
self.session_id = None
|
|
38
46
|
self.message_url = None
|
|
@@ -48,11 +56,41 @@ class SSETransport(MCPBaseTransport):
|
|
|
48
56
|
self.sse_response = None
|
|
49
57
|
self.sse_stream_context = None
|
|
50
58
|
|
|
59
|
+
def _construct_sse_url(self, base_url: str) -> str:
|
|
60
|
+
"""
|
|
61
|
+
Construct the SSE endpoint URL from the base URL.
|
|
62
|
+
|
|
63
|
+
Smart detection to avoid double-appending /sse if already present.
|
|
64
|
+
"""
|
|
65
|
+
# Remove trailing slashes
|
|
66
|
+
base_url = base_url.rstrip('/')
|
|
67
|
+
|
|
68
|
+
# Check if URL already ends with /sse
|
|
69
|
+
if base_url.endswith('/sse'):
|
|
70
|
+
# Already has /sse, use as-is
|
|
71
|
+
logger.debug("URL already contains /sse endpoint: %s", base_url)
|
|
72
|
+
return base_url
|
|
73
|
+
|
|
74
|
+
# Append /sse to the base URL
|
|
75
|
+
sse_url = f"{base_url}/sse"
|
|
76
|
+
logger.debug("Appending /sse to base URL: %s -> %s", base_url, sse_url)
|
|
77
|
+
return sse_url
|
|
78
|
+
|
|
51
79
|
def _get_headers(self) -> Dict[str, str]:
|
|
52
80
|
"""Get headers with auth if available."""
|
|
53
81
|
headers = {}
|
|
82
|
+
|
|
83
|
+
# Add configured headers first
|
|
84
|
+
if self.configured_headers:
|
|
85
|
+
headers.update(self.configured_headers)
|
|
86
|
+
|
|
87
|
+
# Add API key as Bearer token if provided (this will override any Authorization header)
|
|
54
88
|
if self.api_key:
|
|
55
89
|
headers['Authorization'] = f'Bearer {self.api_key}'
|
|
90
|
+
|
|
91
|
+
# DEBUG: Log what headers we're sending
|
|
92
|
+
logger.debug("Sending headers: %s", {k: v[:10] + "..." if len(v) > 10 else v for k, v in headers.items()})
|
|
93
|
+
|
|
56
94
|
return headers
|
|
57
95
|
|
|
58
96
|
async def initialize(self) -> bool:
|
|
@@ -68,8 +106,8 @@ class SSETransport(MCPBaseTransport):
|
|
|
68
106
|
self.stream_client = httpx.AsyncClient(timeout=self.connection_timeout)
|
|
69
107
|
self.send_client = httpx.AsyncClient(timeout=self.default_timeout)
|
|
70
108
|
|
|
71
|
-
# Connect to SSE stream
|
|
72
|
-
sse_url =
|
|
109
|
+
# Connect to SSE stream with smart URL construction
|
|
110
|
+
sse_url = self._construct_sse_url(self.url)
|
|
73
111
|
logger.debug("Connecting to SSE: %s", sse_url)
|
|
74
112
|
|
|
75
113
|
self.sse_stream_context = self.stream_client.stream(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chuk-tool-processor
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.7
|
|
4
4
|
Summary: Async-native framework for registering, discovering, and executing tools referenced in LLM responses
|
|
5
5
|
Author-email: CHUK Team <chrishayuk@somejunkmailbox.com>
|
|
6
6
|
Maintainer-email: CHUK Team <chrishayuk@somejunkmailbox.com>
|
|
@@ -22,11 +22,11 @@ chuk_tool_processor/mcp/register_mcp_tools.py,sha256=s6mQMtZr7dswT2WXDJ84zjOTSi3
|
|
|
22
22
|
chuk_tool_processor/mcp/setup_mcp_http_streamable.py,sha256=ZJUAj7LL4CRfc-CBl0SQJk0qfW12IuixR-7J2hbQ8S8,4538
|
|
23
23
|
chuk_tool_processor/mcp/setup_mcp_sse.py,sha256=4nf0V6cykAPLxtgsl8RTAYQdVWITUNu_3CIU1vcLjlo,3795
|
|
24
24
|
chuk_tool_processor/mcp/setup_mcp_stdio.py,sha256=L8anrx_b5HDsaMqAfbpWaHex084DTd76W8WBf3ClC48,2884
|
|
25
|
-
chuk_tool_processor/mcp/stream_manager.py,sha256=
|
|
25
|
+
chuk_tool_processor/mcp/stream_manager.py,sha256=DU1RkFDqyz9PZVNBgx-LeJM8Tt7hf-_mmYymRvfnqKY,32701
|
|
26
26
|
chuk_tool_processor/mcp/transport/__init__.py,sha256=0DX7m_VvlXPxijc-88_QTLhq4ZqAgUgzBjSMGL9C_lM,963
|
|
27
27
|
chuk_tool_processor/mcp/transport/base_transport.py,sha256=bqId34OMQMxzMXtrKq_86sot0_x0NS_ecaIllsCyy6I,3423
|
|
28
28
|
chuk_tool_processor/mcp/transport/http_streamable_transport.py,sha256=3I3tNYU8r4YqCbNhMCkoucvZc6VS2ulzeUjDe2FbcRk,19108
|
|
29
|
-
chuk_tool_processor/mcp/transport/sse_transport.py,sha256=
|
|
29
|
+
chuk_tool_processor/mcp/transport/sse_transport.py,sha256=s8an1sHLFsIJwqxUcdSvY6bYBkdyNQ-LkQMqzD5okdI,17253
|
|
30
30
|
chuk_tool_processor/mcp/transport/stdio_transport.py,sha256=DPXLR_OxuCJ2bgwYDuT_iYC_CDcUIySvLNO7JzyiPyc,9099
|
|
31
31
|
chuk_tool_processor/models/__init__.py,sha256=TC__rdVa0lQsmJHM_hbLDPRgToa_pQT_UxRcPZk6iVw,40
|
|
32
32
|
chuk_tool_processor/models/execution_strategy.py,sha256=UVW35YIeMY2B3mpIKZD2rAkyOPayI6ckOOUALyf0YiQ,2115
|
|
@@ -54,7 +54,7 @@ chuk_tool_processor/registry/providers/__init__.py,sha256=eigwG_So11j7WbDGSWaKd3
|
|
|
54
54
|
chuk_tool_processor/registry/providers/memory.py,sha256=6cMtUwLO6zrk3pguQRgxJ2CReHAzewgZsizWZhsoStk,5184
|
|
55
55
|
chuk_tool_processor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
56
|
chuk_tool_processor/utils/validation.py,sha256=V5N1dH9sJlHepFIbiI2k2MU82o7nvnh0hKyIt2jdgww,4136
|
|
57
|
-
chuk_tool_processor-0.6.
|
|
58
|
-
chuk_tool_processor-0.6.
|
|
59
|
-
chuk_tool_processor-0.6.
|
|
60
|
-
chuk_tool_processor-0.6.
|
|
57
|
+
chuk_tool_processor-0.6.7.dist-info/METADATA,sha256=2MPxA-1YJcyWceWZpucwslCce1w7xewFoDZXb1iDi80,23463
|
|
58
|
+
chuk_tool_processor-0.6.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
59
|
+
chuk_tool_processor-0.6.7.dist-info/top_level.txt,sha256=7lTsnuRx4cOW4U2sNJWNxl4ZTt_J1ndkjTbj3pHPY5M,20
|
|
60
|
+
chuk_tool_processor-0.6.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|