vector_mcp 0.2.0 → 0.3.0
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.
- checksums.yaml +4 -4
- data/README.md +141 -3
- data/lib/vector_mcp/definitions.rb +3 -1
- data/lib/vector_mcp/handlers/core.rb +43 -0
- data/lib/vector_mcp/server/registry.rb +24 -0
- data/lib/vector_mcp/transport/sse/client_connection.rb +113 -0
- data/lib/vector_mcp/transport/sse/message_handler.rb +166 -0
- data/lib/vector_mcp/transport/sse/puma_config.rb +77 -0
- data/lib/vector_mcp/transport/sse/stream_manager.rb +92 -0
- data/lib/vector_mcp/transport/sse.rb +119 -460
- data/lib/vector_mcp/version.rb +1 -1
- metadata +20 -30
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module VectorMCP
|
4
|
+
module Transport
|
5
|
+
class SSE
|
6
|
+
# Manages Server-Sent Events streaming for client connections.
|
7
|
+
# Handles creation of streaming responses and message broadcasting.
|
8
|
+
class StreamManager
|
9
|
+
class << self
|
10
|
+
# Creates an SSE streaming response body for a client connection.
|
11
|
+
#
|
12
|
+
# @param client_conn [ClientConnection] The client connection to stream to
|
13
|
+
# @param endpoint_url [String] The URL for the client to POST messages to
|
14
|
+
# @param logger [Logger] Logger instance for debugging
|
15
|
+
# @return [Enumerator] Rack-compatible streaming response body
|
16
|
+
def create_sse_stream(client_conn, endpoint_url, logger)
|
17
|
+
Enumerator.new do |yielder|
|
18
|
+
# Send initial endpoint event
|
19
|
+
yielder << format_sse_event("endpoint", endpoint_url)
|
20
|
+
logger.debug { "Sent endpoint event to client #{client_conn.session_id}: #{endpoint_url}" }
|
21
|
+
|
22
|
+
# Start streaming thread for this client
|
23
|
+
client_conn.stream_thread = Thread.new do
|
24
|
+
stream_messages_to_client(client_conn, yielder, logger)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Keep the connection alive by yielding from the streaming thread
|
28
|
+
client_conn.stream_thread.join
|
29
|
+
rescue StandardError => e
|
30
|
+
logger.error { "Error in SSE stream for client #{client_conn.session_id}: #{e.message}\n#{e.backtrace.join("\n")}" }
|
31
|
+
ensure
|
32
|
+
logger.debug { "SSE stream ended for client #{client_conn.session_id}" }
|
33
|
+
client_conn.close
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Enqueues a message to a specific client connection.
|
38
|
+
#
|
39
|
+
# @param client_conn [ClientConnection] The target client connection
|
40
|
+
# @param message [Hash] The JSON-RPC message to send
|
41
|
+
# @return [Boolean] true if message was enqueued successfully
|
42
|
+
def enqueue_message(client_conn, message)
|
43
|
+
return false unless client_conn && !client_conn.closed?
|
44
|
+
|
45
|
+
client_conn.enqueue_message(message)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# Streams messages from a client's queue to the SSE connection.
|
51
|
+
# This method runs in a dedicated thread per client.
|
52
|
+
#
|
53
|
+
# @param client_conn [ClientConnection] The client connection
|
54
|
+
# @param yielder [Enumerator::Yielder] The response yielder
|
55
|
+
# @param logger [Logger] Logger instance
|
56
|
+
def stream_messages_to_client(client_conn, yielder, logger)
|
57
|
+
logger.debug { "Starting message streaming thread for client #{client_conn.session_id}" }
|
58
|
+
|
59
|
+
loop do
|
60
|
+
message = client_conn.dequeue_message
|
61
|
+
break if message.nil? # Queue closed or connection closed
|
62
|
+
|
63
|
+
begin
|
64
|
+
json_message = message.to_json
|
65
|
+
sse_data = format_sse_event("message", json_message)
|
66
|
+
yielder << sse_data
|
67
|
+
|
68
|
+
logger.debug { "Streamed message to client #{client_conn.session_id}: #{json_message}" }
|
69
|
+
rescue StandardError => e
|
70
|
+
logger.error { "Error streaming message to client #{client_conn.session_id}: #{e.message}" }
|
71
|
+
break
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
logger.debug { "Message streaming thread ended for client #{client_conn.session_id}" }
|
76
|
+
rescue StandardError => e
|
77
|
+
logger.error { "Fatal error in streaming thread for client #{client_conn.session_id}: #{e.message}\n#{e.backtrace.join("\n")}" }
|
78
|
+
end
|
79
|
+
|
80
|
+
# Formats data as a Server-Sent Event.
|
81
|
+
#
|
82
|
+
# @param event [String] The event type
|
83
|
+
# @param data [String] The event data
|
84
|
+
# @return [String] Properly formatted SSE event
|
85
|
+
def format_sse_event(event, data)
|
86
|
+
"event: #{event}\ndata: #{data}\n\n"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|