moo-agent 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. moo/agent/README.md +184 -0
  2. moo/agent/__init__.py +0 -0
  3. moo/agent/brain/__init__.py +928 -0
  4. moo/agent/brain/chain.py +228 -0
  5. moo/agent/brain/directives.py +192 -0
  6. moo/agent/brain/plans.py +151 -0
  7. moo/agent/brain/prompt.py +164 -0
  8. moo/agent/brain/state.py +51 -0
  9. moo/agent/cli.py +273 -0
  10. moo/agent/config.py +115 -0
  11. moo/agent/connection.py +238 -0
  12. moo/agent/llm_client.py +174 -0
  13. moo/agent/session_log.py +85 -0
  14. moo/agent/soul.py +315 -0
  15. moo/agent/templates/SOUL.md +25 -0
  16. moo/agent/templates/SOUL.patch.md +0 -0
  17. moo/agent/templates/__init__.py +0 -0
  18. moo/agent/templates/settings.toml +21 -0
  19. moo/agent/tests/__init__.py +0 -0
  20. moo/agent/tests/test_brain.py +1197 -0
  21. moo/agent/tests/test_brain_chain.py +301 -0
  22. moo/agent/tests/test_brain_directives.py +211 -0
  23. moo/agent/tests/test_brain_plans.py +231 -0
  24. moo/agent/tests/test_brain_prompt.py +221 -0
  25. moo/agent/tests/test_brain_state.py +72 -0
  26. moo/agent/tests/test_brain_state_lint.py +50 -0
  27. moo/agent/tests/test_cli.py +101 -0
  28. moo/agent/tests/test_config.py +153 -0
  29. moo/agent/tests/test_connection.py +173 -0
  30. moo/agent/tests/test_llm_client.py +284 -0
  31. moo/agent/tests/test_session_log.py +226 -0
  32. moo/agent/tests/test_soul.py +490 -0
  33. moo/agent/tests/test_tools.py +339 -0
  34. moo/agent/tests/test_tui.py +120 -0
  35. moo/agent/tools.py +778 -0
  36. moo/agent/tui.py +281 -0
  37. moo_agent-1.0.0.dist-info/METADATA +53 -0
  38. moo_agent-1.0.0.dist-info/RECORD +40 -0
  39. moo_agent-1.0.0.dist-info/WHEEL +4 -0
  40. moo_agent-1.0.0.dist-info/entry_points.txt +2 -0
