feat: agent with loop strategy
This commit is contained in:
parent
905e3c91ab
commit
a2b7feec16
2 changed files with 45 additions and 2 deletions
10
README.md
10
README.md
|
|
@ -8,7 +8,7 @@ Python-based Telnet helper for connecting to MUD servers, handling login flows,
|
|||
- Loads credentials and connection settings from a local `.env` file.
|
||||
- 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.
|
||||
- Higher-level agents (`FixedStrategyAgent` so far) that can string multiple tools together via `#agent <spec>`.
|
||||
- Higher-level agents (`fixed`, `loop`) that can string multiple tools together via `#agent <spec>`.
|
||||
- Built-in tools (`SimpleTool`, `ExploreTool`, `CommunicationTool`, `MovementTool`, `IntelligentCommunicationTool`) with a pluggable interface for custom behaviours.
|
||||
|
||||
## Requirements
|
||||
|
|
@ -50,6 +50,14 @@ Python-based Telnet helper for connecting to MUD servers, handling login flows,
|
|||
|
||||
This example uses the fixed strategy agent to run `move` and then `explore` once. The first token after `#agent` selects the agent type (`fixed` today, more to come), and any remaining text is passed as that agent's configuration.
|
||||
|
||||
7. To run a looping agent that repeats tools, use:
|
||||
|
||||
```text
|
||||
#agent loop move,explore
|
||||
```
|
||||
|
||||
Append `:delay` to pause between iterations, e.g. `#agent loop move,explore:2.5`.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
All variables can be placed in the `.env` file (one `KEY=value` per line) or provided through the shell environment.
|
||||
|
|
|
|||
37
agents.py
37
agents.py
|
|
@ -2,9 +2,10 @@ from __future__ import annotations
|
|||
|
||||
import sys
|
||||
from abc import ABC, abstractmethod
|
||||
import itertools
|
||||
from dataclasses import dataclass
|
||||
from threading import Event
|
||||
from typing import Callable, Iterable
|
||||
from typing import Callable
|
||||
|
||||
|
||||
ToolInvoker = Callable[[str], bool]
|
||||
|
|
@ -39,6 +40,30 @@ class FixedStrategyAgent(Agent):
|
|||
break
|
||||
|
||||
|
||||
@dataclass
|
||||
class LoopAgent(Agent):
|
||||
"""Continuously execute a fixed strategy until stopped."""
|
||||
|
||||
plan: str
|
||||
delay: float = 0.0
|
||||
|
||||
def run(self, *, invoke_tool: ToolInvoker, stop_event: Event) -> None:
|
||||
steps = [part.strip() for part in self.plan.split(",") if part.strip()]
|
||||
if not steps:
|
||||
print("[Agent] No tools configured for loop strategy", file=sys.stderr)
|
||||
return
|
||||
|
||||
for step in itertools.cycle(steps):
|
||||
if stop_event.is_set():
|
||||
break
|
||||
success = invoke_tool(step)
|
||||
if not success:
|
||||
break
|
||||
if self.delay > 0:
|
||||
if stop_event.wait(self.delay):
|
||||
break
|
||||
|
||||
|
||||
def build_agent(spec: str) -> Agent:
|
||||
normalized = spec.strip()
|
||||
if not normalized:
|
||||
|
|
@ -50,5 +75,15 @@ def build_agent(spec: str) -> Agent:
|
|||
|
||||
if kind in {"fixed", "strategy", "fixedstrategy"}:
|
||||
return FixedStrategyAgent(config)
|
||||
if kind in {"loop", "cycle"}:
|
||||
delay = 0.0
|
||||
if ":" in config:
|
||||
plan, delay_str = config.split(":", 1)
|
||||
config = plan.strip()
|
||||
try:
|
||||
delay = float(delay_str.strip())
|
||||
except ValueError:
|
||||
print(f"[Agent] Invalid delay '{delay_str}', defaulting to 0")
|
||||
return LoopAgent(config, delay=delay)
|
||||
|
||||
raise RuntimeError(f"Unknown agent type '{kind}'")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue