39 lines
1.2 KiB
Python
39 lines
1.2 KiB
Python
"""System prompt assembly from a list of source files.
|
|
|
|
:func:`assemble` concatenates an agent's granules in order. A source is a
|
|
path, or a ``(tag, path)`` pair whose content is wrapped in ``<tag>...</tag>``.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import logging
|
|
from pathlib import Path
|
|
from typing import TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from collections.abc import Iterable
|
|
|
|
__all__ = ["PromptSource", "assemble"]
|
|
|
|
_log = logging.getLogger("beaver_gateway.agents.prompts")
|
|
|
|
PromptSource = str | Path | tuple[str, str | Path]
|
|
|
|
|
|
def assemble(sources: Iterable[PromptSource]) -> str:
|
|
"""Concatenate ``sources`` in order into one system prompt."""
|
|
parts: list[str] = []
|
|
for source in sources:
|
|
tag, raw = source if isinstance(source, tuple) else (None, source)
|
|
path = Path(raw)
|
|
text = path.read_text(encoding="utf-8").strip()
|
|
digest = hashlib.sha256(text.encode("utf-8")).hexdigest()[:12]
|
|
_log.info(
|
|
"prompt granule %s tag=%s sha=%s bytes=%d", path, tag, digest, len(text)
|
|
)
|
|
if not text:
|
|
continue
|
|
parts.append(f"<{tag}>\n{text}\n</{tag}>" if tag else text)
|
|
return "\n\n".join(parts) + "\n"
|