Ctrl K
ComunidadGuías…

test/agent/test_sysprompt.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Copyright (c) 2026, AG2ai, Inc., AG2ai open-source projects maintainers and core contributors
#
# SPDX-License-Identifier: Apache-2.0

from collections.abc import Sequence
from typing import Any
from unittest.mock import MagicMock

import pytest

from ag2 import Agent, Context, MemoryStream
from ag2.config import LLMClient
from ag2.events import BaseEvent, ModelMessage, ModelResponse


class CustomEvent(BaseEvent):
    pass


class MockClient(LLMClient):
    def __init__(self, mock: MagicMock) -> None:
        self.mock = mock

    def create(self) -> "MockClient":
        return self

    async def __call__(
        self,
        messages: Sequence[BaseEvent],
        ctx: Context,
        **kwargs: Any,
    ) -> ModelResponse:
        await ctx.send(CustomEvent())
        self.mock(ctx.prompt)
        return ModelResponse(ModelMessage("Hi, user!"))


@pytest.mark.asyncio()
async def test_sysprompt(mock: MagicMock):
    agent = Agent(
        "test",
        prompt="You are a helpful agent!",
        config=MockClient(mock),
    )

    conversation = await agent.ask("Hi, agent!")

    mock.assert_called_once_with(["You are a helpful agent!"])
    assert conversation.context.prompt == ["You are a helpful agent!"]


@pytest.mark.asyncio()
async def test_multiple_sysprompts(mock: MagicMock):
    agent = Agent(
        "test",
        prompt=["1", "2"],
        config=MockClient(mock),
    )

    conversation = await agent.ask("Hi, agent!")

    mock.assert_called_once_with(["1", "2"])
    assert conversation.context.prompt == ["1", "2"]


@pytest.mark.asyncio()
async def test_sysprompt_reuse(mock: MagicMock):
    agent = Agent(
        "test",
        prompt="You are a helpful agent!",
        config=MockClient(mock),
    )

    conversation = await agent.ask("Hi, agent!")
    await conversation.ask("Next turn")

    mock.assert_called_with(["You are a helpful agent!"])
    assert mock.call_count == 2


@pytest.mark.asyncio()
async def test_sysprompt_override_with_call(mock: MagicMock):
    agent = Agent(
        "test",
        prompt="You are a helpful agent!",
        config=MockClient(mock),
    )

    await agent.ask("Hi, agent!", prompt=["1"])
    mock.assert_called_once_with(["1"])


@pytest.mark.asyncio()
async def test_callable_sysprompt(mock: MagicMock):
    async def sysprompt() -> str:
        return "1"

    agent = Agent(
        "test",
        prompt=sysprompt,
        config=MockClient(mock),
    )

    await agent.ask("Hi, agent!")
    mock.assert_called_once_with(["1"])


@pytest.mark.asyncio()
async def test_callable_sysprompt_called_once(mock: MagicMock):
    async def sysprompt(event: BaseEvent, ctx: Context) -> str:
        mock.prompt()
        return "1"

    agent = Agent(
        "test",
        prompt=sysprompt,
        config=MockClient(mock),
    )

    conversation = await agent.ask("Hi, agent!")
    await conversation.ask("Next turn")

    mock.prompt.assert_called_once()


@pytest.mark.asyncio()
async def test_decorator_sysprompt(mock: MagicMock):
    agent = Agent("test", config=MockClient(mock))

    @agent.prompt
    async def sysprompt(event: BaseEvent, ctx: Context) -> str:
        return "1"

    await agent.ask("Hi, agent!")
    mock.assert_called_once_with(["1"])


@pytest.mark.asyncio()
async def test_callable_sysprompt_decorator(mock: MagicMock):
    agent = Agent("test", config=MockClient(mock))

    @agent.prompt()
    def sysprompt(ctx: Context) -> str:
        return "1"

    await agent.ask("Hi, agent!")
    mock.assert_called_once_with(["1"])


@pytest.mark.asyncio()
async def test_mixed_sysprompts(mock: MagicMock):
    async def sysprompt(event: BaseEvent, ctx: Context) -> str:
        assert ctx.prompt == ["1"]
        return "2"

    agent = Agent(
        "test",
        prompt=["1", sysprompt],
        config=MockClient(mock),
    )

    await agent.ask("Hi, agent!")

    mock.assert_called_once_with(["1", "2"])


@pytest.mark.asyncio()
async def test_prompt_mutation(mock: MagicMock):
    agent = Agent(
        "test",
        prompt="1",
        config=MockClient(mock),
    )

    # test first call
    conversation = await agent.ask("Hi, agent!")
    mock.assert_called_once_with(["1"])

    # test second call
    conversation.context.prompt = ["2"]
    await conversation.ask("Next turn")

    # validate latest call
    mock.assert_called_with(["2"])

    # validate all calls
    assert [c[0][0] for c in mock.call_args_list] == [
        ["1"],
        ["2"],
    ]


@pytest.mark.asyncio()
async def test_prompt_mutation_from_subscriber(mock: MagicMock):
    agent = Agent(
        "test",
        prompt="1",
        config=MockClient(mock),
    )

    stream = MemoryStream()

    @stream.where(CustomEvent).subscribe()
    async def mutate_prompt(event: CustomEvent, ctx: Context) -> None:
        assert ctx.prompt == ["1"]
        ctx.prompt = ["2"]

    await agent.ask("Hi, agent!", stream=stream)
    mock.assert_called_once_with(["2"])