types.vala 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /*
  2. * Copyright (C) 2025 Mcp-Vala Project
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this library; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. *
  18. * Author: Mcp-Vala Project
  19. */
  20. /**
  21. * Prompt-related data types for MCP protocol.
  22. *
  23. * This namespace contains all prompt-related types defined by the MCP specification,
  24. * including prompt definitions, arguments, and related structures.
  25. */
  26. namespace Mcp.Prompts.Types {
  27. /**
  28. * Prompt definition as defined by MCP protocol.
  29. */
  30. public class PromptDefinition : GLib.Object {
  31. /**
  32. * Name of the prompt.
  33. */
  34. public string name { get; set; }
  35. /**
  36. * Optional title of the prompt.
  37. */
  38. public string? title { get; set; }
  39. /**
  40. * Optional description of the prompt.
  41. */
  42. public string? description { get; set; }
  43. /**
  44. * List of prompt arguments.
  45. */
  46. public Gee.ArrayList<PromptArgument> arguments { get; set; }
  47. /**
  48. * Creates a new PromptDefinition.
  49. *
  50. * @param name Name of the prompt
  51. */
  52. public PromptDefinition (string name) {
  53. this.name = name;
  54. this.arguments = new Gee.ArrayList<PromptArgument> ();
  55. }
  56. /**
  57. * Serializes PromptDefinition to GLib.Variant.
  58. *
  59. * @return A GLib.Variant representing this PromptDefinition
  60. */
  61. public Variant to_variant () {
  62. var builder = Mcp.Types.VariantUtils.new_dict_builder ();
  63. builder.add ("{sv}", "name", new Variant.string (name));
  64. Mcp.Types.VariantUtils.add_string_if_not_null (builder, "title", title);
  65. Mcp.Types.VariantUtils.add_string_if_not_null (builder, "description", description);
  66. // Serialize arguments array
  67. var args_builder = Mcp.Types.VariantUtils.new_dict_array_builder ();
  68. foreach (var arg in arguments) {
  69. args_builder.add_value (arg.to_variant ());
  70. }
  71. builder.add ("{sv}", "arguments", args_builder.end ());
  72. return builder.end ();
  73. }
  74. /**
  75. * Creates a PromptDefinition from GLib.Variant.
  76. *
  77. * @param variant The GLib.Variant to deserialize
  78. * @return The deserialized PromptDefinition
  79. * @throws Error If deserialization fails
  80. */
  81. public PromptDefinition.from_variant (Variant variant) throws Error {
  82. if (!variant.is_of_type (VariantType.VARDICT)) {
  83. throw new Mcp.Core.McpError.PARSE_ERROR ("PromptDefinition must be a dictionary");
  84. }
  85. if (variant.lookup_value ("name", null) == null) {
  86. throw new Mcp.Core.McpError.INVALID_REQUEST ("Missing name in PromptDefinition");
  87. }
  88. this.name = variant.lookup_value ("name", VariantType.STRING).get_string ();
  89. if (variant.lookup_value ("title", null) != null) {
  90. this.title = variant.lookup_value ("title", VariantType.STRING).get_string ();
  91. }
  92. if (variant.lookup_value ("description", null) != null) {
  93. this.description = variant.lookup_value ("description", VariantType.STRING).get_string ();
  94. }
  95. this.arguments = new Gee.ArrayList<PromptArgument> ();
  96. if (variant.lookup_value ("arguments", null) != null) {
  97. var args = variant.lookup_value ("arguments", new VariantType ("aa{sv}"));
  98. for (size_t i = 0; i < args.n_children (); i++) {
  99. var arg = new PromptArgument.from_variant (args.get_child_value (i));
  100. arguments.add (arg);
  101. }
  102. }
  103. }
  104. }
  105. /**
  106. * Prompt argument definition.
  107. */
  108. public class PromptArgument : GLib.Object {
  109. /**
  110. * Name of the argument.
  111. */
  112. public string name { get; set; }
  113. /**
  114. * Optional title of the argument.
  115. */
  116. public string? title { get; set; }
  117. /**
  118. * Optional description of the argument.
  119. */
  120. public string? description { get; set; }
  121. /**
  122. * Whether the argument is required.
  123. */
  124. public bool required { get; set; default = false; }
  125. /**
  126. * Creates a new PromptArgument.
  127. *
  128. * @param name Name of the argument
  129. */
  130. public PromptArgument (string name) {
  131. this.name = name;
  132. }
  133. /**
  134. * Serializes PromptArgument to GLib.Variant.
  135. *
  136. * @return A GLib.Variant representing this PromptArgument
  137. */
  138. public Variant to_variant () {
  139. var builder = Mcp.Types.VariantUtils.new_dict_builder ();
  140. builder.add ("{sv}", "name", new Variant.string (name));
  141. Mcp.Types.VariantUtils.add_string_if_not_null (builder, "title", title);
  142. Mcp.Types.VariantUtils.add_string_if_not_null (builder, "description", description);
  143. builder.add ("{sv}", "required", new Variant.boolean (required));
  144. return builder.end ();
  145. }
  146. /**
  147. * Creates a PromptArgument from GLib.Variant.
  148. *
  149. * @param variant The GLib.Variant to deserialize
  150. * @return The deserialized PromptArgument
  151. * @throws Error If deserialization fails
  152. */
  153. public PromptArgument.from_variant (Variant variant) throws Error {
  154. if (!variant.is_of_type (VariantType.VARDICT)) {
  155. throw new Mcp.Core.McpError.PARSE_ERROR ("PromptArgument must be a dictionary");
  156. }
  157. if (variant.lookup_value ("name", null) == null) {
  158. throw new Mcp.Core.McpError.INVALID_REQUEST ("Missing name in PromptArgument");
  159. }
  160. this.name = variant.lookup_value ("name", VariantType.STRING).get_string ();
  161. if (variant.lookup_value ("title", null) != null) {
  162. this.title = variant.lookup_value ("title", VariantType.STRING).get_string ();
  163. }
  164. if (variant.lookup_value ("description", null) != null) {
  165. this.description = variant.lookup_value ("description", VariantType.STRING).get_string ();
  166. }
  167. if (variant.lookup_value ("required", null) != null) {
  168. this.required = variant.lookup_value ("required", VariantType.BOOLEAN).get_boolean ();
  169. }
  170. }
  171. }
  172. /**
  173. * Result of getting a prompt.
  174. */
  175. public class GetPromptResult : GLib.Object {
  176. /**
  177. * Optional description of the prompt result.
  178. */
  179. public string? description { get; set; }
  180. /**
  181. * List of prompt messages.
  182. */
  183. public Gee.ArrayList<PromptMessage> messages { get; set; }
  184. /**
  185. * Creates a new GetPromptResult.
  186. */
  187. public GetPromptResult () {
  188. messages = new Gee.ArrayList<PromptMessage> ();
  189. }
  190. /**
  191. * Serializes GetPromptResult to GLib.Variant.
  192. *
  193. * @return A GLib.Variant representing this GetPromptResult
  194. */
  195. public Variant to_variant () {
  196. var builder = Mcp.Types.VariantUtils.new_dict_builder ();
  197. Mcp.Types.VariantUtils.add_string_if_not_null (builder, "description", description);
  198. // Serialize messages array
  199. var messages_builder = Mcp.Types.VariantUtils.new_dict_array_builder ();
  200. foreach (var message in messages) {
  201. messages_builder.add_value (message.to_variant ());
  202. }
  203. builder.add ("{sv}", "messages", messages_builder.end ());
  204. return builder.end ();
  205. }
  206. /**
  207. * Creates a GetPromptResult from GLib.Variant.
  208. *
  209. * @param variant The GLib.Variant to deserialize
  210. * @return The deserialized GetPromptResult
  211. * @throws Error If deserialization fails
  212. */
  213. public GetPromptResult.from_variant (Variant variant) throws Error {
  214. if (!variant.is_of_type (VariantType.VARDICT)) {
  215. throw new Mcp.Core.McpError.PARSE_ERROR ("GetPromptResult must be a dictionary");
  216. }
  217. if (variant.lookup_value ("description", null) != null) {
  218. this.description = variant.lookup_value ("description", VariantType.STRING).get_string ();
  219. }
  220. this.messages = new Gee.ArrayList<PromptMessage> ();
  221. if (variant.lookup_value ("messages", null) != null) {
  222. var messages = variant.lookup_value ("messages", new VariantType ("aa{sv}"));
  223. for (size_t i = 0; i < messages.n_children (); i++) {
  224. var message = new PromptMessage.from_variant (messages.get_child_value (i));
  225. this.messages.add (message);
  226. }
  227. }
  228. }
  229. }
  230. /**
  231. * Prompt message.
  232. */
  233. public class PromptMessage : GLib.Object {
  234. /**
  235. * Role of the message sender ("user" or "assistant").
  236. */
  237. public string role { get; set; }
  238. /**
  239. * Content of the message.
  240. */
  241. public Mcp.Types.Common.ContentBlock content { get; set; }
  242. /**
  243. * Creates a new PromptMessage.
  244. *
  245. * @param role Role of the message
  246. * @param content Content of the message
  247. */
  248. public PromptMessage (string role, Mcp.Types.Common.ContentBlock content) {
  249. this.role = role;
  250. this.content = content;
  251. }
  252. /**
  253. * Serializes PromptMessage to GLib.Variant.
  254. *
  255. * @return A GLib.Variant representing this PromptMessage
  256. */
  257. public Variant to_variant () {
  258. var builder = Mcp.Types.VariantUtils.new_dict_builder ();
  259. builder.add ("{sv}", "role", new Variant.string (role));
  260. builder.add ("{sv}", "content", content.to_variant ());
  261. return builder.end ();
  262. }
  263. /**
  264. * Creates a PromptMessage from GLib.Variant.
  265. *
  266. * @param variant The GLib.Variant to deserialize
  267. * @return The deserialized PromptMessage
  268. * @throws Error If deserialization fails
  269. */
  270. public PromptMessage.from_variant (Variant variant) throws Error {
  271. if (!variant.is_of_type (VariantType.VARDICT)) {
  272. throw new Mcp.Core.McpError.PARSE_ERROR ("PromptMessage must be a dictionary");
  273. }
  274. if (variant.lookup_value ("role", null) == null) {
  275. throw new Mcp.Core.McpError.INVALID_REQUEST ("Missing role in PromptMessage");
  276. }
  277. if (variant.lookup_value ("content", null) == null) {
  278. throw new Mcp.Core.McpError.INVALID_REQUEST ("Missing content in PromptMessage");
  279. }
  280. this.role = variant.lookup_value ("role", VariantType.STRING).get_string ();
  281. var content = variant.lookup_value ("content", VariantType.VARDICT);
  282. // TODO: Determine content block type and deserialize appropriately
  283. // For now, assume TextContent
  284. if (content.lookup_value ("type", null) != null &&
  285. content.lookup_value ("type", VariantType.STRING).get_string () == "text") {
  286. this.content = new Mcp.Types.Common.TextContent.from_variant (content);
  287. } else {
  288. throw new Mcp.Core.McpError.INVALID_REQUEST ("Unsupported content type in PromptMessage");
  289. }
  290. }
  291. }
  292. }