"""Run, stream, and persist a conversation without an asynchronous entry point."""

from pathlib import Path
from tempfile import TemporaryDirectory

from zett_agent.agent import AgentRunConfig
from zett_agent.dispatcher import AgentEventDispatcher
from zett_agent.events import AgentEventType
from zett_agent.extensions.sqlite import SQLiteSessionExtension
from zett_agent.messages import (
    AssistantMessage,
    UserMessage,
)
from zett_agent.model import (
    ModelEvent,
    ModelResponse,
)
from zett_agent.sync import (
    SyncModelAdapter,
    create_agent_sync,
)


class Echo:
    """A synchronous model used only to make this example runnable offline."""

    def stream(self, request):
        users = [message for message in request.messages if isinstance(message, UserMessage)]
        answer = f"Turn {len(users)}: {users[-1].text}"
        yield ModelEvent.text(answer)
        yield ModelEvent.completed(ModelResponse(AssistantMessage(content=answer)))


class Console(AgentEventDispatcher):
    async def on_text_delta_event(self, event):
        print(event.delta)


def main() -> None:
    with TemporaryDirectory() as directory:
        history = SQLiteSessionExtension(Path(directory) / "sessions.sqlite3")
        try:
            with create_agent_sync(
                SyncModelAdapter(Echo()),
                config=AgentRunConfig("sync-example"),
                extensions=[history],
                event_dispatcher=Console(),
            ) as agent:
                assert agent.run("Hello").content == "Turn 1: Hello"
                with agent.stream("Remember this") as events:
                    for event in events:
                        if event.type is AgentEventType.RUN_COMPLETED:
                            assert event.message is not None
                            assert event.message.content == "Turn 2: Remember this"
            # Storage is asynchronous; a plain function reaches it through the sync view.
            with history.storage.sync() as database:
                records = database.list_raw_messages("sync-example")
                assert [record.message.role for record in records] == [
                    "system",
                    "user",
                    "assistant",
                    "system",
                    "user",
                    "assistant",
                ]
            print("Synchronous history persisted")
        finally:
            with history.storage.sync() as database:
                database.close()


if __name__ == "__main__":
    main()
