mud_server.translation.profile_builder ====================================== .. py:module:: mud_server.translation.profile_builder .. autoapi-nested-parse:: Character profile builder for the OOC→IC translation layer. ``CharacterProfileBuilder`` is responsible for building the flat context dictionary that is injected into the system prompt template. It fetches axis scores from the database and resolves them to their human-readable labels. World scoping ------------- All DB lookups use *both* ``character_name`` and ``world_id``. This is non-negotiable: two characters in different worlds may share the same name, and a name-only lookup would silently return the wrong character. Any attempt to call this builder without a concrete ``world_id`` will raise a ``ValueError`` at construction time. Axis sourcing ------------- The builder calls ``database.get_character_by_name_in_world`` to resolve the character name to a ``character_id``, then calls ``database.get_character_axis_state(character_id)`` which returns both axis scores and their resolved threshold labels (e.g. score ``0.87`` on the ``demeanor`` axis → label ``"proud"``). Active axes filtering --------------------- Only axes listed in ``active_axes`` are included in the returned profile dict. If a character has no score for an active axis yet (e.g. the world just gained a new axis and old characters haven't been seeded), the builder defaults to ``label="unknown"`` and ``score=0.0`` rather than omitting the key, so the prompt template never contains an unfilled placeholder. Attributes ---------- .. autoapisummary:: mud_server.translation.profile_builder.logger Classes ------- .. autoapisummary:: mud_server.translation.profile_builder.CharacterProfileBuilder Module Contents --------------- .. py:data:: logger .. py:class:: CharacterProfileBuilder(world_id, active_axes) Builds a character profile dict suitable for system prompt rendering. .. attribute:: _world_id World that this builder is scoped to. .. attribute:: _active_axes Axis names to include in the profile. An empty list means "all axes present for this character". Initialise the builder. :param world_id: World the builder is scoped to. Required; raises ``ValueError`` if empty so that silent world-scope omissions are caught at construction rather than producing wrong DB queries. :param active_axes: Axis names to include in the profile. :raises ValueError: If ``world_id`` is empty or blank. .. py:method:: build(character_name) Build a profile dict for the given character in this world. The returned dict contains flat ``{axis_name}_label`` and ``{axis_name}_score`` keys for every axis in ``active_axes``, plus a ``character_name`` key. These map directly to the ``{{key}}`` placeholders in the world's ``ic_prompt.txt`` template. Returns ``None`` in three situations (all logged at WARNING): - The character is not found in this world. - The character has no axis state at all. - An unexpected DB error occurs. In all ``None`` cases the caller (``TranslationService``) treats the result as an unresolvable fallback condition and returns ``None`` from ``translate()``, causing the engine to use the original OOC message instead. :param character_name: Name of the character to build a profile for. :returns: Flat profile dict on success, ``None`` on failure.