aboutsummaryrefslogtreecommitdiff
path: root/agent/orchestrator/loop.py
blob: 07e81e87178937530a3b6108384c675d12af53ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
"""Per-turn orchestration.

A turn is: gather dynamic context, hand the conversation to the backend, return
the response. As capabilities grow (memory recall, routing per intent, channel
adapters) they hang off this function.
"""

from .context import build_turn_context
from .models import Message, ModelRequest, call_model


def handle_turn(messages: list[Message], user: str | None = None) -> str:
    decorated = _decorate_latest_user(messages, user)
    request = ModelRequest(
        messages=messages,
        turn_context=build_turn_context(),
    )
    response = call_model(request)
    return response.content

def _decorate_latest_user(messages: list[Message], user: str | None) -> list[Message]:
    """Prepend [timestamp] [user: name] to the latest user message only.

    Older user messages keep their original form, they were already decorated
    at the time they were sent, and Open WebUI is feeding us back the conversation
    history including those decorations.
    """
    if not messages:
        return messages
    # find the latest user message; decorate it
    decorated = list(messages)
    for i in range(len(decorated) - 1, -1, -1):
        if decorated[i].role == "user":
            now = datetime.now(timezone.utc).astimezone().isoformat(timespec="seconds")
            name = f"[user: {user}] " if user else ""
            prefix = f"[{now}] {name}"
            decorated[i] = Message(
                role="user",
                content=prefix + decorated[i].content,
            )
            break
    return decorated