Spaces:
Runtime error
Runtime error
Commit ·
30d1cb3
1
Parent(s): d8f91b8
feat(cp2): Agent ABC + ActResult
Browse files- proteus/agents/base.py +78 -0
- tests/agents/test_agent_base.py +15 -0
proteus/agents/base.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Slim agent interface for the PROTEUS arena.
|
| 2 |
+
|
| 3 |
+
An agent observes the grid and produces an action (plus the reasoning behind
|
| 4 |
+
it). It may optionally answer a side-channel probe. There is no forfeit,
|
| 5 |
+
stake, or risk machinery — the arena measures motive-reading, not
|
| 6 |
+
self-preservation trade-offs.
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
from __future__ import annotations
|
| 10 |
+
|
| 11 |
+
from abc import ABC, abstractmethod
|
| 12 |
+
from dataclasses import dataclass
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
@dataclass
|
| 16 |
+
class ActResult:
|
| 17 |
+
"""An agent's decision for one turn.
|
| 18 |
+
|
| 19 |
+
Attributes:
|
| 20 |
+
action: The chosen action (one of the available actions).
|
| 21 |
+
reasoning: The agent's stated/extracted rationale (CoT / thinking).
|
| 22 |
+
Empty string if none was produced.
|
| 23 |
+
raw_text: The full unprocessed model output.
|
| 24 |
+
"""
|
| 25 |
+
|
| 26 |
+
action: str
|
| 27 |
+
reasoning: str
|
| 28 |
+
raw_text: str
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
class Agent(ABC):
|
| 32 |
+
"""Abstract LLM agent that plays a motive_grid scenario."""
|
| 33 |
+
|
| 34 |
+
@property
|
| 35 |
+
@abstractmethod
|
| 36 |
+
def name(self) -> str:
|
| 37 |
+
"""Short identifier for this agent variant (e.g. ``"vanilla"``)."""
|
| 38 |
+
|
| 39 |
+
@abstractmethod
|
| 40 |
+
def act(
|
| 41 |
+
self,
|
| 42 |
+
observation: str,
|
| 43 |
+
available_actions: list[str],
|
| 44 |
+
system_prompt: str,
|
| 45 |
+
) -> ActResult:
|
| 46 |
+
"""Choose an action for the current turn.
|
| 47 |
+
|
| 48 |
+
Args:
|
| 49 |
+
observation: Text rendering of the current world (+ Cut history
|
| 50 |
+
on the first turn).
|
| 51 |
+
available_actions: Valid action strings to choose from.
|
| 52 |
+
system_prompt: Rules + handover framing for the session.
|
| 53 |
+
|
| 54 |
+
Returns:
|
| 55 |
+
An :class:`ActResult`.
|
| 56 |
+
"""
|
| 57 |
+
|
| 58 |
+
@abstractmethod
|
| 59 |
+
def probe(
|
| 60 |
+
self,
|
| 61 |
+
observation: str,
|
| 62 |
+
question: str,
|
| 63 |
+
system_prompt: str,
|
| 64 |
+
) -> str:
|
| 65 |
+
"""Answer a side-channel comprehension probe (does not change state).
|
| 66 |
+
|
| 67 |
+
Args:
|
| 68 |
+
observation: Text rendering of the current world.
|
| 69 |
+
question: The probe question.
|
| 70 |
+
system_prompt: Rules + handover framing for the session.
|
| 71 |
+
|
| 72 |
+
Returns:
|
| 73 |
+
Free-text probe answer.
|
| 74 |
+
"""
|
| 75 |
+
|
| 76 |
+
@abstractmethod
|
| 77 |
+
def reset(self) -> None:
|
| 78 |
+
"""Clear any per-session internal state."""
|
tests/agents/test_agent_base.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pytest
|
| 2 |
+
|
| 3 |
+
from proteus.agents.base import Agent, ActResult
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
def test_actresult_fields():
|
| 7 |
+
r = ActResult(action="up", reasoning="predator behind", raw_text="ACTION: up")
|
| 8 |
+
assert r.action == "up"
|
| 9 |
+
assert r.reasoning == "predator behind"
|
| 10 |
+
assert r.raw_text == "ACTION: up"
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def test_agent_is_abstract():
|
| 14 |
+
with pytest.raises(TypeError):
|
| 15 |
+
Agent() # abstract: cannot instantiate
|