Coverage for /home/admin/Documents/AI/applications/lexigram-dev/lexigram/experimental/ai/lexigram-ai-llm/src/lexigram/ai/llm/parsers/pydantic.py: 46%
24 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 07:19 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 07:19 +0800
1"""Pydantic Output Parser."""
3from __future__ import annotations
5from typing import TYPE_CHECKING, cast
7from lexigram.ai.llm.structured.exceptions import ParseError, SchemaValidationError
8from lexigram.ai.llm.structured.parser import (
9 extract_json_block,
10 validate_against_model,
11)
12from lexigram.logging import (
13 get_logger,
14)
16if TYPE_CHECKING:
17 from pydantic import BaseModel
19logger = get_logger(__name__)
22class PydanticOutputParser:
23 """Parse LLM responses into Pydantic models.
25 Uses the existing structured parser's validation logic to parse
26 and validate against a Pydantic model.
28 Example:
29 >>> from pydantic import BaseModel
30 >>>
31 >>> class User(BaseModel):
32 ... name: str
33 ... age: int
34 >>>
35 >>> parser = PydanticOutputParser(User)
36 >>> result = parser.parse('{"name": "John", "age": 30}')
37 >>> assert result.name == "John"
38 """
40 def __init__(self, model: type[BaseModel]) -> None:
41 """Initialize with a Pydantic model class.
43 Args:
44 model: Pydantic BaseModel subclass to parse into.
45 """
46 self._model = model
48 def parse(self, text: str) -> BaseModel:
49 """Parse text into a Pydantic model instance.
51 Args:
52 text: Raw LLM response text that may contain JSON.
54 Returns:
55 Validated Pydantic model instance.
57 Raises:
58 ParseError: When JSON cannot be extracted.
59 SchemaValidationError: When validation fails.
60 """
61 try:
62 parsed = extract_json_block(text)
63 except ValueError as exc:
64 raise ParseError(str(exc)) from exc
66 try:
67 return cast("BaseModel", validate_against_model(parsed, self._model))
68 except (TypeError, ValueError) as exc:
69 raise SchemaValidationError(str(exc)) from exc
71 def get_format_instructions(self) -> str:
72 """Return format instructions for the LLM.
74 Returns:
75 Format instruction string telling the model to output valid JSON
76 that matches the Pydantic model schema.
77 """
78 from lexigram.serialization import dumps_str
80 schema = (
81 self._model.model_json_schema()
82 if hasattr(self._model, "model_json_schema")
83 else {"type": "object"}
84 )
85 schema_str = dumps_str(schema, indent=2)
86 return (
87 f"Your response should be a valid JSON object matching this schema:\n\n"
88 f"{schema_str}\n\n"
89 "Do not include any text before or after the JSON. "
90 "Do not use markdown code fences."
91 )
94__all__ = ["PydanticOutputParser"]