Files
codewhale/crates
Hunter Bown bd938a559c fix(rlm): wire real recursive substrate; bump 0.6.4
The v0.6.3 RLM loop had Algorithm 1's outer shape but the substrate was
non-functional: `llm_query()` was a Python stub that returned a hardcoded
string and `child_model` was bound with an underscore prefix and silently
dropped. The recursive sub-LLM call advertised by /rlm never fired.

This commit wires the substrate end-to-end per Zhang/Kraska/Khattab
(arXiv:2512.24601, Algorithm 1):

- New axum HTTP sidecar (`rlm/sidecar.rs`) bound to 127.0.0.1:0 for the
  duration of one RLM turn. Python's `llm_query()` and `sub_rlm()` are
  real `urllib.request` POSTs; Rust services them via the existing
  DeepSeek client. Token usage from sidecar-served calls folds into the
  parent `RlmTurnResult.usage`.
- `child_model` is plumbed through `Op::RlmQuery` → `AppAction::RlmQuery`
  → `run_rlm_turn` → sidecar handlers; default remains `deepseek-v4-flash`.
- New `sub_rlm(prompt)` Python helper runs a full Algorithm-1 turn at
  depth-1 (paper's `sub_RLM`). Default `max_depth = 2` from `/rlm`. The
  recursive opaque-future cycle is broken by returning a concrete
  `Pin<Box<dyn Future + Send>>` from `run_rlm_turn_inner`.
- Strict termination: the loop ends only via `FINAL(value)` (or the
  iteration cap). One fence-less round is tolerated with a reminder
  appended; two consecutive ones surface the model text as a
  `RlmTermination::DirectAnswer` exit. New `RlmTermination` enum lets
  callers tell `Final | DirectAnswer | Exhausted | Error` apart.
- Richer `Metadata(state)`: includes paper-required access patterns
  (`repl_get` / slicing / `splitlines` / `repl_set` / `llm_query` /
  `sub_rlm` / `FINAL`) and a live list of variable keys currently in
  the REPL state file.
- Unicode-safe `truncate_text` (was mixing bytes with chars), per-turn
  state-file cleanup, `ROOM_TEMPERATURE` typo → `ROOT_TEMPERATURE`.
- New end-to-end test `sidecar_url_is_exported_to_python_env` stands up
  a stand-in axum server, runs `print(llm_query('hello'))` in the real
  PythonRuntime, and asserts the reply round-trips. Catches future
  regressions in sidecar URL passthrough.

Versions: workspace 0.6.3 → 0.6.4 in Cargo.toml; npm wrapper 0.6.3 → 0.6.4
in npm/deepseek-tui/package.json.

Gates: cargo fmt, cargo clippy --all-targets --all-features --locked
-D warnings, cargo test --workspace --all-features --locked (1088
passed), parity_protocol/parity_state/snapshot, RUSTDOCFLAGS=-Dwarnings
cargo doc --workspace --no-deps — all green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:36:59 -05:00
..