AgentnessBench / tests /agents /test_vanilla.py
irregular6612's picture
refactor: restructure proteus into game/web subpackages
426093b
Raw
History Blame Contribute Delete
5.04 kB
from proteus.providers import FakeProvider
from proteus.game.agents import VanillaAgent, ActResult
VALID = ["up", "down", "left", "right", "stay"]
def test_act_parses_action_and_captures_reasoning_from_think_tags():
provider = FakeProvider(
responses=["<think>predator is east, go up</think>ACTION: up"],
)
agent = VanillaAgent(provider)
result = agent.act("grid here", VALID, "rules")
assert isinstance(result, ActResult)
assert result.action == "up"
assert "predator is east" in result.reasoning
assert result.raw_text # full text retained
def test_act_falls_back_to_stay_when_unparseable():
provider = FakeProvider(responses=["I don't know what to do"])
agent = VanillaAgent(provider)
result = agent.act("grid", VALID, "rules")
assert result.action == "stay" # safe default when no valid action parsed
def test_probe_returns_text_and_sends_question():
provider = FakeProvider(responses=["the predator is east"])
agent = VanillaAgent(provider)
result = agent.probe("grid", "where is the predator?", "rules")
assert result.answer == "the predator is east"
# the probe question reached the provider
assert any("where is the predator?" in m["content"] for m in provider.calls[-1])
def test_name_is_vanilla():
assert VanillaAgent(FakeProvider(responses=["x"])).name == "vanilla"
def test_act_ignores_decoy_action_inside_think_block():
# A decoy "ACTION:" inside the think block must NOT win over the real
# post-thinking ACTION line. (Regression for extracting from full text.)
provider = FakeProvider(responses=["<think>maybe ACTION: up</think>ACTION: down"])
agent = VanillaAgent(provider)
result = agent.act("grid", VALID, "rules")
assert result.action == "down"
def test_act_uses_provider_native_thinking_when_no_inline_tags():
# Covers the middle branch of the reasoning fallback: no inline <think>,
# but the provider supplies a native thinking_text on CompletionResult.
from proteus.providers.base import CompletionResult, LLMProvider
class _NativeThink(LLMProvider):
@property
def model_name(self) -> str:
return "native"
def complete(self, messages, temperature=0.7, max_tokens=4096):
return CompletionResult(
text="ACTION: up", input_tokens=0, output_tokens=2,
thinking_text="native reasoning here",
)
result = VanillaAgent(_NativeThink()).act("grid", VALID, "rules")
assert result.action == "up"
assert result.reasoning == "native reasoning here"
def test_act_appends_action_directive_with_available_actions():
provider = FakeProvider(responses=["ACTION: up"])
agent = VanillaAgent(provider)
agent.act("grid here", VALID, "rules")
user_msg = provider.calls[-1][-1]["content"]
assert "grid here" in user_msg
assert "ACTION:" in user_msg
assert "up, down, left, right, stay" in user_msg # actions list formatted into directive
def test_act_captures_token_accounting_from_completion_result():
# Inline <think> count comes from the parser; output_tokens from the provider.
provider = FakeProvider(responses=["<think>go up now</think>ACTION: up"])
result = VanillaAgent(provider).act("grid", VALID, "rules")
assert result.thinking_tokens == 3 # "go up now" -> 3 words
assert result.output_tokens > 0
assert result.input_tokens == 0 # FakeProvider always reports 0; documents the fake's constant, not a propagation check
def test_act_prefers_provider_thinking_tokens_when_present():
# When the provider reports its own thinking_tokens (e.g. Ollama's structured
# message.thinking), use that over the inline-tag parser count.
from proteus.providers.base import CompletionResult, LLMProvider
class _NativeTokens(LLMProvider):
@property
def model_name(self): return "native"
def complete(self, messages, temperature=0.7, max_tokens=4096):
return CompletionResult(
text="ACTION: up", input_tokens=11, output_tokens=7,
thinking_tokens=42, thinking_text="native reasoning",
)
result = VanillaAgent(_NativeTokens()).act("grid", VALID, "rules")
assert result.thinking_tokens == 42
assert result.input_tokens == 11
assert result.output_tokens == 7
def test_probe_returns_probe_result_with_reasoning_and_tokens():
from proteus.game.agents import ProbeResult
provider = FakeProvider(responses=["<think>predator is two cells east</think>go up"])
result = VanillaAgent(provider).probe("grid", "where is the predator?", "rules")
assert isinstance(result, ProbeResult)
assert result.answer == "go up" # think-stripped answer
assert "predator is two cells east" in result.reasoning
assert result.raw_text == "<think>predator is two cells east</think>go up"
assert result.thinking_tokens == 5 # 5-word think block (parser fallback)
assert result.output_tokens > 0