Coverage for /home/admin/Documents/AI/applications/lexigram-dev/lexigram/experimental/ai/lexigram-ai-prompt/src/lexigram/ai/prompt/service/models.py: 94%
36 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"""Data models for PromptService — templates, requests, results, and provider enum."""
3from __future__ import annotations
5from dataclasses import dataclass, field
6import enum
7from typing import Any
9from lexigram.ai.prompt.rendering.engine import RenderFormat
12class LLMProvider(str, enum.Enum):
13 """Target LLM provider for provider-specific prompt escaping.
15 Use this enum to tag a :class:`PromptTemplate` with its intended provider
16 so that :class:`~lexigram.ai.prompt.service.service.PromptService` can
17 apply the correct escaping when rendering.
19 Values:
20 ANTHROPIC: Anthropic Claude API. Variable values are wrapped in
21 ``<parameter name="…">…</parameter>`` XML tags (scaffolded;
22 full escaping is future work — see the ``_escape_*``
23 methods in ``service.py``).
24 OPENAI: OpenAI GPT API. Curly braces inside variable values are
25 escaped to prevent accidental format-string interpretation.
26 AZURE: Azure OpenAI Service. Delegates to OPENAI escaping rules.
27 GENERIC: No escaping. Values are substituted verbatim.
28 """
30 ANTHROPIC = "anthropic"
31 OPENAI = "openai"
32 AZURE = "azure"
33 GENERIC = "generic"
36@dataclass(frozen=True)
37class PromptTemplate:
38 """A named, versioned prompt template with variable declarations.
40 This is the primary value object stored and served by
41 :class:`~lexigram.ai.prompt.service.service.PromptService`.
43 Attributes:
44 name: Template name used as lookup key.
45 version: Semver-style or arbitrary version string (e.g. ``"v1"``,
46 ``"1.0.0"``). The service treats ``"latest"`` as a special
47 sentinel that always resolves to the most recently loaded
48 version.
49 content: Raw template string. Placeholder syntax depends on
50 ``format``.
51 format: Render format for this template — a
52 :class:`~lexigram.ai.prompt.rendering.engine.RenderFormat`
53 value: ``f_string`` (``{variable}``), ``jinja2``
54 (``{{ variable }}``, loops/filters/conditionals), ``dollar``
55 (``$variable``), or ``simple`` (literal, no substitution).
56 provider: Target LLM provider for escaping. Defaults to GENERIC.
57 required_variables: Variable names that MUST be supplied at render
58 time. Missing required variables raise.
59 optional_defaults: Default values for optional variables. Keys that
60 appear here but not in *required_variables* are
61 optional.
62 description: Human-readable description of the template purpose.
63 metadata: Arbitrary app-defined metadata (tags, author, etc.).
64 """
66 name: str
67 version: str
68 content: str
69 format: RenderFormat = RenderFormat.F_STRING
70 provider: LLMProvider = LLMProvider.GENERIC
71 required_variables: tuple[str, ...] = field(default_factory=tuple)
72 optional_defaults: dict[str, Any] = field(default_factory=dict)
73 description: str = ""
74 metadata: dict[str, Any] = field(default_factory=dict)
76 def __post_init__(self) -> None:
77 # Normalise: required_variables must be a tuple (frozen dataclass).
78 if not isinstance(self.required_variables, tuple):
79 object.__setattr__(
80 self, "required_variables", tuple(self.required_variables)
81 )
84@dataclass(frozen=True)
85class PromptRenderRequest:
86 """Input to :meth:`~lexigram.ai.prompt.service.service.PromptService.render`.
88 Attributes:
89 name: Template name to look up.
90 variables: Variable name → value mapping for substitution.
91 version: Specific version to render. Defaults to ``"latest"``.
92 """
94 name: str
95 variables: dict[str, Any] = field(default_factory=dict)
96 version: str = "latest"
99@dataclass(frozen=True)
100class PromptRenderResult:
101 """Output from :meth:`~lexigram.ai.prompt.service.service.PromptService.render`.
103 Attributes:
104 name: Template name that was rendered.
105 version: Concrete version that was used (never ``"latest"``).
106 rendered: The fully substituted prompt string.
107 provider: Provider the escaping was applied for.
108 """
110 name: str
111 version: str
112 rendered: str
113 provider: LLMProvider
116__all__ = [
117 "LLMProvider",
118 "PromptRenderRequest",
119 "PromptRenderResult",
120 "PromptTemplate",
121]