From ffcebeb801b0ef8014580987eabc9d81ee154eec Mon Sep 17 00:00:00 2001 From: Daniel Eder Date: Mon, 29 Sep 2025 08:18:38 +0200 Subject: [PATCH] refactor: SimpleTool -> LookTool --- README.md | 8 ++++---- app.py | 12 ++++++------ tools.py | 12 +++++++++--- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index e449c3f..9215e47 100644 --- a/README.md +++ b/README.md @@ -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. - Optional always-on tool mode plus an on-demand `#execute ` escape hatch for ad-hoc automations. - Higher-level agents (`fixed`, `loop`, `intelligent`) that can string multiple tools together via `#agent `. -- 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 @@ -64,7 +64,7 @@ Python-based Telnet helper for connecting to MUD servers, handling login flows, #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 @@ -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_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` | ❌ | 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`). | | `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 - When `MISTLE_TOOL_MODE` is **off**, you can trigger an ephemeral tool at any time with `#execute `. -- 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. ## Danger Zone diff --git a/app.py b/app.py index b1f2b7d..7980265 100644 --- a/app.py +++ b/app.py @@ -7,14 +7,14 @@ from pathlib import Path from threading import Event, Lock, Thread from typing import Callable, Optional, Type -from tools import Tool, SimpleTool +from tools import Tool, LookTool from agents import Agent, build_agent from agent_runtime import run_agent TOOL_REGISTRY = { - "simple": { + "look": { "module": "tools", - "class": "SimpleTool", + "class": "LookTool", "kwargs": {}, "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.""" normalized = spec.strip() if not normalized: - return SimpleTool() + return LookTool() key = normalized.lower() - if key == "simple": - return SimpleTool() + if key in {"simple", "look"}: + return LookTool() if key in TOOL_REGISTRY: meta = TOOL_REGISTRY[key] diff --git a/tools.py b/tools.py index c0f0b09..5799cb8 100644 --- a/tools.py +++ b/tools.py @@ -21,18 +21,24 @@ class Tool(ABC): @dataclass -class SimpleTool(Tool): - """Minimal tool that always returns the same command.""" +class LookTool(Tool): + """Tool that sends a look command to refresh the room description.""" default_command: str = "schau" last_output: str = field(default="", init=False) + needs_look: bool = field(default=True, init=False) def observe(self, output: str) -> None: if output: self.last_output = output + # Once we received output, we consider the look complete. + self.needs_look = False def decide(self) -> Optional[str]: - return self.default_command + if self.needs_look: + self.needs_look = False + return self.default_command + return None @dataclass