refactor: SimpleTool -> LookTool

This commit is contained in:
Daniel Eder 2025-09-29 08:18:38 +02:00
parent f7bdf34329
commit ffcebeb801
3 changed files with 19 additions and 13 deletions

View file

@ -9,7 +9,7 @@ Python-based Telnet helper for connecting to MUD servers, handling login flows,
- Interactive console session that mirrors server output and lets you type commands directly. - Interactive console session that mirrors server output and lets you type commands directly.
- Optional always-on tool mode plus an on-demand `#execute <tool>` escape hatch for ad-hoc automations. - Optional always-on tool mode plus an on-demand `#execute <tool>` escape hatch for ad-hoc automations.
- Higher-level agents (`fixed`, `loop`, `intelligent`) that can string multiple tools together via `#agent <spec>`. - Higher-level agents (`fixed`, `loop`, `intelligent`) that can string multiple tools together via `#agent <spec>`.
- Built-in tools (`SimpleTool`, `ExploreTool`, `CommunicationTool`, `MovementTool`, `IntelligentCommunicationTool`) with a pluggable interface for custom behaviours. - Built-in tools (`LookTool`, `ExploreTool`, `CommunicationTool`, `MovementTool`, `IntelligentCommunicationTool`) with a pluggable interface for custom behaviours.
## Requirements ## Requirements
@ -64,7 +64,7 @@ Python-based Telnet helper for connecting to MUD servers, handling login flows,
#agent intelligent #agent intelligent
``` ```
Add guidance text after the type and optional modifiers separated by `|`, e.g. `#agent intelligent explore carefully|model=mistral/mistral-large-2407|delay=2`. The agent only calls built-in tools (`simple`, `move`, `movement`, `explore`, `communication`, `intelligentcommunication`) and refuses unknown names. Add guidance text after the type and optional modifiers separated by `|`, e.g. `#agent intelligent explore carefully|model=mistral/mistral-large-2407|delay=2`. The agent only calls built-in tools (`look`, `move`, `movement`, `explore`, `communication`, `intelligentcommunication`) and refuses unknown names.
## Environment Variables ## Environment Variables
@ -79,7 +79,7 @@ All variables can be placed in the `.env` file (one `KEY=value` per line) or pro
| `MISTLE_LOGIN_PROMPT` | ❌ | Prompt string that signals the client to send credentials (e.g., `"Name:"`). When omitted, the client just waits for the initial banner. | | `MISTLE_LOGIN_PROMPT` | ❌ | Prompt string that signals the client to send credentials (e.g., `"Name:"`). When omitted, the client just waits for the initial banner. |
| `MISTLE_EXIT_COMMAND` | ❌ | Command issued during graceful shutdown (after pressing `Ctrl-C`). Useful for `quit`/`save` macros. | | `MISTLE_EXIT_COMMAND` | ❌ | Command issued during graceful shutdown (after pressing `Ctrl-C`). Useful for `quit`/`save` macros. |
| `MISTLE_TOOL_MODE` | ❌ | Enable full-time tool thread when set to truthy values (`1`, `true`, `yes`, `on`). Defaults to interactive-only mode. | | `MISTLE_TOOL_MODE` | ❌ | Enable full-time tool thread when set to truthy values (`1`, `true`, `yes`, `on`). Defaults to interactive-only mode. |
| `MISTLE_TOOL` | ❌ | Select which tool class to instantiate when tool mode is active. Accepted values: `simple` (default), `explore`, `communication`, `movement`, `intelligent`/`intelligentcommunication` (LLM-backed), or custom spec `module:ClassName`. | | `MISTLE_TOOL` | ❌ | Select which tool class to instantiate when tool mode is active. Accepted values: `look` (default, alias `simple`), `explore`, `communication`, `movement`, `intelligent`/`intelligentcommunication` (LLM-backed), or custom spec `module:ClassName`. |
| `MISTLE_LLM_MODEL` | ❌ | Override the `litellm` model used by the intelligent tool (defaults to `mistral/mistral-small-2407`). | | `MISTLE_LLM_MODEL` | ❌ | Override the `litellm` model used by the intelligent tool (defaults to `mistral/mistral-small-2407`). |
| `MISTRAL_API_KEY` | ❌ | API key used by `IntelligentCommunicationTool` (via `litellm`) when calling the `mistral/mistral-small-2407` model. | | `MISTRAL_API_KEY` | ❌ | API key used by `IntelligentCommunicationTool` (via `litellm`) when calling the `mistral/mistral-small-2407` model. |
@ -98,7 +98,7 @@ All variables can be placed in the `.env` file (one `KEY=value` per line) or pro
## On-Demand Tools ## On-Demand Tools
- When `MISTLE_TOOL_MODE` is **off**, you can trigger an ephemeral tool at any time with `#execute <tool_spec>`. - When `MISTLE_TOOL_MODE` is **off**, you can trigger an ephemeral tool at any time with `#execute <tool_spec>`.
- The syntax accepts the same values as `MISTLE_TOOL` and reuses the `build_tool` helper, so `#execute simple`, `#execute explore`, `#execute move`, `#execute intelligent`, or `#execute mypackage.mymodule:CustomTool` are all valid. - The syntax accepts the same values as `MISTLE_TOOL` and reuses the `build_tool` helper, so `#execute look`, `#execute explore`, `#execute move`, `#execute intelligent`, or `#execute mypackage.mymodule:CustomTool` are all valid.
- On-demand runs share the current session, respect the one-command-per-second limit, and stop automatically after a few seconds of inactivity. - On-demand runs share the current session, respect the one-command-per-second limit, and stop automatically after a few seconds of inactivity.
## Danger Zone ## Danger Zone

