diff options
Diffstat (limited to 'third_party/mcpc/src/serlz.c')
| -rw-r--r-- | third_party/mcpc/src/serlz.c | 619 |
1 files changed, 619 insertions, 0 deletions
diff --git a/third_party/mcpc/src/serlz.c b/third_party/mcpc/src/serlz.c new file mode 100644 index 0000000..0721233 --- /dev/null +++ b/third_party/mcpc/src/serlz.c @@ -0,0 +1,619 @@ +// This file is part of the mcpc library. +// +// Copyright (C) 2025 Michael Lee <micl2e2 AT proton.me> +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#define __TU__ "serlz" + +#include "serlz.h" + +#include "ext_string.h" +#include "log.h" + + +/* = = = = = = = = = = = = = = = = = tool = = = = = = = = = = = = = = = = = */ + +u8_t +serlz_tool_inputschema_properties_prop (retbuf_t rtbf, const mcpc_toolprop_t *tprop) +{ + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + + const char8_t *name, *desc = nullptr; + size_t name_len, desc_len = 0; + + bug_if_nz (mcpc_toolprop_getref_name (tprop, &name, &name_len)); + bug_if_nz (mcpc_toolprop_getref_desc (tprop, &desc, &desc_len)); + + mcpc_anytype_t typ = MCPC_NONE; + bug_if_nz (mcpc_toolprop_get_data_type (tprop, &typ)); + + if (false) + ; + else if (mcpc_anytype_is_intlike (typ)) + { + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%Q"), "type", "integer"); + } + else if (typ == MCPC_U8STR) + { + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%Q"), "type", "string"); + } + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%.*Q"), "title", name_len, name); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%.*Q"), "description", desc_len, desc); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +u8_t +serlz_tool_inputschema_properties (retbuf_t rtbf, const mcpc_toolproppool_t *tppool) +{ + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + + if (tppool != nullptr) + { + size_t len_tppool = mcpc_toolproppool_get_len (tppool); + if (len_tppool > 0) + { + for (size_t i = 0; i < len_tppool; i++) + { + const mcpc_toolprop_t *tprop = mcpc_toolproppool_get (tppool, i); + size_t name_len = 0; + const char8_t *name = nullptr; + bug_if (mcpc_toolprop_getref_name (tprop, &name, &name_len)); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("%.*Q:"), name_len, name); + serlz_tool_inputschema_properties_prop (rtbf, tprop); + if (i != len_tppool - 1) + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + } + } + } + + + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +u8_t +serlz_tool_inputschema (retbuf_t rtbf, const mcpc_tool_t *tool) +{ + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%Q"), "type", "object"); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "properties"); + serlz_tool_inputschema_properties (rtbf, mcpc_tool_get_toolproppool (tool)); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:["), "required"); + bool first = true; + size_t property_count = mcpc_tool_get_toolprop_len (tool); + for (size_t i = 0; i < property_count; ++i) + { + const mcpc_toolprop_t *property = mcpc_tool_get_toolprop (tool, i); + const char8_t *name = nullptr; + size_t name_len = 0; + if (!mcpc_toolprop_is_required (property)) + continue; + bug_if_nz (mcpc_toolprop_getref_name (property, &name, &name_len)); + if (!first) + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%.*Q"), name_len, name); + first = false; + } + rtbuf_printf_mjfmt (rtbf, u8c1 ("]")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +uint8_t +serlz_tool (retbuf_t rtbf, const mcpc_tool_t *tool) +{ + const char8_t *name, *desc = nullptr; + size_t name_len, desc_len = 0; + bug_if_nz (mcpc_toolprop_getref_name (tool, &name, &name_len)); + bug_if_nz (mcpc_toolprop_getref_desc (tool, &desc, &desc_len)); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%.*Q"), "name", name_len, name); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%.*Q"), "description", desc_len, desc); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "inputSchema"); + serlz_tool_inputschema (rtbf, tool); + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +u8_t +serlz_toolpool (retbuf_t rtbf, const mcpc_toolpool_t *toolpool) +{ + size_t len_tpool = mcpc_toolpool_get_len (toolpool); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "tools"); + rtbuf_printf_mjfmt (rtbf, u8c1 ("[")); + + // TODO TODO TODO use iterator + if (toolpool != nullptr && len_tpool > 0) + { + for (size_t i = 0; i < len_tpool; i++) + { + const mcpc_tool_t *cur_tool = mcpc_toolpool_get (toolpool, i); + serlz_tool (rtbf, cur_tool); + if (i != len_tpool - 1) + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + } + } + + rtbuf_printf_mjfmt (rtbf, u8c1 ("]")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +/* = = = = = = = = = = = = = = = = = prmpt = = = = = = = = = = = = = = = = = */ + +u8_t +serlz_prmptarg (retbuf_t rtbf, const mcpc_prmptarg_t *prmptarg) +{ + const char8_t *name, *desc = nullptr; + size_t name_len, desc_len = 0; + bool required = false; + + bug_if_nz (mcpc_prmptarg_getref_name (prmptarg, &name, &name_len)); + bug_if_nz (mcpc_prmptarg_getref_desc (prmptarg, &desc, &desc_len)); + required = mcpc_prmptarg_is_required (prmptarg); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%.*Q"), "name", name_len, name); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%.*Q"), "description", desc_len, desc); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%B"), "required", required); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +uint8_t +serlz_prmpt (retbuf_t rtbf, const mcpc_prmpt_t *prmpt) +{ + const char8_t *name, *desc = nullptr; + size_t name_len, desc_len = 0; + bug_if_nz (mcpc_prmptarg_getref_name (prmpt, &name, &name_len)); + bug_if_nz (mcpc_prmptarg_getref_desc (prmpt, &desc, &desc_len)); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%.*Q"), "name", name_len, name); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%.*Q"), "description", desc_len, desc); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "arguments"); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("[")); + + const mcpc_prmptarg_t *cur_prmptarg = nullptr; + bool first = true; + while ((cur_prmptarg = mcpc_prmpt_get_next_prmptarg (prmpt))) + { + if (!first) + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + serlz_prmptarg (rtbf, cur_prmptarg); + first = false; + } + + rtbuf_printf_mjfmt (rtbf, u8c1 ("]")); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +u8_t +serlz_prmptpool (retbuf_t rtbf, const mcpc_prmptpool_t *prmptpool) +{ + size_t len_tpool = mcpc_prmptpool_get_len (prmptpool); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "prompts"); + rtbuf_printf_mjfmt (rtbf, u8c1 ("[")); + + if (prmptpool != nullptr && len_tpool > 0) + { + for (size_t i = 0; i < len_tpool; i++) + { + const mcpc_prmpt_t *cur_prmpt = mcpc_prmptpool_get (prmptpool, i); + serlz_prmpt (rtbf, cur_prmpt); + if (i != len_tpool - 1) + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + } + } + + rtbuf_printf_mjfmt (rtbf, u8c1 ("]")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +/* = = = = = = = = = = = = = = = = = = rsc = = = = = = = = = = = = = = = = = = */ + +u8_t +serlz_rsc (retbuf_t rtbf, const mcpc_rsc_t *rsc) +{ + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + + const char8_t *ref_uri = nullptr; + size_t ref_uri_len = 0; + const char8_t *ref_name = nullptr; + size_t ref_name_len = 0; + mcpc_mime_t mime = MCPC_MIME_NONE; + + mcpc_rsc_getref_uri (rsc, &ref_uri, &ref_uri_len); + mcpc_rsc_getref_name (rsc, &ref_name, &ref_name_len); + mcpc_rsc_get_mime (rsc, &mime); + + bool serlz_uri = ref_uri_len > 0 && ref_uri != nullptr; + bool serlz_name = ref_name_len > 0 && ref_name != nullptr; + bool serlz_mime = mime != MCPC_MIME_NONE; + + // uri is ID, hence first + if (serlz_uri) + { + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%.*Q"), "uri", ref_uri_len, (const char *) ref_uri); + } + + if (serlz_name) + { + if (serlz_uri) + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%.*Q"), "name", ref_name_len, ref_name); + } + + if (serlz_mime) + { + if (serlz_name || serlz_uri) + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "mimeType"); + if (false); + else if (mime == MCPC_MIME_TEXT_PLAIN) + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q"), u8c1 ("text/plain")); + else if (mime == MCPC_MIME_IMAGE_PNG) + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q"), u8c1 ("image/png")); + else if (mime == MCPC_MIME_IMAGE_JPEG) + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q"), u8c1 ("image/jpeg")); + else if (mime == MCPC_MIME_IMAGE_GIF) + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q"), u8c1 ("image/gif")); + else if (mime == MCPC_MIME_AUDIO_MPEG) + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q"), u8c1 ("audio/mpeg")); + else if (mime == MCPC_MIME_AUDIO_WAV) + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q"), u8c1 ("audio/wav")); + else if (mime == MCPC_MIME_VIDEO_MPEG) + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q"), u8c1 ("video/mpeg")); + else if (mime == MCPC_MIME_VIDEO_AVI) + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q"), u8c1 ("video/avi")); + else if (mime == MCPC_MIME_APPLI_OCTS) + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q"), u8c1 ("application/octet-stream")); + else if (mime == MCPC_MIME_APPLI_JSON) + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q"), u8c1 ("application/json")); + else if (mime == MCPC_MIME_APPLI_PDF) + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q"), u8c1 ("application/pdf")); + } + + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + + return 0; +} + +u8_t +serlz_rscpool (retbuf_t rtbf, const mcpc_rscpool_t *rscpool) +{ + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "resources"); + rtbuf_printf_mjfmt (rtbf, u8c1 ("[")); + + + const mcpc_rsc_t *cur_rsc = nullptr; + bool first = true; + while ((cur_rsc = mcpc_rscpool_get_next (rscpool))) + { + if (!first) + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + serlz_rsc (rtbf, cur_rsc); + first = false; + } + + rtbuf_printf_mjfmt (rtbf, u8c1 ("]")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +/* = = = = = = = = = = = = = = = = = = = - = = = = = = = = = = = = = = = = = = = */ + +uint8_t +serlz_serverInfo (retbuf_t rtbf, const mcpc_server_t *sv) +{ + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%.*Q"), "name", sv->name_len, sv->name); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%.*Q"), "version", sv->ver_len, sv->ver); + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +uint8_t +serlz_capasprompts (retbuf_t rtbf, const mcpc_server_t *sv) +{ + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "listChanged"); + bool supp_lschg = mcpc_server_supp_prompts_lschg (sv); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%B"), supp_lschg); + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +uint8_t +serlz_capastools (retbuf_t rtbf, const mcpc_server_t *sv) +{ + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "listChanged"); + bool supp_lschg = mcpc_server_supp_tools_lschg (sv); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%B"), supp_lschg); + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +uint8_t +serlz_capasresources (retbuf_t rtbf, const mcpc_server_t *sv) +{ + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "subscribe"); + bool supp_subs = mcpc_server_supp_rscs_subs (sv); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%B"), supp_subs); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "listChanged"); + bool supp_lschg = mcpc_server_supp_rscs_lschg (sv); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%B"), supp_lschg); + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +uint8_t +serlz_capas (retbuf_t rtbf, const mcpc_server_t *sv) +{ + bool need_comma = false; + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + + if (mcpc_server_supp_prompts (sv)) + { + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "prompts"); + serlz_capasprompts (rtbf, sv); + need_comma = true; + } + + if (mcpc_server_supp_tools (sv)) + { + if (need_comma) + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "tools"); + serlz_capastools (rtbf, sv); + need_comma = true; + } + + if (mcpc_server_supp_rscs (sv)) + { + if (need_comma) + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "resources"); + serlz_capasresources (rtbf, sv); + } + + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +uint8_t +serlz_initres (retbuf_t rtbf, const mcpc_server_t *sv) +{ + rtbuf_printf (rtbf, u8c1 ("{")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%Q"), "protocolVersion", "2024-11-05"); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "serverInfo"); + serlz_serverInfo (rtbf, sv); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "capabilities"); + serlz_capas (rtbf, sv); + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +/* = = = = = = = = = = = = = = = = = ucbr = = = = = = = = = = = = = = = = = */ + +uint8_t +serlz_ucbrchd_tool_callres (retbuf_t rtbf, const mcpc_ucbrchd_t *ucbrchd) +{ + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%Q"), "type", "text"); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "text"); + + mcpc_anytype_t data_type = MCPC_NONE; + bug_if_nz (mcpc_ucbrchd_get_data_type (ucbrchd, &data_type)); + + if (false) + ; + else if (data_type == MCPC_U8STR) + { + const char8_t *s = nullptr; + size_t s_len = 0; + mcpc_ucbrchd_getref_u8str (ucbrchd, &s, &s_len); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%.*Q"), s_len, (const char *) s); + } + + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +uint8_t +serlz_ucbrchd_prmpt_callres (retbuf_t rtbf, const mcpc_ucbrchd_t *ucbrchd) +{ + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "role"); + if (mcpc_ucbrchd_is_assist_prmpt (ucbrchd)) + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q"), "assistant"); + else + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q"), "user"); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "content"); + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%Q"), "type", "text"); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "text"); + + mcpc_anytype_t data_type = MCPC_NONE; + bug_if_nz (mcpc_ucbrchd_get_data_type (ucbrchd, &data_type)); + + if (false) + ; + else if (data_type == MCPC_U8STR) + { + const char8_t *s = nullptr; + size_t s_len = 0; + mcpc_ucbrchd_getref_u8str (ucbrchd, &s, &s_len); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%.*Q"), s_len, (const char *) s); + } + + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +uint8_t +serlz_ucbrchd (retbuf_t rtbf, const mcpc_ucbrchd_t *ucbrchd) +{ + if (false); + else if (mcpc_ucbrchd_is_tool_callres (ucbrchd)) + { + return serlz_ucbrchd_tool_callres (rtbf, ucbrchd); + } + else if (mcpc_ucbrchd_is_prmpt_callres (ucbrchd)) + { + return serlz_ucbrchd_prmpt_callres (rtbf, ucbrchd); + } + return 0; +} + +u8_t +serlz_ucbr (retbuf_t rtbf, const mcpc_ucbr_t *ucbr) +{ + rtbuf_printf_mjfmt (rtbf, u8c1 ("[")); + + size_t length = mcpc_ucbr_get_len (ucbr); + for (size_t i = 0; i < length; ++i) + { + const mcpc_ucbrchd_t *cur_ucbrchd = mcpc_ucbr_get (ucbr, i); + if (i != 0) + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + serlz_ucbrchd (rtbf, cur_ucbrchd); + } + + rtbuf_printf_mjfmt (rtbf, u8c1 ("]")); + return 0; +} + +u8_t +serlz_tool_callres (retbuf_t rtbf, const mcpc_ucbr_t *ucbr) +{ + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + + if (mcpc_ucbr_is_err (ucbr)) + { + // https://modelcontextprotocol.io/docs/concepts/tools#error-handling-2 + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%B"), "isError", true); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + } + + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "content"); + serlz_ucbr (rtbf, ucbr); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +u8_t +serlz_prmpt_callres (retbuf_t rtbf, const mcpc_ucbr_t *ucbr) +{ + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%Q"), "description", "Prompt List"); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "messages"); + serlz_ucbr (rtbf, ucbr); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} + +/* = = = = = = = = = = = = = = = = complt = = = = = = = = = = = = = = = = */ + +u8_t +serlz_complt (retbuf_t rtbf, const mcpc_complt_t *complt) +{ + size_t total = 0; + + mcpc_complt_get_compltcandi_len (complt, &total); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "completion"); + rtbuf_printf_mjfmt (rtbf, u8c1 ("{")); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%lu"), "total", total); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:%B"), "hasMore", false); + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("%Q:"), "values"); + rtbuf_printf_mjfmt (rtbf, u8c1 ("[")); + + const mcpc_compltcand_t *cur_compltcand = nullptr; + bool first = true; + while ((cur_compltcand = mcpc_complt_get_next_compltcand (complt))) + { + if (!first) + rtbuf_printf_mjfmt (rtbf, u8c1 (",")); + const char8_t *sbuf = nullptr; + size_t sbuf_len = 0; + bug_if_nz (mcpc_compltcand_getref_u8str (cur_compltcand, &sbuf, &sbuf_len)); + bug_if_nullptr (sbuf); + bug_if_zero (sbuf_len); + + rtbuf_printf_mjfmt (rtbf, u8c1 ("%.*Q"), sbuf_len, sbuf); + first = false; + } + + rtbuf_printf_mjfmt (rtbf, u8c1 ("]")); + + + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + rtbuf_printf_mjfmt (rtbf, u8c1 ("}")); + return 0; +} |
