Skip to content

v0.4.1-fixes: AI hardening, model-agnostic prompts, codebase modularization - #17

Merged
cuttlefisch merged 13 commits into
mainfrom
feature/v0.4.1-fixes
Apr 24, 2026
Merged

v0.4.1-fixes: AI hardening, model-agnostic prompts, codebase modularization#17
cuttlefisch merged 13 commits into
mainfrom
feature/v0.4.1-fixes

Conversation

@cuttlefisch

@cuttlefisch cuttlefisch commented Apr 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • AI agent hardening: enforce max_rounds, fix oscillation detection, soften pruning, fix mode system (default/keybinding/status bar/enforcement)
  • Model-agnostic prompts: redesign prompts for weak-model-friendly use, clean up executor tool names, centralize AI_PROFILES constant
  • Codebase modularization: split 6 god files (18,674 lines total) into focused module directories:
    • core/editor/tests.rs (4,458 lines) → 14 test modules
    • mae/key_handling.rs (2,056 lines) → 10 mode-specific modules
    • ai/tools.rs (2,704 lines) → 8 modules by category
    • ai/executor.rs (2,050 lines) → 7 modules by category
    • ai/session.rs (2,791 lines) → 5 modules (run_loop, context_mgmt, handle_prompt, tests)
    • mae/main.rs (2,477 lines) → extracted terminal_loop, lsp_bridge, dap_bridge, shell_keys
  • Code smell audit: 12 fixes across providers/session/executor (ErrorKind consistency, cached transcript path, finalize_transaction helper, stale model names, remove panicking .expect() in providers)
  • Version bump: v0.4.1

Net: -63 lines, +20,181/-11,308 with no new files beyond the module splits. All 1,484 tests pass.

Test plan

  • make ci passes (fmt + clippy + build + test)
  • make build succeeds (includes GUI)
  • Test count preserved (1,484 tests, 232 in mae-ai alone)
  • Manual smoke test: launch editor, open AI conversation, verify mode switching

🤖 Generated with Claude Code

cuttlefisch and others added 13 commits April 24, 2026 03:03
- Add max_rounds guard at top of tool loop — previously set but never checked
- Fix oscillation detection: count frequency in sliding window instead of
  requiring consecutive identical turns. Catches A→B→A→B patterns that
  previously evaded the circuit breaker
- Reduce aggressive_prune from 25% to 10% to preserve more context
- Reduce context window shrink from 50% to 20% on overflow
- Improve truncation message with actionable guidance (use line ranges,
  narrow queries) instead of generic warning
- Remove unused consecutive_identical_tools field
- Add tests: max_rounds enforcement, A-B oscillation detection, prune ratio

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix default ai_mode from invalid "manual" to "standard" (both constructors)
- Fix BackTab cycle to use valid modes: standard → auto-accept → plan
- Add mode to status bar: [AI:standard|Write] in both terminal and GUI
- Add plan-mode guard on buffer_write — returns error suggesting create_plan
- Add mode/profile context injection per-turn so model knows its constraints

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove dead terminal_list entry from executor (duplicate of shell_list)
- Add comment documenting session-level tools handled in session.rs
- Define AI_PROFILES constant and use in ai_set_profile + delegate tools
- Change brittle assert_eq!(tools.len(), 98) to assert!(>= 90)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rewrite all 4 profile prompts: shorter, concrete rules, no <reasoning> blocks
- Add READ-ONLY hard constraints (Claude Code pattern) to explorer/planner/reviewer
- Add "When to Stop" section to system prompt with explicit completion criteria
- Add "Mode Rules (ENFORCED)" section replacing advisory mode paragraph
- Remove hardcoded profile names from delegation SOP
- Drop Forced Reasoning Block requirement (Claude-ism that confuses other models)
- Prompts now work across Claude, Gemini, OpenAI, DeepSeek, and smaller models

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tripping

