Skip to content

profile_routes

profile_routes

The user's name, so the assistant knows what to call them.

GET/PUT /v1/profile read and write a small block in the persona's USER.md, which :class:~locus.prompt.builder.SystemPromptBuilder adds to every system prompt under "User Profile". Anything else the user keeps in that file is left alone. The block is plain text, so the CLI and agents see the same name, and editing it by hand works too.

Functions

render_block

render_block(profile: Profile) -> str

The USER.md block for profile, or "" when it's empty.

Source code in src/locus/server/profile_routes.py
def render_block(profile: Profile) -> str:
    """The USER.md block for ``profile``, or "" when it's empty."""
    values = {key: _clean(getattr(profile, key)) for key, _ in _FIELDS}
    if not any(values.values()):
        return ""
    lines = [START]
    lines += [f"{label}: {values[key]}" for key, label in _FIELDS if values[key]]
    call_them = values["nickname"] or values["first_name"]
    if call_them:
        lines.append(
            f'Address the user as "{call_them}" when you greet them or speak to them '
            "directly, unless they ask you to use a different name."
        )
    lines.append(END)
    return "\n".join(lines) + "\n"

parse_block

parse_block(text: str) -> Profile

The profile stored in USER.md text (empty if there is none).

Source code in src/locus/server/profile_routes.py
def parse_block(text: str) -> Profile:
    """The profile stored in USER.md ``text`` (empty if there is none)."""
    match = _BLOCK_RE.search(text)
    if not match:
        return Profile()
    found = {}
    for key, label in _FIELDS:
        line = re.search(rf"^{label}: (.*)$", match.group(0), re.M)
        if line:
            found[key] = line.group(1).strip()
    return Profile(**found)

write_profile

write_profile(path: Path, profile: Profile) -> None

Replace (or add, or remove) the profile block in path.

Source code in src/locus/server/profile_routes.py
def write_profile(path: Path, profile: Profile) -> None:
    """Replace (or add, or remove) the profile block in ``path``."""
    existing = path.read_text(encoding="utf-8") if path.exists() else ""
    rest = _BLOCK_RE.sub("", existing).lstrip("\n")
    block = render_block(profile)
    if not block and not rest:
        if path.exists():
            path.unlink()
        return
    content = block + ("\n" + rest if block and rest else rest)
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(content, encoding="utf-8")

profile_path

profile_path(request: Request) -> Path

The USER.md the system prompt reads, honouring a named persona.

Source code in src/locus/server/profile_routes.py
def profile_path(request: Request) -> Path:
    """The USER.md the system prompt reads, honouring a named persona."""
    from locus.core.config import load_config
    from locus.prompt.builder import SystemPromptBuilder

    config = getattr(request.app.state, "config", None) or load_config()
    resolved = SystemPromptBuilder._resolve_persona(config.memory_files)
    if not resolved.user_path:
        # persona_name = "none" turns persona files off entirely.
        raise HTTPException(
            status_code=409,
            detail='Persona files are turned off (persona_name = "none"), '
            "so Locus can't use your name.",
        )
    return Path(resolved.user_path).expanduser()