Class: Kward::RPC::Server
- Inherits:
-
Object
- Object
- Kward::RPC::Server
- Defined in:
- lib/kward/rpc/server.rb
Overview
Experimental JSON-RPC backend for UI clients.
The server speaks LSP-style Content-Length framing over stdin/stdout,
exposes capabilities during initialize, redacts secrets in errors and
notifications, and coordinates auth, config, sessions, turns, tools,
memory, commands, and startup resources.
Server should stay focused on protocol concerns: framing, JSON-RPC error
codes, method dispatch, capability reporting, and redaction at the wire
boundary. Delegate stateful product behavior to manager objects such as
SessionManager, AuthManager, and ConfigManager. When adding an RPC
feature, update dispatch, capabilities, docs, and tests together so clients
can trust initialize as the source of supported behavior.
Constant Summary collapse
- PROTOCOL_VERSION =
1- JSONRPC_VERSION =
"2.0"- BUILTIN_SLASH_COMMAND_NAMES =
PromptCommands::BUILTIN_RESERVED_COMMAND_NAMES
- ERROR_CODES =
{ parse_error: -32_700, invalid_request: -32_600, method_not_found: -32_601, invalid_params: -32_602, internal_error: -32_603 }.freeze
- PROTOCOL_METHODS =
["initialize", "shutdown"].freeze
- WORKSPACE_METHODS =
["workspace/validate", "workspace/info"].freeze
- TOOL_METHODS =
["tools/list"].freeze
- PROMPT_METHODS =
["prompts/list", "prompts/expand"].freeze
- SESSION_METHODS =
[ "sessions/create", "sessions/resume", "sessions/list", "sessions/rename", "sessions/clone", "sessions/compact", "sessions/forkMessages", "sessions/fork", "sessions/tree", "sessions/tree/setLabel", "sessions/tree/navigate", "sessions/export", "sessions/delete", "sessions/close", "sessions/transcript" ].freeze
- TURN_METHODS =
["turns/start", "turns/cancel", "turns/status", "turns/events"].freeze
- MODEL_METHODS =
["models/list", "models/current", "models/set", "reasoning/set"].freeze
- RUNTIME_METHODS =
["runtime/state", "runtime/stats"].freeze
- RUNTIME_SETTING_METHODS =
["runtime/updateSetting", "runtime/reload"].freeze
- AUTH_METHODS =
[ "auth/status", "auth/providers", "auth/loginWithApiKey", "auth/logoutProvider", "auth/loginWithOAuth", "auth/startOpenAILogin", "auth/submitOpenAICode", "auth/loginStatus" ].freeze
- MEMORY_METHODS =
[ "memory/status", "memory/enable", "memory/disable", "memory/autoSummary/enable", "memory/autoSummary/disable", "memory/list", "memory/add", "memory/addCore", "memory/forget", "memory/promote", "memory/relax", "memory/inspect", "memory/why", "memory/summarize" ].freeze
- WORKER_METHODS =
["workers/list", "workers/show"].freeze
- COMMAND_METHODS =
["commands/list", "commands/run"].freeze
- STARTUP_RESOURCE_METHODS =
["resources/startup"].freeze
- CONFIG_METHODS =
["config/read", "config/update"].freeze
- LOGGING_METHODS =
["logging/stats", "logging/tokenCsv"].freeze
- UI_METHODS =
["ui/answerQuestion"].freeze
- SESSION_EVENT_NOTIFICATION =
"session/event"- SESSION_UPDATED_NOTIFICATION =
"session/updated"- TURN_EVENT_NOTIFICATION =
"turn/event"- UI_QUESTION_NOTIFICATION =
"ui/question"- UI_FOOTER_NOTIFICATION =
"ui/footer"- METHOD_GROUPS =
{ protocol: PROTOCOL_METHODS, workspace: WORKSPACE_METHODS, tools: TOOL_METHODS, prompts: PROMPT_METHODS, sessions: SESSION_METHODS, turns: TURN_METHODS, models: MODEL_METHODS, runtime: RUNTIME_METHODS, runtime_settings: RUNTIME_SETTING_METHODS, auth: AUTH_METHODS, memory: MEMORY_METHODS, workers: WORKER_METHODS, commands: COMMAND_METHODS, startup_resources: STARTUP_RESOURCE_METHODS, config: CONFIG_METHODS, logging: LOGGING_METHODS, ui: UI_METHODS }.freeze
- RPC_METHODS =
METHOD_GROUPS.values.flatten.freeze
Instance Method Summary collapse
-
#error_payload(error) ⇒ Hash
Builds redacted diagnostics suitable for JSON-RPC error data.
-
#initialize(input: $stdin, output: $stdout, error_output: $stderr, client: Client.new, experimental_workers: false) ⇒ Server
constructor
Creates the RPC server and its stateful managers.
- #log_error(error) ⇒ Object
-
#notify(method, params = {}) ⇒ Object
Sends a redacted JSON-RPC notification to the client.
-
#run ⇒ void
Reads framed JSON-RPC messages until shutdown or EOF.
Constructor Details
#initialize(input: $stdin, output: $stdout, error_output: $stderr, client: Client.new, experimental_workers: false) ⇒ Server
Creates the RPC server and its stateful managers.
104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/kward/rpc/server.rb', line 104 def initialize(input: $stdin, output: $stdout, error_output: $stderr, client: Client.new, experimental_workers: false) @transport = Transport.new(input: input, output: output) @error_output = error_output @client = client @config_manager = ConfigManager.new @session_manager = SessionManager.new(server: self, client: client, config_manager: @config_manager) @auth_manager = AuthManager.new(server: self, config_manager: @config_manager) @worker_store = Workers::Store.new @experimental_workers = experimental_workers @shutdown = false end |
Instance Method Details
#error_payload(error) ⇒ Hash
Builds redacted diagnostics suitable for JSON-RPC error data.
148 149 150 151 152 153 154 |
# File 'lib/kward/rpc/server.rb', line 148 def error_payload(error) Redactor.redact({ code: error.class.name, message: error., backtrace: Array(error.backtrace).first(8) }) end |
#log_error(error) ⇒ Object
156 157 158 |
# File 'lib/kward/rpc/server.rb', line 156 def log_error(error) @error_output.puts("Kward RPC error: #{Redactor.redact_string(error.)}") if @error_output end |
#notify(method, params = {}) ⇒ Object
Sends a redacted JSON-RPC notification to the client.
140 141 142 |
# File 'lib/kward/rpc/server.rb', line 140 def notify(method, params = {}) @transport.({ jsonrpc: JSONRPC_VERSION, method: method, params: Redactor.redact(params) }) end |
#run ⇒ void
This method returns an undefined value.
Reads framed JSON-RPC messages until shutdown or EOF.
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/kward/rpc/server.rb', line 119 def run until @shutdown begin = @transport. break unless () rescue JSON::ParserError => e write_error(nil, ERROR_CODES[:parse_error], "Parse error", e) rescue StandardError => e write_error(nil, ERROR_CODES[:invalid_request], e., e) end end ensure @session_manager.shutdown_sessions end |