Pudu programming language
Menu
Package

@chrismichaelps / pudu-lang-mcp

Model Context Protocol server for Pudu language documentation and compiler tools

0.1.1Apache-2.01

InstallClose

Negotiation.pudu

Pudu58 lines2.3 KB

GitHub ↗
1/** @Domain.Protocol.Negotiation.Backbone — admits requests by protocol era */2module PuduLangMcp.Domain.Protocol.Negotiation34import Std.Json as Json5import Std.Text as Text6import PuduLangMcp.Constants.Protocol as Protocol7import PuduLangMcp.Errors.RpcError as RpcError8import PuduLangMcp.Utils.JsonAccess as Access910/** @Domain.Protocol.Negotiation.Session — the only process-scoped protocol state */11export type Session = Unopened | Legacy(Str)1213/** @Domain.Protocol.Negotiation.Era — version governing one admitted request */14export type Era = Modern | LegacyEra(Str)1516/// The method that opens a legacy session.17const HANDSHAKE: Str = "initialize"1819/// Whether a method opens a legacy session.20export fn isHandshake(method: Str) -> Bool {21  method == HANDSHAKE22}2324/// The era governing one request, or the refusal to answer it with.25export fn admit(session: &Session, method: Str, params: &Json.Json) -> Result[Era, RpcError.ProtocolError] {26  let meta = match Access.member(params, Protocol.META_KEY) {27    case Some(Json.Object(fields)) => Json.Object(fields)28    case _ => Json.object(&[])29  }30  match Access.member(&meta, Protocol.META_PROTOCOL_VERSION) {31    case Some(Json.Text(requested)) => {32      if requested != Protocol.MODERN_VERSION {33        return Err(RpcError.UnsupportedVersion(requested))34      }35      match Access.member(&meta, Protocol.META_CLIENT_CAPABILITIES) {36        case Some(Json.Object(_)) => Ok(Modern)37        case _ => Err(RpcError.InvalidParams("_meta must include " + Protocol.META_CLIENT_CAPABILITIES + " as an object"))38      }39    }40    case Some(_) => Err(RpcError.InvalidParams(Protocol.META_PROTOCOL_VERSION + " must be a string"))41    case None => {42      if isHandshake(method) { return Ok(LegacyEra(negotiateLegacy(params))) }43      match session {44        case Legacy(version) => Ok(LegacyEra(version))45        case Unopened => Err(RpcError.InvalidParams("missing _meta " + Protocol.META_PROTOCOL_VERSION + "; send " + Protocol.MODERN_VERSION + " on every request, or call initialize first for " + Text.join(&Protocol.LEGACY_VERSIONS, ", ")))46      }47    }48  }49}5051/// The legacy version an `initialize` receives.52export fn negotiateLegacy(params: &Json.Json) -> Str {53  match Access.text(params, "protocolVersion") {54    case Some(asked) => if Protocol.isLegacyVersion(asked) { asked } else { Protocol.LATEST_LEGACY_VERSION }55    case None => Protocol.LATEST_LEGACY_VERSION56  }57}58