chat-peg-parser.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include "chat-peg-parser.h"
  2. #include <nlohmann/json.hpp>
  3. using json = nlohmann::json;
  4. static std::string_view trim_trailing_space(std::string_view sv) {
  5. while (!sv.empty() && std::isspace(static_cast<unsigned char>(sv.back()))) {
  6. sv.remove_suffix(1);
  7. }
  8. return sv;
  9. }
  10. void common_chat_peg_mapper::from_ast(const common_peg_ast_arena & arena, const common_peg_parse_result & result) {
  11. arena.visit(result, [this](const common_peg_ast_node & node) {
  12. map(node);
  13. });
  14. }
  15. void common_chat_peg_mapper::map(const common_peg_ast_node & node) {
  16. bool is_reasoning = node.tag == common_chat_peg_builder::REASONING;
  17. bool is_content = node.tag == common_chat_peg_builder::CONTENT;
  18. if (is_reasoning) {
  19. result.reasoning_content = std::string(trim_trailing_space(node.text));
  20. }
  21. if (is_content) {
  22. result.content = std::string(trim_trailing_space(node.text));
  23. }
  24. }
  25. void common_chat_peg_native_mapper::map(const common_peg_ast_node & node) {
  26. common_chat_peg_mapper::map(node);
  27. bool is_tool_open = node.tag == common_chat_peg_native_builder::TOOL_OPEN;
  28. bool is_tool_name = node.tag == common_chat_peg_native_builder::TOOL_NAME;
  29. bool is_tool_id = node.tag == common_chat_peg_native_builder::TOOL_ID;
  30. bool is_tool_args = node.tag == common_chat_peg_native_builder::TOOL_ARGS;
  31. if (is_tool_open) {
  32. result.tool_calls.emplace_back();
  33. current_tool = &result.tool_calls.back();
  34. }
  35. if (is_tool_id && current_tool) {
  36. current_tool->id = std::string(trim_trailing_space(node.text));
  37. }
  38. if (is_tool_name && current_tool) {
  39. current_tool->name = std::string(trim_trailing_space(node.text));
  40. }
  41. if (is_tool_args && current_tool) {
  42. current_tool->arguments = std::string(trim_trailing_space(node.text));
  43. }
  44. }
  45. void common_chat_peg_constructed_mapper::map(const common_peg_ast_node & node) {
  46. common_chat_peg_mapper::map(node);
  47. bool is_tool_open = node.tag == common_chat_peg_constructed_builder::TOOL_OPEN;
  48. bool is_tool_name = node.tag == common_chat_peg_constructed_builder::TOOL_NAME;
  49. bool is_tool_close = node.tag == common_chat_peg_constructed_builder::TOOL_CLOSE;
  50. bool is_arg_open = node.tag == common_chat_peg_constructed_builder::TOOL_ARG_OPEN;
  51. bool is_arg_close = node.tag == common_chat_peg_constructed_builder::TOOL_ARG_CLOSE;
  52. bool is_arg_name = node.tag == common_chat_peg_constructed_builder::TOOL_ARG_NAME;
  53. bool is_arg_string = node.tag == common_chat_peg_constructed_builder::TOOL_ARG_STRING_VALUE;
  54. bool is_arg_json = node.tag == common_chat_peg_constructed_builder::TOOL_ARG_JSON_VALUE;
  55. if (is_tool_open) {
  56. result.tool_calls.emplace_back();
  57. current_tool = &result.tool_calls.back();
  58. arg_count = 0;
  59. }
  60. if (is_tool_name) {
  61. current_tool->name = std::string(node.text);
  62. current_tool->arguments = "{";
  63. }
  64. if (is_arg_open) {
  65. needs_closing_quote = false;
  66. }
  67. if (is_arg_name && current_tool) {
  68. if (arg_count > 0) {
  69. current_tool->arguments += ",";
  70. }
  71. current_tool->arguments += json(trim_trailing_space(node.text)).dump() + ":";
  72. ++arg_count;
  73. }
  74. if (is_arg_string && current_tool) {
  75. // Serialize to JSON, but exclude the end quote
  76. std::string dumped = json(node.text).dump();
  77. current_tool->arguments += dumped.substr(0, dumped.size() - 1);
  78. needs_closing_quote = true;
  79. }
  80. if (is_arg_close && current_tool) {
  81. if (needs_closing_quote) {
  82. current_tool->arguments += "\"";
  83. }
  84. }
  85. if (is_arg_json && current_tool) {
  86. current_tool->arguments += std::string(trim_trailing_space(node.text));
  87. }
  88. if (is_tool_close && current_tool) {
  89. current_tool->arguments += "}";
  90. }
  91. }