From 62ea08ac5e128109af71588dc9db28fae40815bf Mon Sep 17 00:00:00 2001 From: "ilblackdragon@gmail.com" Date: Sat, 28 Mar 2026 12:10:01 -0700 Subject: [PATCH] fix: document Monty runtime limitations in CodeAct prompt, fix new-thread read-only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add "Runtime environment" section to codeact_preamble.md documenting Monty's restrictions: no stdlib imports, single imports only, no classes/ with/match/del/yield, available builtins and modules, workarounds - Add MONTY.md tracking current pin, all limitations, upgrade process, and changelog for future Monty updates - Fix gateway createNewThread() not resetting read-only state — new threads now eagerly enable chat input instead of waiting for async loadThreads() callback Co-Authored-By: Claude Opus 4.6 (1M context) --- crates/ironclaw_engine/MONTY.md | 63 +++++++++++++++++++ .../prompts/codeact_preamble.md | 17 +++++ src/channels/web/static/app.js | 2 + 3 files changed, 82 insertions(+) create mode 100644 crates/ironclaw_engine/MONTY.md diff --git a/crates/ironclaw_engine/MONTY.md b/crates/ironclaw_engine/MONTY.md new file mode 100644 index 00000000..fe86bd74 --- /dev/null +++ b/crates/ironclaw_engine/MONTY.md @@ -0,0 +1,63 @@ +# Monty Integration + +Monty is the embedded Python interpreter used for Tier 1 (CodeAct) execution. It's a lightweight Rust-native Python implementation — not CPython — so it has a restricted feature set. + +**Source**: `git = "https://github.com/pydantic/monty.git", branch = "main"` +**Pinned at**: `6053820` (2026-03-27, "Support max() kwargs/default") + +## Upgrade Process + +1. **Update the pin**: `cargo update -p monty` +2. **Check for new features**: `cd ~/.cargo/git/checkouts/monty-*/*/` and `git log --oneline` since last pin +3. **Update the preamble**: If a previously-unsupported feature now works, remove it from the "Runtime environment" section in `prompts/codeact_preamble.md` +4. **Update this file**: Record the new pin and what changed +5. **Run tests**: `cargo test -p ironclaw_engine` +6. **Watch traces**: After deploying, check traces for new `NotImplementedError` patterns (self-improvement mission catches these) + +## Current Limitations (as of pin `6053820`) + +These are documented in `prompts/codeact_preamble.md` so the LLM avoids them: + +### Syntax not supported +| Feature | Workaround | +|---------|-----------| +| `import a, b, c` (multi-module) | Use separate `import a` / `import b` statements | +| `class Foo:` | Use functions and dicts | +| `with` statements | Use try/finally or direct calls | +| `match` statements | Use if/elif chains | +| `del` statement | Reassign to None | +| `yield` / `yield from` | Use lists and list comprehensions | +| `*expr` (starred expressions) | Unpack explicitly | +| `async` / `await` | Not available; tool calls suspend the VM automatically | +| Type aliases (`type X = ...`) | Omit type annotations | +| Template strings (t-strings) | Use f-strings | +| Complex number literals | Use floats | +| Exception groups (`try*/except*`) | Use regular try/except | + +### No standard library +`import datetime`, `import csv`, `import json`, `import os`, `import io`, etc. all fail. + +Available built-in modules: +- `math` — standard math functions +- `re` — regex (basic) +- `sys` — system info (limited) +- `os.path` — path manipulation (limited) +- `typing` — type hints (limited, for annotation only) + +### Available builtins +`abs`, `all`, `any`, `bin`, `chr`, `divmod`, `enumerate`, `filter`, `getattr`, `hash`, `hex`, `id`, `isinstance`, `len`, `map`, `min`, `max`, `next`, `oct`, `ord`, `pow`, `print`, `repr`, `reversed`, `round`, `sorted`, `sum`, `type`, `zip` + +### Host-provided functions (always available) +These are injected by the IronClaw executor, not by Monty: +- `FINAL(answer)` / `FINAL_VAR(name)` — terminate with result +- `llm_query(prompt, context)` — recursive LLM sub-call +- `llm_query_batched(prompts)` — parallel sub-calls +- `rlm_query(prompt)` — full sub-agent with tools +- `globals()` / `locals()` — returns dict of known tool names +- All tool functions (web_search, http, time, etc.) + +## Upgrade Changelog + +| Date | Pin | Notable changes | +|------|-----|-----------------| +| 2026-03-20 | `6053820` | Initial integration. max() kwargs support. | diff --git a/crates/ironclaw_engine/prompts/codeact_preamble.md b/crates/ironclaw_engine/prompts/codeact_preamble.md index 7fcc49f5..50eacd40 100644 --- a/crates/ironclaw_engine/prompts/codeact_preamble.md +++ b/crates/ironclaw_engine/prompts/codeact_preamble.md @@ -40,3 +40,20 @@ You can write multiple code blocks across turns. Variables persist between block 6. For large data, process it in chunks using llm_query() on subsets rather than loading everything into context. 7. Outputs are truncated to 8000 chars — use variables to store large intermediate results. 8. Include the actual content in your FINAL() answer, not just a count or summary. Users want to see the details. + +## Runtime environment + +The Python REPL runs in Monty, a lightweight embedded interpreter — not CPython. Key differences: + +- **No standard library modules**: `import datetime`, `import csv`, `import json`, `import os`, `import re` etc. will fail with `ModuleNotFoundError`. Use the provided tool functions instead (e.g. `time()` for dates, `http()` for fetching data, `json()` for parsing). +- **Single imports only**: `import a, b, c` is not supported. Use separate statements: `import a` then `import b`. +- **No classes**: `class Foo:` is not supported. Use functions and dicts instead. +- **No `with` statements**: Use try/finally or just call functions directly. +- **No `match` statements**: Use if/elif chains. +- **No `del` statement**: Reassign to None instead. +- **No `yield`/`yield from`**: Use lists and list comprehensions instead of generators. +- **No `*expr` unpacking in assignments**: Unpack explicitly. +- **Available builtins**: `abs`, `all`, `any`, `bin`, `chr`, `divmod`, `enumerate`, `filter`, `getattr`, `hash`, `hex`, `id`, `isinstance`, `len`, `map`, `min`, `max`, `next`, `oct`, `ord`, `pow`, `print`, `repr`, `reversed`, `round`, `sorted`, `sum`, `type`, `zip`. +- **Available modules**: `math`, `re`, `sys`, `os.path`, `typing` (limited). +- **String methods, list methods, dict methods**: All work normally. +- For dates, use the `time()` tool. For CSV parsing, split strings manually. For HTTP, use `http()`. For JSON, use `json()` or work with dicts directly (tool results are already Python objects). diff --git a/src/channels/web/static/app.js b/src/channels/web/static/app.js index 889ba312..8b02cb96 100644 --- a/src/channels/web/static/app.js +++ b/src/channels/web/static/app.js @@ -2092,8 +2092,10 @@ function switchThread(threadId) { function createNewThread() { apiFetch('/api/chat/thread/new', { method: 'POST' }).then((data) => { currentThreadId = data.id || null; + currentThreadIsReadOnly = false; document.getElementById('chat-messages').innerHTML = ''; showWelcomeCard(); + enableChatInput(); loadThreads(); }).catch((err) => { showToast('Failed to create thread: ' + err.message, 'error');