Selaa lähdekoodia

feat: 更正修复Jinja prompt template

kekezack 1 viikko sitten
vanhempi
sitoutus
12de988120
2 muutettua tiedostoa jossa 44 lisäystä ja 0 poistoa
  1. 30 0
      tests/test_lmstudio_wrapper_generator.py
  2. 14 0
      tools/lmstudio/wrapper_generator.py

+ 30 - 0
tests/test_lmstudio_wrapper_generator.py

@@ -591,6 +591,36 @@ class WrapperGeneratorTests(unittest.TestCase):
             profile_with_mmproj["capabilities"]["tools"],
         )
 
+<<<<<<< HEAD
+=======
+    def test_prompt_template_removes_lmstudio_unsupported_safe_filter(self):
+        metadata = {
+            "general.architecture": "qwen35moe",
+            "general.name": "Safe Filter Model",
+            "general.basename": "Safe Filter Model",
+            "tokenizer.chat_template": (
+                "{{ '<think>\\n'|safe }}"
+                "{{- message.content | safe }}"
+                "{{ tool_call.arguments|tojson|safe }}"
+            ),
+            "qwen2.context_length": "262144",
+        }
+
+        profile = gen.build_virtual_model_profile(metadata)
+        files = gen.build_virtual_model_files(
+            publisher="publisher-e",
+            slug="safe-filter-model",
+            model_key="publisher-e/Safe-Filter-Model-GGUF/model.gguf",
+            profile=profile,
+        )
+
+        self.assertNotIn("|safe", files["model.yaml"])
+        self.assertNotIn("| safe", files["model.yaml"])
+        self.assertIn("{{ '<think>\\n' }}", files["model.yaml"])
+        self.assertIn("{{- message.content }}", files["model.yaml"])
+        self.assertIn("{{ tool_call.arguments|tojson }}", files["model.yaml"])
+
+>>>>>>> cd0a3e8 (feat: 更正修复Jinja prompt template)
 
 if __name__ == "__main__":
     unittest.main()

+ 14 - 0
tools/lmstudio/wrapper_generator.py

@@ -267,6 +267,14 @@ def _detect_capabilities(chat_template: str) -> dict[str, bool]:
     }
 
 
+<<<<<<< HEAD
+=======
+def sanitize_chat_template_for_lmstudio(chat_template: str) -> str:
+    # LM Studio's Jinja renderer does not support MarkupSafe's no-op `safe` filter.
+    return re.sub(r"\s*\|\s*safe\b", "", chat_template)
+
+
+>>>>>>> cd0a3e8 (feat: 更正修复Jinja prompt template)
 def _architecture_defaults(architecture: str) -> dict[str, object]:
     if architecture == "qwen35moe":
         return {
@@ -357,7 +365,13 @@ def build_virtual_model_profile(
         or metadata.get("architecture")
         or ""
     ).strip()
+<<<<<<< HEAD
     chat_template = str(metadata.get("tokenizer.chat_template") or "")
+=======
+    chat_template = sanitize_chat_template_for_lmstudio(
+        str(metadata.get("tokenizer.chat_template") or "")
+    )
+>>>>>>> cd0a3e8 (feat: 更正修复Jinja prompt template)
     base_name = _extract_base_name(metadata)
     basename_slug = _slugify(base_name)
     metadata_capabilities = _detect_capabilities(chat_template)