copilotkit-runtime 0.1.0.rc.1
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 +7 -0
- data/LICENSE +21 -0
- data/README.md +445 -0
- data/lib/copilotkit/a2ui.rb +334 -0
- data/lib/copilotkit/agent.rb +46 -0
- data/lib/copilotkit/inspector_metadata.rb +82 -0
- data/lib/copilotkit/intelligence.rb +371 -0
- data/lib/copilotkit/mcp_apps.rb +199 -0
- data/lib/copilotkit/runner.rb +353 -0
- data/lib/copilotkit/runtime.rb +386 -0
- data/lib/copilotkit/runtime_entitlements.rb +53 -0
- data/lib/copilotkit/telemetry.rb +186 -0
- data/lib/copilotkit/ui_agent.rb +38 -0
- data/lib/copilotkit/websocket.rb +84 -0
- metadata +83 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'socket'
|
|
3
|
+
require 'openssl'
|
|
4
|
+
require 'websocket'
|
|
5
|
+
|
|
6
|
+
module CopilotKit
|
|
7
|
+
# Small synchronous WebSocket transport with verified TLS and an owned reader.
|
|
8
|
+
# Protocol framing uses the websocket gem; TLS trust and timeouts stay explicit.
|
|
9
|
+
class WebSocketTransport
|
|
10
|
+
def initialize(url, headers, &on_message)
|
|
11
|
+
uri = URI(url)
|
|
12
|
+
raise ArgumentError, 'WebSocket URL must use ws or wss' unless %w[ws wss].include?(uri.scheme)
|
|
13
|
+
@closed, @write_mutex = false, Mutex.new
|
|
14
|
+
@socket = Socket.tcp(uri.host, uri.port || (uri.scheme == 'wss' ? 443 : 80), connect_timeout: 5)
|
|
15
|
+
if uri.scheme == 'wss'
|
|
16
|
+
context = OpenSSL::SSL::SSLContext.new
|
|
17
|
+
context.set_params(verify_mode: OpenSSL::SSL::VERIFY_PEER)
|
|
18
|
+
context.verify_hostname = true
|
|
19
|
+
@socket = OpenSSL::SSL::SSLSocket.new(@socket, context)
|
|
20
|
+
@socket.sync_close = true
|
|
21
|
+
@socket.hostname = uri.host
|
|
22
|
+
Timeout.timeout(5) { @socket.connect }
|
|
23
|
+
@socket.post_connection_check(uri.host)
|
|
24
|
+
end
|
|
25
|
+
handshake = WebSocket::Handshake::Client.new(url: url, headers: headers)
|
|
26
|
+
@socket.write(handshake.to_s)
|
|
27
|
+
Timeout.timeout(5) do
|
|
28
|
+
until handshake.finished?
|
|
29
|
+
byte = @socket.read(1)
|
|
30
|
+
raise Error.new(502, 'Gateway handshake ended early') unless byte
|
|
31
|
+
handshake << byte
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
raise Error.new(502, 'Gateway WebSocket upgrade rejected') unless handshake.valid?
|
|
35
|
+
@version = handshake.version
|
|
36
|
+
@reader = Thread.new do
|
|
37
|
+
decoder = WebSocket::Frame::Incoming::Client.new
|
|
38
|
+
loop do
|
|
39
|
+
decoder << @socket.readpartial(16_384)
|
|
40
|
+
while (frame = decoder.next)
|
|
41
|
+
case frame.type
|
|
42
|
+
when :text then on_message.call(JSON.parse(frame.data))
|
|
43
|
+
when :ping then write(frame.data, type: :pong)
|
|
44
|
+
when :close
|
|
45
|
+
on_message.call([:closed])
|
|
46
|
+
break
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
# The framing gem reports unsupported close codes (including 1012)
|
|
50
|
+
# through error? rather than raising. Treat them as a closed transport
|
|
51
|
+
# immediately so pending events replay without waiting for an ACK timeout.
|
|
52
|
+
raise Error.new(502, 'Gateway framing failed') if decoder.error?
|
|
53
|
+
end
|
|
54
|
+
rescue StandardError
|
|
55
|
+
on_message.call([:closed]) unless @closed
|
|
56
|
+
end
|
|
57
|
+
rescue StandardError
|
|
58
|
+
@socket&.close
|
|
59
|
+
raise
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def send(data)
|
|
63
|
+
write(data)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def close
|
|
67
|
+
@closed = true
|
|
68
|
+
@socket&.close
|
|
69
|
+
@reader&.join(1) unless @reader == Thread.current
|
|
70
|
+
rescue IOError, SystemCallError
|
|
71
|
+
nil
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def write(data, type: :text)
|
|
77
|
+
@write_mutex.synchronize do
|
|
78
|
+
raise Error.new(502, 'Gateway connection is closed') if @closed
|
|
79
|
+
frame = WebSocket::Frame::Outgoing::Client.new(data: data, type: type, version: @version)
|
|
80
|
+
@socket.write(frame.to_s)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: copilotkit-runtime
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0.rc.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- CopilotKit
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-09-17 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: base64
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0.2'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0.2'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: websocket
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '1.2'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '1.2'
|
|
41
|
+
description:
|
|
42
|
+
email:
|
|
43
|
+
executables: []
|
|
44
|
+
extensions: []
|
|
45
|
+
extra_rdoc_files: []
|
|
46
|
+
files:
|
|
47
|
+
- LICENSE
|
|
48
|
+
- README.md
|
|
49
|
+
- lib/copilotkit/a2ui.rb
|
|
50
|
+
- lib/copilotkit/agent.rb
|
|
51
|
+
- lib/copilotkit/inspector_metadata.rb
|
|
52
|
+
- lib/copilotkit/intelligence.rb
|
|
53
|
+
- lib/copilotkit/mcp_apps.rb
|
|
54
|
+
- lib/copilotkit/runner.rb
|
|
55
|
+
- lib/copilotkit/runtime.rb
|
|
56
|
+
- lib/copilotkit/runtime_entitlements.rb
|
|
57
|
+
- lib/copilotkit/telemetry.rb
|
|
58
|
+
- lib/copilotkit/ui_agent.rb
|
|
59
|
+
- lib/copilotkit/websocket.rb
|
|
60
|
+
homepage: https://github.com/CopilotKit/CopilotKit
|
|
61
|
+
licenses:
|
|
62
|
+
- MIT
|
|
63
|
+
metadata: {}
|
|
64
|
+
post_install_message:
|
|
65
|
+
rdoc_options: []
|
|
66
|
+
require_paths:
|
|
67
|
+
- lib
|
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - ">="
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '2.7'
|
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
|
+
requirements:
|
|
75
|
+
- - ">="
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '0'
|
|
78
|
+
requirements: []
|
|
79
|
+
rubygems_version: 3.5.22
|
|
80
|
+
signing_key:
|
|
81
|
+
specification_version: 4
|
|
82
|
+
summary: Native Intelligence runtime for Ruby Rack applications
|
|
83
|
+
test_files: []
|