| 88 | } |
| 89 | |
| 90 | common_peg_arena autoparser::build_parser(const generation_params & inputs) const { |
| 91 | if (!analysis_complete) { |
| 92 | throw std::invalid_argument("Cannot call build_parser on autoparser without performing analysis first, call analyze_template(...)"); |
| 93 | } |
| 94 | return build_chat_peg_parser([&](common_chat_peg_builder & p) { |
| 95 | parser_build_context ctx(p, inputs); |
| 96 | bool extract_reasoning = inputs.reasoning_format != COMMON_REASONING_FORMAT_NONE; |
| 97 | |
| 98 | ctx.extracting_reasoning = extract_reasoning && reasoning.mode != reasoning_mode::NONE; |
| 99 | ctx.content = &content; |
| 100 | ctx.reasoning = &reasoning; |
| 101 | |
| 102 | // Build reasoning parser |
| 103 | ctx.reasoning_parser = reasoning.build_parser(ctx); |
| 104 | |
| 105 | auto parser = p.eps(); |
| 106 | |
| 107 | bool has_tools = inputs.tools.is_array() && !inputs.tools.empty(); |
| 108 | bool has_response_format = inputs.json_schema.is_object() && !inputs.json_schema.empty(); |
| 109 | bool pure_content = reasoning.mode == reasoning_mode::NONE; |
| 110 | |
| 111 | if (has_response_format) { |
| 112 | auto response_format = p.rule("response-format", p.content(p.schema(p.json(), "response-format-schema", inputs.json_schema))); |
| 113 | parser = ctx.reasoning_parser + p.space() + p.choice({ |
| 114 | p.literal("```json") + p.space() + response_format + p.space() + p.literal("```"), |
| 115 | response_format |
| 116 | }) + p.end(); |
| 117 | pure_content = false; |
| 118 | } else if (has_tools && inputs.tool_choice != COMMON_CHAT_TOOL_CHOICE_NONE && jinja_caps.supports_tool_calls) { |
| 119 | parser = tools.build_parser(ctx); |
| 120 | pure_content = false; |
| 121 | } else { |
| 122 | parser = content.build_parser(ctx); |
| 123 | } |
| 124 | return pure_content ? p.prefix(inputs.generation_prompt, reasoning.start) + parser : p.prefix(inputs.generation_prompt, reasoning.start) << parser; |
| 125 | }); |
| 126 | } |
| 127 | |
| 128 | common_peg_parser analyze_reasoning::build_parser(parser_build_context & ctx) const { |
| 129 | auto & p = ctx.p; |
no test coverage detected