moo/agent/README.md ADDED
@@ -0,0 +1,184 @@
1
+ # moo-agent
2
+
3
+ An autonomous, persona-driven agent that lives inside a DjangoMOO world as a
4
+ persistent player. It connects over SSH, perceives the game world as a stream of
5
+ text, applies reflexive rules for immediate reactions, and calls an LLM for
6
+ higher-level reasoning — all while presenting a real-time TUI where a human
7
+ observer can watch and intervene.
8
+
9
+ ## Prerequisites
10
+
11
+ - Python 3.11
12
+ - A running DjangoMOO server (port 8022 by default)
13
+ - `ANTHROPIC_API_KEY` environment variable set to a valid Anthropic API key
14
+
15
+ ## Install
16
+
17
+ ```
18
+ uv sync
19
+ moo-agent --help
20
+ ```
21
+
22
+ ## Quickstart
23
+
24
+ 1. Create a config directory:
25
+
26
+ ```
27
+ moo-agent init --output-dir ./my-agent --name Jeeves
28
+ ```
29
+
30
+ 2. Edit `./my-agent/SOUL.md` — define the agent's mission and persona.
31
+
32
+ 3. Run:
33
+
34
+ ```
35
+ export ANTHROPIC_API_KEY=sk-ant-...
36
+ moo-agent run ./my-agent
37
+ ```
38
+
39
+ The input prompt shows the agent's current status: `interact>` (green, idle),
40
+ `wait>` (red, LLM call in flight or wakeup timer imminent), `working>` (yellow,
41
+ processing an event).
42
+
43
+ Press `Escape` to enter scroll mode and use arrow keys / `PgUp`/`PgDn` to review
44
+ history. Press `Escape` again to resume autoscroll.
45
+
46
+ Press `Ctrl-C`, `Ctrl-D`, or `Ctrl-Q` to exit. The agent sends `@quit` before
47
+ disconnecting.
48
+
49
+ ---
50
+
51
+ ## SOUL.md format
52
+
53
+ `SOUL.md` defines the agent's core identity. It is human-authored and never
54
+ modified at runtime.
55
+
56
+ ```markdown
57
+ # Name
58
+ Jeeves
59
+
60
+ # Mission
61
+ You are Jeeves, a butler inhabiting the Manor House in this MOO world. Your purpose
62
+ is to assist guests, maintain the manor's dignity, and report anything unusual to
63
+ the Wizard. You are unfailingly polite and subtly condescending.
64
+
65
+ # Persona
66
+ Speak in formal British English. Address players as "sir" or "madam." Never express
67
+ surprise directly — use understatement. Keep responses brief and to the point.
68
+
69
+ ## Rules of Engagement
70
+ - `^You feel hungry` -> eat crumpets
71
+ - `(?i)ring.*bell` -> say How may I assist you?
72
+ - `^Phil arrives` -> say Good evening, sir.
73
+
74
+ ## Verb Mapping
75
+ - look_around -> look
76
+ - go_north -> go north
77
+ - greet_player -> say Good evening!
78
+ - serve_tea -> put tea on tray
79
+ ```
80
+
81
+ | Section | Required | Notes |
82
+ |---|---|---|
83
+ | `# Name` | Yes | Agent's in-world name |
84
+ | `# Mission` | Yes | Seeded into the LLM system prompt |
85
+ | `# Persona` | Yes | Tone and style; appended to system prompt |
86
+ | `## Rules of Engagement` | No | Reflexive triggers; `pattern -> command` |
87
+ | `## Verb Mapping` | No | Intent-to-command map; `intent -> command` |
88
+
89
+ Rule patterns use Python `re.search()` syntax. They do not need to match the full
90
+ line.
91
+
92
+ `SOUL.patch.md` holds learned rules and verb mappings. The agent appends to it
93
+ at runtime; you should not need to edit it. Delete it to reset learned behaviors
94
+ without changing the core soul.
95
+
96
+ ---
97
+
98
+ ## settings.toml format
99
+
100
+ ```toml
101
+ [ssh]
102
+ host = "localhost"
103
+ port = 8022
104
+ user = "wizard"
105
+ password = "your-password"
106
+ key_file = "" # path to private key; leave empty to use password
107
+
108
+ [llm]
109
+ provider = "anthropic"
110
+ model = "claude-opus-4-6"
111
+ api_key_env = "ANTHROPIC_API_KEY"
112
+
113
+ [agent]
114
+ command_rate_per_second = 1.0
115
+ memory_window_lines = 50
116
+ idle_wakeup_seconds = 60.0
117
+ ```
118
+
119
+ The API key is never stored in `settings.toml`. It is read at runtime from the
120
+ environment variable named in `api_key_env`.
121
+
122
+ `idle_wakeup_seconds` — seconds of inactivity before the brain runs an unsolicited
123
+ LLM cycle. The agent may choose to stay silent; this just ensures it checks in
124
+ periodically. The TUI shows `wait>` (red) when the timer is within 30 seconds of
125
+ firing.
126
+
127
+ ---
128
+
129
+ ## CLI reference
130
+
131
+ ### `moo-agent init`
132
+
133
+ ```
134
+ moo-agent init [--output-dir DIR] [--name NAME] [--host HOST] [--port PORT]
135
+ [--user USER] [--api-key-env ENV_VAR] [--force]
136
+ ```
137
+
138
+ | Flag | Default | Description |
139
+ |---|---|---|
140
+ | `--output-dir` | `./moo-agent-config` | Where to write the config files |
141
+ | `--name` | `Agent` | Agent's in-world name |
142
+ | `--host` | `localhost` | SSH host |
143
+ | `--port` | `8022` | SSH port |
144
+ | `--user` | `wizard` | SSH username |
145
+ | `--api-key-env` | `ANTHROPIC_API_KEY` | Env var name for the API key |
146
+ | `--force` | off | Overwrite existing files |
147
+
148
+ ### `moo-agent run`
149
+
150
+ ```
151
+ moo-agent run <config-dir>
152
+ ```
153
+
154
+ Reads `settings.toml` and `SOUL.md` from `<config-dir>` and starts the agent.
155
+
156
+ ---
157
+
158
+ ## Architecture
159
+
160
+ ```
161
+ DjangoMOO Server (SSH, port 8022)
162
+ |
163
+ | PTY TERM=moo-automation
164
+ | PREFIX/SUFFIX delimiters
165
+ | QUIET mode (plain text)
166
+ v
167
+ connection.py MooSession.data_received -> buffer -> extract -> strip ANSI
168
+ |
169
+ | on_output(text)
170
+ v
171
+ brain.py asyncio.Queue -> rolling window (50 lines)
172
+ reflexive rule check -> immediate dispatch
173
+ LLM inference (Anthropic, ReAct) -> intent resolution
174
+ idle wakeup timer -> unsolicited LLM cycle
175
+ rate-limited dispatch (asynciolimiter)
176
+ |
177
+ | send_command(cmd) / on_thought(text) / on_status_change(status)
178
+ v
179
+ tui.py prompt-toolkit full-screen app
180
+ output pane: server=green, thought=blue, action=red, patch=yellow
181
+ status prompt: interact=green, wait=red, working=yellow
182
+ Escape -> scroll mode (arrow keys / PgUp/PgDn)
183
+ input field -> on_user_input -> brain.enqueue_instruction()
184
+ ```
moo/agent/__init__.py ADDED
File without changes