simple, stupid exploration agent

This commit is contained in:
Daniel Eder 2025-09-27 08:12:41 +02:00
parent 5f3ea6a781
commit 4e106e174f
2 changed files with 41 additions and 8 deletions

2
.env
View file

@ -5,4 +5,4 @@ MISTLE_PASSWORD=sl-mudbot
MISTLE_LOGIN_PROMPT=Wie heisst Du denn ("neu" fuer neuen Spieler) ? MISTLE_LOGIN_PROMPT=Wie heisst Du denn ("neu" fuer neuen Spieler) ?
MISTLE_EXIT_COMMAND=schlaf ein MISTLE_EXIT_COMMAND=schlaf ein
MISTLE_AGENT_MODE=true MISTLE_AGENT_MODE=true
MISTLE_AGENT=simple MISTLE_AGENT=explore

View file

@ -1,8 +1,10 @@
from __future__ import annotations from __future__ import annotations
import re
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from collections import deque
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Optional from typing import Deque, Optional, Pattern, Set
class Agent(ABC): class Agent(ABC):
@ -19,7 +21,7 @@ class Agent(ABC):
@dataclass @dataclass
class SimpleAgent(Agent): class SimpleAgent(Agent):
"""Very small stateful agent that decides which command to run next.""" """Minimal agent that always returns the same command."""
default_command: str = "schau" default_command: str = "schau"
last_output: str = field(default="", init=False) last_output: str = field(default="", init=False)
@ -34,14 +36,45 @@ class SimpleAgent(Agent):
@dataclass @dataclass
class ExploreAgent(Agent): class ExploreAgent(Agent):
"""Very small stateful agent that decides which command to run next.""" """Agent that inspects every noun it discovers in the room description."""
default_command: str = "untersuche boden" look_command: str = "schau"
inspect_command: str = "untersuche"
nouns_pattern: Pattern[str] = field(
default_factory=lambda: re.compile(r"\b[A-ZÄÖÜ][A-Za-zÄÖÜäöüß-]*\b")
)
last_output: str = field(default="", init=False) last_output: str = field(default="", init=False)
look_sent: bool = field(default=False, init=False)
pending_targets: Deque[str] = field(default_factory=deque, init=False)
seen_targets: Set[str] = field(default_factory=set, init=False)
inspected_targets: Set[str] = field(default_factory=set, init=False)
def observe(self, output: str) -> None: def observe(self, output: str) -> None:
if output: if not output:
self.last_output = output return
self.last_output = output
if not self.look_sent:
return
for noun in self.nouns_pattern.findall(output):
target = noun.strip()
key = target.lower()
if not target or key in self.seen_targets:
continue
self.seen_targets.add(key)
self.pending_targets.append(target)
def decide(self) -> Optional[str]: def decide(self) -> Optional[str]:
return self.default_command if not self.look_sent:
self.look_sent = True
return self.look_command
if self.pending_targets:
target = self.pending_targets.popleft()
key = target.lower()
self.inspected_targets.add(key)
progress = f"Explored {len(self.inspected_targets)}/{len(self.seen_targets)}"
print(progress)
return f"{self.inspect_command} {target}"
return None