Coverage for /home/admin/Documents/AI/applications/lexigram-dev/lexigram/experimental/ai/lexigram-ai-llm/src/lexigram/ai/llm/parsers/enum.py: 38%
34 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"""Enum Output Parser."""
3from __future__ import annotations
5from enum import Enum
6from typing import TYPE_CHECKING
8from lexigram.ai.llm.structured.exceptions import ParseError
9from lexigram.ai.llm.structured.parser import extract_json_block
10from lexigram.logging import (
11 get_logger,
12)
14if TYPE_CHECKING:
15 from typing import TypeVar
17 T = TypeVar("T", bound=Enum)
18else:
19 T = None
21logger = get_logger(__name__)
24class EnumOutputParser:
25 """Parse LLM responses into Enum members.
27 Extracts JSON from the response and maps it to an Enum member.
28 Supports both string values and integer values.
30 Example:
31 >>> from enum import Enum
32 >>>
33 >>> class Status(Enum):
34 ... ACTIVE = "active"
35 ... INACTIVE = "inactive"
36 >>>
37 >>> parser = EnumOutputParser(Status)
38 >>> result = parser.parse('"active"')
39 >>> assert result == Status.ACTIVE
40 """
42 def __init__(self, enum: type[Enum]) -> None:
43 """Initialize with an Enum class.
45 Args:
46 enum: Enum subclass to parse into.
47 """
48 self._enum = enum
50 def parse(self, text: str) -> Enum:
51 """Parse text into an Enum member.
53 Args:
54 text: Raw LLM response text that may contain JSON with enum value.
56 Returns:
57 Corresponding Enum member.
59 Raises:
60 ParseError: When JSON cannot be extracted or enum value is invalid.
61 """
62 try:
63 parsed = extract_json_block(text)
64 except ValueError as exc:
65 raise ParseError(str(exc)) from exc
67 if isinstance(parsed, str):
68 value = parsed
69 elif isinstance(parsed, int):
70 try:
71 return self._enum(parsed)
72 except ValueError:
73 raise ParseError(f"Invalid enum value: {parsed}")
74 else:
75 raise ParseError(
76 f"Expected string or int for enum, got {type(parsed).__name__}"
77 )
79 try:
80 return self._enum(value)
81 except ValueError:
82 valid_values = [e.value for e in self._enum]
83 raise ParseError(
84 f"Invalid enum value {value!r}. Valid values: {valid_values}"
85 )
87 def get_format_instructions(self) -> str:
88 """Return format instructions for the LLM.
90 Returns:
91 Format instruction string telling the model to output a valid
92 enum value.
93 """
94 valid_values = [e.value for e in self._enum]
95 values_str = ", ".join(repr(v) for v in valid_values)
96 return (
97 f"Your response should be one of: {values_str}. "
98 "Return just the value, not a JSON object. "
99 "Do not include any text before or after the value."
100 )
103__all__ = ["EnumOutputParser"]