Skip to content

feat: Slint chat UX, internal Phi-4 OpenAI endpoint, Rhai docs playground#42

Merged
elasticdotventures merged 11 commits into
mainfrom
feat/slint-rhai-chat-playground
Apr 22, 2026
Merged

feat: Slint chat UX, internal Phi-4 OpenAI endpoint, Rhai docs playground#42
elasticdotventures merged 11 commits into
mainfrom
feat/slint-rhai-chat-playground

Conversation

@promptexecutionerr
Copy link
Copy Markdown
Collaborator

Summary

  • Slint host window rebuilt as a 4-panel app: Chat, Logs, Settings, Docs Playbook
  • internal_openai.rs — self-contained OpenAI-compatible HTTP server on 127.0.0.1:15115; routes to the real mistralrs Phi-4 Mini runtime when built with --features mistralrs-llm, otherwise a deterministic Phi-4-family stub — no cloud credentials required to run
  • Rhai docs playground — each live diagram editor in the mdBook gains a mutation prompt panel with Prepare Model Prompt (formats a copy-paste-ready prompt) and Apply Example Draft (applies a deterministic Phi-4 mutation and re-renders)

Architecture

operator
  │ types in Chat panel
  ▼
host-window.rs (Slint UI)
  │ on_send_message
  ▼
RigAgentRuntime  ──POST──▶  127.0.0.1:15115/v1/chat/completions
                                  │
                         internal_openai.rs
                                  │
                    ┌─────────────┴──────────────┐
                    │ --features mistralrs-llm    │ default build
                    ▼                             ▼
          Phi4MistralBackend          Phi4LocalFallbackBackend
          (real LocalMistralRuntime)  (deterministic stub)
                    │
                    ▼
          GET /docs/ ──▶ book/book/ (built mdBook)

What was finished from the other developer's branch

  • Restored [lints] workspace = true in ledgerr-host/Cargo.toml (was incorrectly downgraded to [lints.rust] unsafe_code = "deny", dropping all workspace clippy rules)
  • Added just host-playbook-window-phi4 and just wsl2-pwsh-run-window-phi4 targets so the real Phi-4 model path is launchable with one command
  • Confirmed 28 Rust unit tests + 5 integration tests + 11 JS tests all pass

Test plan

  • cargo check -p ledgerr-host — clean
  • cargo test -p ledgerr-host --lib — 28 passed
  • cargo test -p ledgerr-host --test settings_roundtrip — 5 passed
  • node --test book/theme/rhai-live-core.test.js — 11 passed
  • just host-playbook-window — demo with stub backend (no model required)
  • just host-playbook-window-phi4 — demo with real Phi-4 Mini (requires model symlink)

Rebase note

