chat-server.vala 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. /*
  2. * Chat MCP Server Example
  3. *
  4. * This example demonstrates how to create an MCP server that provides
  5. * chat-related prompts for different conversation scenarios. It shows how to
  6. * implement and register multiple prompt templates.
  7. *
  8. * Compile with:
  9. * valac --pkg mcp-vala --pkg json-glib-1.0 --pkg gee-0.8 --pkg posix chat-server.vala -o chat-server
  10. */
  11. using Mcp;
  12. using Posix;
  13. /**
  14. * Chat server that provides conversation prompts.
  15. */
  16. public class ChatServer : GLib.Object {
  17. private Mcp.Core.Server server;
  18. /**
  19. * Creates a new ChatServer.
  20. */
  21. public ChatServer () {
  22. // Create server information
  23. var server_info = new Mcp.Types.Protocol.ServerInfo (
  24. "chat-server",
  25. "1.0.0"
  26. );
  27. server_info.description = "MCP server providing chat and conversation prompts";
  28. // Create server capabilities with prompts enabled
  29. var capabilities = new Mcp.Types.Protocol.ServerCapabilities ();
  30. capabilities.logging = true;
  31. capabilities.prompts = new Mcp.Types.Protocol.PromptsCapabilities ();
  32. // Create server
  33. server = new Mcp.Core.Server (server_info, capabilities);
  34. // Register chat prompt templates
  35. setup_prompts ();
  36. }
  37. /**
  38. * Sets up chat prompt templates.
  39. */
  40. private void setup_prompts () {
  41. // Register conversation starter prompt
  42. var conversation_starter = new ConversationStarterPrompt ();
  43. try {
  44. server.prompt_manager.register_template ("conversation_starter", conversation_starter);
  45. } catch (Error e) {
  46. GLib.stderr.printf ("Failed to register conversation starter prompt: %s\n", e.message);
  47. }
  48. // Register code review prompt
  49. var code_review = new CodeReviewPrompt ();
  50. try {
  51. server.prompt_manager.register_template ("code_review", code_review);
  52. } catch (Error e) {
  53. GLib.stderr.printf ("Failed to register code review prompt: %s\n", e.message);
  54. }
  55. // Register brainstorming prompt
  56. var brainstorming = new BrainstormingPrompt ();
  57. try {
  58. server.prompt_manager.register_template ("brainstorming", brainstorming);
  59. } catch (Error e) {
  60. GLib.stderr.printf ("Failed to register brainstorming prompt: %s\n", e.message);
  61. }
  62. // Register interview prompt
  63. var interview = new InterviewPrompt ();
  64. try {
  65. server.prompt_manager.register_template ("interview", interview);
  66. } catch (Error e) {
  67. GLib.stderr.printf ("Failed to register interview prompt: %s\n", e.message);
  68. }
  69. // Register story writing prompt
  70. var story_writing = new StoryWritingPrompt ();
  71. try {
  72. server.prompt_manager.register_template ("story_writing", story_writing);
  73. } catch (Error e) {
  74. GLib.stderr.printf ("Failed to register story writing prompt: %s\n", e.message);
  75. }
  76. }
  77. /**
  78. * Runs the server.
  79. *
  80. * @return Exit code
  81. */
  82. public async int run () {
  83. try {
  84. // Start the server
  85. bool started = yield server.start ();
  86. if (!started) {
  87. GLib.stderr.printf ("Failed to start server\n");
  88. return 1;
  89. }
  90. // Chat server started successfully
  91. // Available prompts: conversation_starter, code_review, brainstorming, interview, story_writing
  92. // Waiting for MCP client connections...
  93. // Run the main loop
  94. var main_loop = new MainLoop ();
  95. // Connect shutdown signal
  96. server.shutdown.connect (() => {
  97. main_loop.quit ();
  98. });
  99. main_loop.run ();
  100. return 0;
  101. } catch (Error e) {
  102. GLib.stderr.printf ("Server error: %s\n", e.message);
  103. return 1;
  104. }
  105. }
  106. }
  107. /**
  108. * Conversation starter prompt template.
  109. */
  110. public class ConversationStarterPrompt : Mcp.Prompts.BaseTemplate {
  111. /**
  112. * Creates a new ConversationStarterPrompt.
  113. */
  114. public ConversationStarterPrompt () {
  115. base ("conversation_starter", "Conversation Starter", "Generates conversation starter prompts for different contexts");
  116. // Add arguments
  117. add_argument ("context", "Context", "The context or situation for the conversation (e.g., professional, casual, networking)", true);
  118. add_argument ("topic", "Topic", "The main topic to discuss", false);
  119. add_argument ("tone", "Tone", "The tone of the conversation (formal, casual, friendly, enthusiastic)", false);
  120. add_argument ("participants", "Participants", "Number of participants expected", false);
  121. }
  122. /**
  123. * {@inheritDoc}
  124. */
  125. protected override Gee.ArrayList<Mcp.Prompts.Types.PromptMessage> generate_messages (GLib.Variant arguments) {
  126. var messages = new Gee.ArrayList<Mcp.Prompts.Types.PromptMessage> ();
  127. string context = get_string_arg_variant (arguments, "context");
  128. string? topic = get_string_arg_variant (arguments, "topic", null);
  129. string? tone = get_string_arg_variant (arguments, "tone", null);
  130. int? participants = get_int_arg_variant (arguments, "participants", 2);
  131. string template = """Generate a conversation starter for a {{context}} context{{#topic}} focused on {{topic}}{{/topic}}{{#tone}} with a {{tone}} tone{{/tone}}{{#participants}} for {{participants}} participants{{/participants}}.
  132. The conversation starter should:
  133. 1. Be appropriate for the specified context
  134. 2. Engage participants naturally
  135. 3. Set a positive and collaborative atmosphere
  136. 4. Lead to meaningful discussion
  137. 5. Be concise but inviting
  138. Please provide 3-5 different conversation starter options, each with a brief explanation of when it would be most effective.""";
  139. messages.add (create_user_message (template, arguments));
  140. return messages;
  141. }
  142. /**
  143. * Gets a string argument from the arguments object.
  144. */
  145. private string? get_string_arg_variant (GLib.Variant arguments, string name, string? default_value = null) {
  146. if (arguments.lookup_value (name, null) != null) {
  147. return arguments.lookup_value (name, new VariantType ("s")).get_string ();
  148. }
  149. return default_value;
  150. }
  151. /**
  152. * Gets an integer argument from the arguments object.
  153. */
  154. private int get_int_arg_variant (GLib.Variant arguments, string name, int default_value = 0) {
  155. if (arguments.lookup_value (name, null) != null) {
  156. return arguments.lookup_value (name, new VariantType ("i")).get_int32 ();
  157. }
  158. return default_value;
  159. }
  160. }
  161. /**
  162. * Code review prompt template.
  163. */
  164. public class CodeReviewPrompt : Mcp.Prompts.BaseTemplate {
  165. /**
  166. * Creates a new CodeReviewPrompt.
  167. */
  168. public CodeReviewPrompt () {
  169. base ("code_review", "Code Review", "Generates a comprehensive code review prompt");
  170. // Add arguments
  171. add_argument ("code", "Code", "The code to review", true);
  172. add_argument ("language", "Language", "Programming language of the code", true);
  173. add_argument ("focus", "Focus Area", "Specific areas to focus on (security, performance, readability, best_practices, all)", false);
  174. add_argument ("experience_level", "Experience Level", "Target experience level (beginner, intermediate, advanced)", false);
  175. add_argument ("file_type", "File Type", "Type of file (function, class, module, script, config)", false);
  176. }
  177. /**
  178. * {@inheritDoc}
  179. */
  180. protected override Gee.ArrayList<Mcp.Prompts.Types.PromptMessage> generate_messages (GLib.Variant arguments) {
  181. var messages = new Gee.ArrayList<Mcp.Prompts.Types.PromptMessage> ();
  182. string code = get_string_arg_variant (arguments, "code");
  183. string language = get_string_arg_variant (arguments, "language");
  184. string? focus = get_string_arg_variant (arguments, "focus", "all");
  185. string? experience_level = get_string_arg_variant (arguments, "experience_level", "intermediate");
  186. string? file_type = get_string_arg_variant (arguments, "file_type", "code");
  187. string template = """Please perform a comprehensive code review of the following {{language}} {{file_type}}:
  188. ```{{language}}
  189. {{code}}
  190. ```
  191. Review Focus: {{focus}}
  192. Target Audience: {{experience_level}} developers
  193. Please analyze the code and provide feedback on:
  194. 1. **Code Quality & Readability**
  195. - Clarity and maintainability
  196. - Naming conventions
  197. - Code organization and structure
  198. - Comments and documentation
  199. 2. **Functionality & Logic**
  200. - Correctness of implementation
  201. - Edge cases handled
  202. - Algorithm efficiency
  203. - Logic flow and control structures
  204. 3. **Best Practices & Standards**
  205. - Language-specific conventions
  206. - Design patterns usage
  207. - Error handling
  208. - Security considerations
  209. 4. **Performance & Optimization**
  210. - Time and space complexity
  211. - Resource usage
  212. - Potential bottlenecks
  213. - Optimization opportunities
  214. 5. **Testing & Maintainability**
  215. - Testability of the code
  216. - Modularity and reusability
  217. - Coupling and cohesion
  218. - Future extensibility
  219. {{#focus}}
  220. For the {{focus}} focus, please pay special attention to:
  221. - Security vulnerabilities and potential exploits
  222. - Performance bottlenecks and optimization opportunities
  223. - Code readability and maintainability issues
  224. - Adherence to established best practices
  225. {{/focus}}
  226. Please provide:
  227. - Specific line-by-line feedback where relevant
  228. - Overall assessment and summary
  229. - Concrete suggestions for improvement
  230. - Positive aspects worth noting
  231. - Priority levels for issues found (critical, high, medium, low)
  232. Format your response constructively with clear explanations and actionable recommendations.""";
  233. messages.add (create_user_message (template, arguments));
  234. return messages;
  235. }
  236. /**
  237. * Gets a string argument from the arguments object.
  238. */
  239. private string? get_string_arg_variant (GLib.Variant arguments, string name, string? default_value = null) {
  240. if (arguments.lookup_value (name, null) != null) {
  241. return arguments.lookup_value (name, new VariantType ("s")).get_string ();
  242. }
  243. return default_value;
  244. }
  245. }
  246. /**
  247. * Brainstorming prompt template.
  248. */
  249. public class BrainstormingPrompt : Mcp.Prompts.BaseTemplate {
  250. /**
  251. * Creates a new BrainstormingPrompt.
  252. */
  253. public BrainstormingPrompt () {
  254. base ("brainstorming", "Brainstorming", "Generates structured brainstorming prompts");
  255. // Add arguments
  256. add_argument ("topic", "Topic", "The main topic or problem to brainstorm", true);
  257. add_argument ("brainstorm_type", "Type", "Type of brainstorming (ideas, solutions, pros_cons, mind_map)", false);
  258. add_argument ("constraints", "Constraints", "Any constraints or limitations to consider", false);
  259. add_argument ("time_limit", "Time Limit", "Time limit for brainstorming session in minutes", false);
  260. add_argument ("participants", "Participants", "Number of participants", false);
  261. }
  262. /**
  263. * {@inheritDoc}
  264. */
  265. protected override Gee.ArrayList<Mcp.Prompts.Types.PromptMessage> generate_messages (GLib.Variant arguments) {
  266. var messages = new Gee.ArrayList<Mcp.Prompts.Types.PromptMessage> ();
  267. string topic = get_string_arg_variant (arguments, "topic");
  268. string? brainstorm_type = get_string_arg_variant (arguments, "brainstorm_type", "ideas");
  269. string? constraints = get_string_arg_variant (arguments, "constraints", null);
  270. int? time_limit = get_int_arg_variant (arguments, "time_limit", 30);
  271. int? participants = get_int_arg_variant (arguments, "participants", 1);
  272. string template = """Facilitate a {{brainstorm_type}} brainstorming session for the following topic:
  273. **Topic:** {{topic}}
  274. {{#constraints}}
  275. **Constraints/Limitations:** {{constraints}}
  276. {{/constraints}}
  277. **Session Details:**
  278. - Duration: {{time_limit}} minutes
  279. - Participants: {{participants}}
  280. - Type: {{brainstorm_type}} brainstorming
  281. Please structure the session as follows:
  282. 1. **Warm-up (2-3 minutes)**
  283. - Briefly restate the topic and objectives
  284. - Set positive, creative atmosphere
  285. - Establish basic ground rules
  286. 2. **Divergent Thinking Phase** ({{time_limit_minus_5}} minutes)
  287. - Generate as many {{#ideas}}ideas{{/ideas}}{{#solutions}}potential solutions{{/solutions}}{{#pros_cons}}pros and cons{{/pros_cons}} as possible
  288. - Encourage wild and creative thinking
  289. - No judgment or criticism during this phase
  290. - Build on others' ideas when applicable
  291. 3. **Convergent Thinking Phase** (5 minutes)
  292. - Group similar {{#ideas}}ideas{{/ideas}}{{#solutions}}solutions{{/solutions}}{{#pros_cons}}points{{/pros_cons}}
  293. - Evaluate and prioritize
  294. - Look for patterns and connections
  295. - Select most promising options
  296. 4. **Action Planning (2-3 minutes)**
  297. - Identify next steps
  298. - Assign responsibilities if applicable
  299. - Set follow-up timeline
  300. {{#ideas}}
  301. Focus on quantity over quality initially. Use techniques like:
  302. - Word association
  303. - Mind mapping
  304. - SCAMPER (Substitute, Combine, Adapt, Modify, Put to other uses, Eliminate, Reverse)
  305. - Random word stimulation
  306. {{/ideas}}
  307. {{#solutions}}
  308. Focus on practical and innovative approaches:
  309. - Break the problem into smaller parts
  310. - Consider analogies from different domains
  311. - Think about first principles
  312. - Challenge assumptions
  313. {{/solutions}}
  314. {{#pros_cons}}
  315. Create balanced columns for advantages and disadvantages:
  316. - Consider short-term and long-term effects
  317. - Think about different stakeholders
  318. - Evaluate feasibility and resources needed
  319. {{/pros_cons}}
  320. Please provide specific facilitation techniques and keep the energy high throughout the session!""";
  321. // Add computed value for time limit
  322. var builder = new VariantBuilder (new VariantType ("a{sv}"));
  323. // Copy all existing arguments
  324. var iter = arguments.iterator ();
  325. string key;
  326. Variant value;
  327. while (iter.next ("{sv}", out key, out value)) {
  328. builder.add ("{sv}", key, value);
  329. }
  330. // Add computed value
  331. builder.add ("{sv}", "time_limit_minus_5", new Variant.int32 (time_limit - 5));
  332. var modified_args = builder.end ();
  333. messages.add (create_user_message (template, modified_args));
  334. return messages;
  335. }
  336. /**
  337. * Gets a string argument from the arguments object.
  338. */
  339. private string? get_string_arg_variant (GLib.Variant arguments, string name, string? default_value = null) {
  340. if (arguments.lookup_value (name, null) != null) {
  341. return arguments.lookup_value (name, new VariantType ("s")).get_string ();
  342. }
  343. return default_value;
  344. }
  345. /**
  346. * Gets an integer argument from the arguments object.
  347. */
  348. private int get_int_arg_variant (GLib.Variant arguments, string name, int default_value = 0) {
  349. if (arguments.lookup_value (name, null) != null) {
  350. return arguments.lookup_value (name, new VariantType ("i")).get_int32 ();
  351. }
  352. return default_value;
  353. }
  354. }
  355. /**
  356. * Interview prompt template.
  357. */
  358. public class InterviewPrompt : Mcp.Prompts.BaseTemplate {
  359. /**
  360. * Creates a new InterviewPrompt.
  361. */
  362. public InterviewPrompt () {
  363. base ("interview", "Interview", "Generates interview questions for different contexts");
  364. // Add arguments
  365. add_argument ("role", "Role", "Position being interviewed for", true);
  366. add_argument ("interview_type", "Type", "Type of interview (technical, behavioral, case_study, situational)", false);
  367. add_argument ("experience_level", "Experience Level", "Target experience level (junior, mid, senior, lead)", false);
  368. add_argument ("duration", "Duration", "Interview duration in minutes", false);
  369. add_argument ("company", "Company", "Company or organization name", false);
  370. }
  371. /**
  372. * {@inheritDoc}
  373. */
  374. protected override Gee.ArrayList<Mcp.Prompts.Types.PromptMessage> generate_messages (GLib.Variant arguments) {
  375. var messages = new Gee.ArrayList<Mcp.Prompts.Types.PromptMessage> ();
  376. string role = get_string_arg_variant (arguments, "role");
  377. string? interview_type = get_string_arg_variant (arguments, "interview_type", "technical");
  378. string? experience_level = get_string_arg_variant (arguments, "experience_level", "mid");
  379. int? duration = get_int_arg_variant (arguments, "duration", 60);
  380. string? company = get_string_arg_variant (arguments, "company", null);
  381. string template = """Generate a comprehensive interview plan for a {{experience_level}} {{role}} position at {{#company}}{{company}}{{/company}}{{^company}}the company{{/company}}.
  382. **Interview Details:**
  383. - Type: {{interview_type}} interview
  384. - Duration: {{duration}} minutes
  385. - Experience Level: {{experience_level}}
  386. Please create an interview structure that includes:
  387. 1. **Introduction & Ice Breakers** (5 minutes)
  388. - Welcome and introduction
  389. - Brief company/role overview
  390. - Comfort-building questions
  391. 2. **Experience & Background** (10-15 minutes)
  392. - Previous relevant experience
  393. - Technical skills and competencies
  394. - Project highlights and achievements
  395. - Career motivation and goals
  396. 3. **{{#technical}}Technical Assessment{{/technical}}{{#behavioral}}Behavioral Questions{{/behavioral}}{{#case_study}}Case Study{{/case_study}}{{#situational}}Situational Questions{{/situational}}** (20-30 minutes)
  397. {{#technical}}
  398. - Technical skills assessment
  399. - Problem-solving scenarios
  400. - Code review or system design
  401. - Technology stack questions
  402. - Best practices and patterns
  403. {{/technical}}
  404. {{#behavioral}}
  405. - Teamwork and collaboration examples
  406. - Conflict resolution
  407. - Leadership and initiative
  408. - Time management and prioritization
  409. - Dealing with failure or setbacks
  410. {{/behavioral}}
  411. {{#case_study}}
  412. - Real-world problem scenarios
  413. - Analytical thinking assessment
  414. - Decision-making process
  415. - Strategic thinking
  416. - Business impact consideration
  417. {{/case_study}}
  418. {{#situational}}
  419. - "What would you do if..." scenarios
  420. - Priority handling
  421. - Ethical dilemmas
  422. - Customer/client situations
  423. - Pressure and deadline situations
  424. {{/situational}}
  425. 4. **Candidate Questions** (10-15 minutes)
  426. - Questions about the role, team, and company
  427. - Growth and development opportunities
  428. - Company culture and values
  429. - Next steps and timeline
  430. 5. **Closing** (5 minutes)
  431. - Summary and next steps
  432. - Final questions from candidate
  433. - Clear communication of follow-up process
  434. For each section, provide:
  435. - Specific questions to ask
  436. - What to look for in answers
  437. - Red flags to watch for
  438. - Evaluation criteria
  439. Tailor the difficulty and depth of questions appropriately for a {{experience_level}} level candidate.""";
  440. // Add conditional values
  441. var builder = new VariantBuilder (new VariantType ("a{sv}"));
  442. // Copy all existing arguments
  443. var iter = arguments.iterator ();
  444. string key;
  445. Variant value;
  446. while (iter.next ("{sv}", out key, out value)) {
  447. builder.add ("{sv}", key, value);
  448. }
  449. // Add conditional values
  450. builder.add ("{sv}", "technical", new Variant.boolean (interview_type == "technical"));
  451. builder.add ("{sv}", "behavioral", new Variant.boolean (interview_type == "behavioral"));
  452. builder.add ("{sv}", "case_study", new Variant.boolean (interview_type == "case_study"));
  453. builder.add ("{sv}", "situational", new Variant.boolean (interview_type == "situational"));
  454. var modified_args = builder.end ();
  455. messages.add (create_user_message (template, modified_args));
  456. return messages;
  457. }
  458. /**
  459. * Gets a string argument from the arguments object.
  460. */
  461. private string? get_string_arg_variant (GLib.Variant arguments, string name, string? default_value = null) {
  462. if (arguments.lookup_value (name, null) != null) {
  463. return arguments.lookup_value (name, new VariantType ("s")).get_string ();
  464. }
  465. return default_value;
  466. }
  467. /**
  468. * Gets an integer argument from the arguments object.
  469. */
  470. private int get_int_arg_variant (GLib.Variant arguments, string name, int default_value = 0) {
  471. if (arguments.lookup_value (name, null) != null) {
  472. return arguments.lookup_value (name, new VariantType ("i")).get_int32 ();
  473. }
  474. return default_value;
  475. }
  476. }
  477. /**
  478. * Story writing prompt template.
  479. */
  480. public class StoryWritingPrompt : Mcp.Prompts.BaseTemplate {
  481. /**
  482. * Creates a new StoryWritingPrompt.
  483. */
  484. public StoryWritingPrompt () {
  485. base ("story_writing", "Story Writing", "Generates creative writing prompts and story structure guidance");
  486. // Add arguments
  487. add_argument ("genre", "Genre", "Story genre (fantasy, scifi, mystery, romance, thriller, horror, literary)", false);
  488. add_argument ("theme", "Theme", "Central theme or message", false);
  489. add_argument ("setting", "Setting", "Time and place of the story", false);
  490. add_argument ("characters", "Characters", "Brief character descriptions", false);
  491. add_argument ("plot_point", "Plot Point", "Starting plot point or inciting incident", false);
  492. add_argument ("story_length", "Story Length", "Target length (flash, short, novella, novel)", false);
  493. add_argument ("audience", "Audience", "Target audience (children, ya, adult)", false);
  494. }
  495. /**
  496. * {@inheritDoc}
  497. */
  498. protected override Gee.ArrayList<Mcp.Prompts.Types.PromptMessage> generate_messages (GLib.Variant arguments) {
  499. var messages = new Gee.ArrayList<Mcp.Prompts.Types.PromptMessage> ();
  500. string? genre = get_string_arg_variant (arguments, "genre", "general");
  501. string? theme = get_string_arg_variant (arguments, "theme", null);
  502. string? setting = get_string_arg_variant (arguments, "setting", null);
  503. string? characters = get_string_arg_variant (arguments, "characters", null);
  504. string? plot_point = get_string_arg_variant (arguments, "plot_point", null);
  505. string? story_length = get_string_arg_variant (arguments, "story_length", "short");
  506. string? audience = get_string_arg_variant (arguments, "audience", "adult");
  507. string template = """Generate a comprehensive story writing guide for a {{genre}} story.
  508. **Story Parameters:**
  509. {{#theme}}Theme: {{theme}}{{/theme}}
  510. {{#setting}}Setting: {{setting}}{{/setting}}
  511. {{#characters}}Characters: {{characters}}{{/characters}}
  512. {{#plot_point}}Plot Point: {{plot_point}}{{/plot_point}}
  513. Target Length: {{story_length}}
  514. Target Audience: {{audience}}
  515. Please provide a structured story guide that includes:
  516. 1. **Story Structure Outline**
  517. - Three-act structure or hero's journey framework
  518. - Key plot points and turning points
  519. - Character arcs and development
  520. - Pacing recommendations for {{story_length}} fiction
  521. 2. **{{genre}} Genre Conventions**
  522. - Tropes and expectations for {{genre}} stories
  523. - How to innovate within the genre
  524. - Reader satisfaction elements
  525. - Common pitfalls to avoid
  526. 3. **Character Development Guidance**
  527. {{#characters}}
  528. - How to develop the specified characters
  529. - Character voice and dialogue tips
  530. - Relationship dynamics
  531. {{/characters}}
  532. {{^characters}}
  533. - Creating compelling original characters
  534. - Protagonist and antagonist development
  535. - Supporting cast considerations
  536. {{/characters}}
  537. 4. **World-Building Elements**
  538. {{#setting}}
  539. - How to bring the setting to life
  540. - Sensory details and atmosphere
  541. - Integrating setting with plot
  542. {{/setting}}
  543. {{^setting}}
  544. - Creating immersive original worlds
  545. - Balancing description with action
  546. - Consistency considerations
  547. {{/setting}}
  548. 5. **Writing Style & Voice**
  549. - Narrative perspective recommendations
  550. - Tense and POV consistency
  551. - Dialogue vs. narration balance
  552. - Pacing for {{story_length}} fiction
  553. 6. **{{theme}}Theme Integration**
  554. - Weaving {{theme}} naturally into the narrative
  555. - Symbolism and metaphor opportunities
  556. - Avoiding heavy-handed messaging
  557. - Subtle thematic reinforcement
  558. 7. **Target Audience Considerations**
  559. - Age-appropriate content and complexity
  560. - Themes and topics suitable for {{audience}} readers
  561. - Reading level and vocabulary
  562. - Cultural sensitivity and inclusivity
  563. 8. **Writing Process & Tips**
  564. - Daily word count goals
  565. - Overcoming writer's block
  566. - Revision and editing strategies
  567. - Getting feedback and improving
  568. Please provide specific, actionable advice that will help the writer create a compelling {{genre}} story that resonates with {{audience}} readers.""";
  569. // Add conditional values
  570. var builder = new VariantBuilder (new VariantType ("a{sv}"));
  571. // Copy all existing arguments
  572. var iter = arguments.iterator ();
  573. string key;
  574. Variant value;
  575. while (iter.next ("{sv}", out key, out value)) {
  576. builder.add ("{sv}", key, value);
  577. }
  578. var modified_args = builder.end ();
  579. messages.add (create_user_message (template, modified_args));
  580. return messages;
  581. }
  582. /**
  583. * Gets a string argument from the arguments object.
  584. */
  585. private string? get_string_arg_variant (GLib.Variant arguments, string name, string? default_value = null) {
  586. if (arguments.lookup_value (name, null) != null) {
  587. return arguments.lookup_value (name, new VariantType ("s")).get_string ();
  588. }
  589. return default_value;
  590. }
  591. }
  592. /**
  593. * Main function.
  594. *
  595. * @param args Command line arguments
  596. * @return Exit code
  597. */
  598. public static int main (string[] args) {
  599. // Create and run the server
  600. var server = new ChatServer ();
  601. // Handle Ctrl+C to gracefully shutdown
  602. // For now, we'll skip signal handling to get the build working
  603. var loop = new MainLoop ();
  604. // Run the server
  605. server.run.begin ((obj, res) => {
  606. loop.quit ();
  607. });
  608. // Keep the main loop running
  609. loop.run ();
  610. return 0;
  611. }