Coverage for /home/admin/Documents/AI/applications/lexigram-dev/lexigram/experimental/ai/lexigram-ai-guard/src/lexigram/ai/guard/output/length.py: 56%
18 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"""Output length guard.
3Rejects LLM responses that exceed a configured maximum length.
4Used to prevent runaway generation and enforce SLA constraints.
5"""
7from __future__ import annotations
9from typing import TYPE_CHECKING, Any
11from lexigram.ai.guard.output.base import AbstractOutputGuard
12from lexigram.ai.guard.pipeline.result import GuardCheckResult
13from lexigram.contracts.ai.guards import GuardResultProtocol
14from lexigram.result import Ok, Result
16if TYPE_CHECKING:
17 from lexigram.contracts.ai.exceptions import GuardError
20class OutputLengthGuard(AbstractOutputGuard):
21 """GuardProtocol that enforces a maximum LLM response length.
23 Args:
24 max_chars: Maximum allowed character count in the response.
25 action: Action when the limit is exceeded — ``"block"`` (default)
26 or ``"warn"``.
28 Example::
30 guard = OutputLengthGuard(max_chars=50000, action="warn")
31 result = await guard.check(llm_response)
32 """
34 def __init__(self, max_chars: int, action: str = "block") -> None:
35 """Initialise the output length guard.
37 Args:
38 max_chars: Maximum allowed character count.
39 action: ``"block"`` or ``"warn"``.
40 """
41 super().__init__(action=action)
42 self._max_chars = max_chars
44 async def check(
45 self,
46 content: str,
47 *,
48 original_input: str | None = None,
49 metadata: dict[str, Any] | None = None,
50 ) -> Result[GuardResultProtocol, GuardError]:
51 """Check whether the response exceeds the configured length.
53 Args:
54 content: LLM response text to measure.
55 original_input: Unused — present for protocol compatibility.
56 metadata: Optional metadata.
58 Returns:
59 PASS if within limit; BLOCK or WARN if exceeded.
60 """
61 length = len(content)
62 if length <= self._max_chars:
63 return Ok(GuardCheckResult.allow(self.name, char_count=length))
65 if self._action == "warn":
66 return Ok(
67 GuardCheckResult.warn(
68 self.name,
69 reason=f"Response length {length} chars exceeds soft limit {self._max_chars}",
70 char_count=length,
71 max_chars=self._max_chars,
72 )
73 )
75 return Ok(
76 GuardCheckResult.block(
77 self.name,
78 reason=f"Response length {length} chars exceeds maximum {self._max_chars}",
79 char_count=length,
80 max_chars=self._max_chars,
81 )
82 )
85__all__ = ["OutputLengthGuard"]