- gpt-4o-mini: 100→30, deepseek-*: 100→25 to prevent token drain
- trim_messages: only strip orphaned tool messages after actual pruning,
  preventing destruction of valid tool history on non-pruned sessions
- Add regression test for trim preservation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split monolithic editor/tests.rs into editor/tests/ directory:
- command_tests (48), navigation_tests (55), visual_tests (34)
- editing_tests (28), operator_tests (33), count_tests (21)
- change_tests (14), search_tests (12), text_object_tests (15)
- lsp_tests (21), shell_tests (15), mouse_tests (13)
- buffer_tests (12), misc_tests (18)

All 1066 tests pass. Shared helpers in tests/mod.rs.
No file exceeds 800-line ceiling (max: navigation_tests at 757).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…modules

Split key_handling.rs into key_handling/ directory:
- mod.rs (363) — handle_key dispatcher, conversion fns, shared helpers
- normal.rs (500) — handle_keymap_mode, handle_describe_key_await, handle_normal_mode
- command.rs (336) — handle_command_mode, tab completion, self-test prompt
- conversation.rs (265) — handle_conversation_input, submit_conversation_prompt
- file_picker.rs (225) — handle_file_picker_mode, handle_file_browser_mode
- insert.rs (154) — handle_insert_mode
- command_palette.rs (110) — handle_command_palette_mode
- visual.rs (81) — handle_visual_mode
- git_status.rs (70) — handle_git_status_mode
- search.rs (29) — handle_search_mode

All tests pass. No file exceeds 500-line ceiling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
tools.rs (2704 lines) → tools/ directory (7 modules + mod.rs)
executor.rs (2050 lines) → executor/ directory (6 helpers + mod.rs)

All 232 AI tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…eys from main.rs

main.rs (2477 → 1148 lines, 460 non-GUI):
- terminal_loop.rs (564) — run_terminal_loop, cleanup_stale_mcp_sockets, run_headless_self_test
- lsp_bridge.rs (433) — drain_lsp_intents, handle_lsp_event, try_complete_deferred, open_location
- dap_bridge.rs (217) — drain_dap_intents, handle_dap_event, intent_to_dap_command
- shell_keys.rs (157) — shell_dims_for_buffer, handle_shell_key, keypress_to_pty_bytes

GUI code remains in main.rs under #[cfg(feature = "gui")] for a future split.
All tests pass. make build (with GUI) succeeds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- mod.rs (183) — struct definition, constructors, builders
- run_loop.rs (178) — run() async loop, execute_shell(), update_cost()
- context_mgmt.rs (149) — trim_messages, aggressive_prune, budget
- handle_prompt.rs (1013) — handle_prompt(), collapse_transaction()
- tests.rs (1295) — all session tests

All 232 AI tests pass. Fields changed to pub(super) for cross-module access.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- #1: Replace .expect() with .unwrap_or_default() in provider HTTP clients
- #2: Remove redundant Some("STOP") match arm in gemini.rs
- #3/#17: Fix ErrorKind::Unknown → ErrorKind::Transport for HTTP/JSON errors
  across all three providers (claude, gemini, openai)
- #6: Add finalize_transaction() helper, replace 10 collapse+clear patterns
- #7: Cache transcript_path as String once, eliminate 8x to_string_lossy allocs
- #15: Remove dead `let _ = editor` in executor benchmark fn
- #18: Fix stale gemini-3.1-*/3.0-flash model names → real 2.5/2.0 names
  in both context_limits.rs and pricing.rs; deduplicate gemini-2.5-pro entry

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ROADMAP: v0.4.0→v0.4.1, add Phase 3g-v2 section (6 file splits,
  12 code smell fixes), update test table (1,324→1,590), add rendering
  dedup and packaging readiness to priority list
- README: badges updated (tests 1,324→1,590, LOC ~26k→~76k)
- CLAUDE.md: v0.4.1 modularization note in Phase 3 section

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

1 participant