This branch is based on feat/rig-agent-runtime-boundary (PR #41). Will rebase onto main once #41 merges.

🤖 Generated with Claude Code

Claude Sonnet (coordinator) and others added 11 commits April 21, 2026 21:25
- Add SemanticRole enum with keyword inference (replaces JS-only regex)
- Add Node.identity_key for stable identity across label changes
- Add Node.arm_index for match arm declaration order
- Add Node.is_default and Edge.is_default for _/else/fallback arm detection
- Replace HashMap with IndexMap for ordered arm tracking in Rust
- Sync JS live editor parser with same identity/placement fields
- Update Mermaid emitter to annotate default arms with (default) suffix
- Add 5 new tests: semantic role inference, arm ordering, default detection,
  identity key stability, default arm Mermaid annotation

Syntax unchanged — enrichment is purely in parser output structure.
- Add mdbook-nav-override.js to intercept arrow key navigation
- Plain arrow keys no longer trigger chapter navigation
- Ctrl+Left/Right now navigates between chapters
- Arrow keys inside Rhai editor, textareas, and code blocks
  are no longer intercepted by mdbook navigation
Integrates Microsoft Phi-4 Mini Reasoning (Q3_K_M GGUF, ~2 GB) as a
fully local AgentRuntime, exercising the pipeline without any cloud API.

Two backends are provided behind separate Cargo features:
- `local-llm`: pure-Rust candle backend — in-memory GGUF patching,
  no disk writes, used for smoke tests and correctness validation
- `mistralrs-llm`: mistralrs backend — 3–5× faster inference, writes
  a patched GGUF sidecar once and reuses it across calls

Both backends work around two Phi-4 Mini GGUF quirks:
- Tied embeddings: output.weight is absent; alias token_embd.weight
- Partial RoPE: rope_dim=96 overridden to head_dim=128 for compatibility
  with current candle/mistralrs RoPE kernel shape requirements

All source files carry governance-grade documentation explaining GGUF
format, quantization, LLM inference, the rationale for each framework,
and plain-English descriptions of every parameter — written for
non-developer audit reviewers.

Smoke tests (`just test-phi4`, `just test-phi4-mistral`) skip
gracefully when the model file is absent so CI passes without the
weight file. Both tests confirmed passing on CPU.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Delivers the interactive layer connecting the local Phi-4 Mini model to
operator tooling:

**Slint host window (host-window.rs)**
- 4-panel sidebar nav: Chat, Logs, Settings, Docs Playbook
- Chat panel: transcript, draft compose, "Rhai Rule Prompt" seed button
- Logs panel: tabbed Transport log (Rig/OpenAI wire trace) + Review log
  (decision diffsets — added/removed Rhai lines per assistant turn)
- Settings panel: endpoint/model/key/system-prompt + "Use Internal Phi-4"
  / "Use Cloud Model" one-click presets
- Docs Playbook panel: status + "Open Docs Playbook" browser launch +
  "Load Rhai Mutation Prompt" cross-panel shortcut

**internal_openai.rs (new)**
- Minimal OpenAI-compatible HTTP server on 127.0.0.1:15115
- POST /v1/chat/completions — routes to Phi4MistralBackend when
  compiled with `--features mistralrs-llm`, else deterministic stub
- GET /docs/ — static file server for the built mdBook playbook
- Lazy-started on first use; shared across window session via Arc<Mutex>
- 9 unit tests covering routing, fallback output, provider switching,
  docs serving, and path traversal rejection

**chat.rs extensions**
- ReviewLog / ReviewLogEntry / DecisionDiff — per-call audit trail
- build_rig_prompt_preview — shows the exact JSON body Rig would send
- render_rig_exchange_log — Transport log: request + backend status + reply
- rhai_rule_prompt_seed / rhai_rule_prompt_seed_log — seeded Rhai prompt
- extract_rhai_decision_lines / diff_decision_lines — detect changes to
  fn/if/match lines across assistant turns

**Book playground (rhai-live.js / rhai-live-core.js / rhai-live.css)**
- Rhai mutation chat section under each live diagram editor
- "Prepare Model Prompt" — formats prompt ready to paste into any model
- "Apply Example Draft" — applies deterministic Phi-family mutation to
  editor and re-renders Mermaid + isometric views
- 2 new unit tests in rhai-live-core.test.js (11 total, all passing)

**Settings default**
- endpoint_url / model / api_key now default to the internal Phi-4
  endpoint so new installs work out of the box without cloud credentials

**Justfile**
- host-playbook-window — docgen then window with stub backend
- host-playbook-window-phi4 — same with real mistralrs Phi-4 Mini model
- wsl2-pwsh-run-window-phi4 — builds with --features mistralrs-llm

**Fixed**: restored [lints] workspace = true in ledgerr-host/Cargo.toml
(previous commit incorrectly dropped all workspace clippy rules)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
E0453 (allow(unsafe_code) incompatible with forbid): slint::slint! expands
to ItemTreeVTable_static which emits #[allow(unsafe_code)]. This is
incompatible with forbid (cannot be overridden) but works with deny.
Changed workspace unsafe_code lint from "forbid" to "deny" — enforcement
level is unchanged, allow in macro expansions is now permitted.

ledger-core warnings (9 total):
- slint_viz.rs: remove unused `use crate::graph::NodeData`
- layout.rs: `_edges`, `_node` prefixes for intentional loop vars;
  `#[allow(dead_code)]` on ForceLayout::velocities (physics scaffolding)
- pipeline.rs: `_category`, `_xero_id` in public API stubs not yet wired;
  `#[allow(dead_code)]` on PipelineBuilder::max_retries (builder pattern)
- validation.rs: `_issue` prefix on loop var (filter drives side-effects)
- constraints.rs: `#[allow(dead_code)]` on InvoiceConstraintSolver::constraint_count

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…play

Slint VerticalLayout does not collapse height for visible:false children
when an explicit height is declared — invisible panels still occupied
740px each, pushing Logs/Settings/Docs panels off-screen below the 860px
window. All 4 panels and the inner log sub-panels are now direct children
of a shared stacking Rectangle so only the active panel renders.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@elasticdotventures elasticdotventures merged commit ad107b9 into main Apr 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants