welsonjs/WelsonJS.Augmented/WelsonJS.Launcher/JsonRpc2Dispatcher.cs
Namhyeon, Go d7f58a9b0c Propagate request id and add tools call handler
Forward the JSON-RPC request id through the dispatcher and handler so methods can access the id. JsonRpc2Dispatcher now passes the id to dispatchMethodAsync, and the JsonRpc2 endpoint lambda accepts the id parameter. Implemented a call for "tools/call" that extracts the tool name via ser.ExtractFrom(id, "params", "name") and invokes a new ResolveToolsCall(string) stub (TODO: implement actual tool logic). This prepares the codepath for tooling invocation based on request params.
2026-03-07 14:44:14 +09:00

85 lines
2.6 KiB
C#

// JsonRpc2Dispatcher.cs
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2025 Catswords OSS and WelsonJS Contributors
// https://github.com/gnh1201/welsonjs
//
using log4net;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace WelsonJS.Launcher
{
public sealed class JsonRpc2Request
{
public string Version;
public string Method;
}
public sealed class JsonRpc2Exception : Exception
{
public JsonRpc2Exception(string message) : base(message) { }
public JsonRpc2Exception(string message, Exception inner) : base(message, inner) { }
}
public sealed class JsonRpc2Dispatcher
{
private readonly ILog _logger;
public JsonRpc2Dispatcher(ILog logger)
{
_logger = logger;
}
public async Task<string> HandleAsync(
string requestBody,
Func<string, JsSerializer, CancellationToken, Task<string>> dispatchMethodAsync,
CancellationToken ct)
{
if (string.IsNullOrEmpty(requestBody))
throw new JsonRpc2Exception("Empty request body");
if (dispatchMethodAsync == null)
throw new ArgumentNullException("dispatchMethodAsync");
using (var ser = new JsSerializer())
{
int id = ser.Load(requestBody);
try
{
string version = ser.ExtractFrom(id, "jsonrpc");
if (!string.Equals(version, "2.0", StringComparison.Ordinal))
throw new JsonRpc2Exception("Unsupported JSON-RPC version: " + version);
string method = ser.ExtractFrom(id, "method");
if (string.IsNullOrEmpty(method))
throw new JsonRpc2Exception("Missing method");
var req = new JsonRpc2Request
{
Version = version,
Method = method
};
return await dispatchMethodAsync(req.Method, id, ser, ct);
}
catch (JsonRpc2Exception)
{
throw;
}
catch (Exception ex)
{
if (_logger != null)
_logger.Error("[JsonRpc2] Parse error", ex);
throw new JsonRpc2Exception("Parse error", ex);
}
finally
{
ser.Unload(id);
}
}
}
}
}