12
app.py
View file

@ -7,14 +7,14 @@ from pathlib import Path
from threading import Event, Lock, Thread from threading import Event, Lock, Thread
from typing import Callable, Optional, Type from typing import Callable, Optional, Type
from tools import Tool, SimpleTool from tools import Tool, LookTool
from agents import Agent, build_agent from agents import Agent, build_agent
from agent_runtime import run_agent from agent_runtime import run_agent
TOOL_REGISTRY = { TOOL_REGISTRY = {
"simple": { "look": {
"module": "tools", "module": "tools",
"class": "SimpleTool", "class": "LookTool",
"kwargs": {}, "kwargs": {},
"description": "Sends the 'schau' look command to refresh the room description.", "description": "Sends the 'schau' look command to refresh the room description.",
}, },
@ -210,11 +210,11 @@ def build_tool(spec: str) -> Tool:
"""Instantiate a tool based on configuration.""" """Instantiate a tool based on configuration."""
normalized = spec.strip() normalized = spec.strip()
if not normalized: if not normalized:
return SimpleTool() return LookTool()
key = normalized.lower() key = normalized.lower()
if key == "simple": if key in {"simple", "look"}:
return SimpleTool() return LookTool()
if key in TOOL_REGISTRY: if key in TOOL_REGISTRY:
meta = TOOL_REGISTRY[key] meta = TOOL_REGISTRY[key]

View file

@ -21,18 +21,24 @@ class Tool(ABC):
@dataclass @dataclass
class SimpleTool(Tool): class LookTool(Tool):
"""Minimal tool that always returns the same command.""" """Tool that sends a look command to refresh the room description."""
default_command: str = "schau" default_command: str = "schau"
last_output: str = field(default="", init=False) last_output: str = field(default="", init=False)
needs_look: bool = field(default=True, init=False)
def observe(self, output: str) -> None: def observe(self, output: str) -> None:
if output: if output:
self.last_output = output self.last_output = output
# Once we received output, we consider the look complete.
self.needs_look = False
def decide(self) -> Optional[str]: def decide(self) -> Optional[str]:
if self.needs_look:
self.needs_look = False
return self.default_command return self.default_command
return None
@dataclass @dataclass