| |
| |
| |
| |
| @@ -677,6 +677,13 @@ private: |
| optional_props.push_back("*"); |
| } |
| |
| + if (required_props.empty() && optional_props.empty()) { |
| + // No properties and no additionalProperties: avoid falling through to two |
| + // adjacent `space` tokens with nothing between them, which is invalid GBNF |
| + // (e.g. a no-arg tool schema like {"type":"object","properties":{}}). |
| + return "\"{\" space \"}\""; |
| + } |
| + |
| std::string rule = "\"{\" space "; |
| for (size_t i = 0; i < required_props.size(); i++) { |
| if (i > 0) { |
| @@ -972,6 +979,14 @@ public: |
| std::string char_rule = _add_primitive("char", PRIMITIVE_RULES.at("char")); |
| int min_len = schema.contains("minLength") ? schema["minLength"].get<int>() : 0; |
| int max_len = schema.contains("maxLength") ? schema["maxLength"].get<int>() : std::numeric_limits<int>::max(); |
| + // Clamp to the grammar engine's own repetition cap (MAX_REPETITION_THRESHOLD in |
| + // src/llama-grammar.cpp, currently 2000) so a large-but-valid maxLength doesn't |
| + // blow up grammar init. A bound this large isn't meaningfully enforceable via a |
| + // literal GBNF repetition anyway, so treat "too large to represent" as unbounded. |
| + constexpr int GRAMMAR_MAX_REPETITION_THRESHOLD = 2000; |
| + if (max_len > GRAMMAR_MAX_REPETITION_THRESHOLD) { |
| + max_len = std::numeric_limits<int>::max(); |
| + } |
| return _add_rule(rule_name, "\"\\\"\" " + build_repetition(char_rule, min_len, max_len) + " \"\\\"\""); |
| } |
| if (schema_type == "integer" && (schema.contains("minimum") || schema.contains("exclusiveMinimum") || schema.contains("maximum") || schema.contains("exclusiveMaximum"))) { |
|
|