Skip to content

Learning-driven command correction: Phase 2 & 3 #810

@AlexMikhalev

Description

@AlexMikhalev

Context

Phase 1 (currently deployed) widens the OpenCode tool.execute.before hook so it pipes whitelisted package-manager commands through terraphim-agent replace, using the Terraphim Engineer role's KG. Verified mappings include:

  • npm installbun add
  • npx create-react-app foobunx create-react-app foo
  • pip install requestsuv add requests
  • pip install -r requirements.txtuv sync
  • python -m pip install fastapiuv add fastapi
  • git commit -m "fix npm install bug"git commit -m "fix bun add bug"

See docs/src/command-rewriting-howto.md for the full Phase 1 guide.

Phase 1 uses only the curated KG at ~/.config/terraphim/docs/src/kg/. Captured corrections under ~/Library/Application Support/terraphim/learnings/correction-*.md (written by terraphim-agent learn hook --learn-hook-type user-prompt-submit) are stored but not applied. This issue tracks closing that loop.

Phase 2 – Wire user-prompt-submit into agent hooks

Goal: every time the user types "use X instead of Y" / "prefer X over Y" / "use X not Y" / "switch to X" in a prompt, the existing process_user_prompt_submit parser records a CorrectionType::ToolPreference file.

Work:

  1. Document which agent events map to user-prompt-submit for each adapter (Claude Code, OpenCode, Codex). OpenCode exposes something like experimental.chat.messages.transform – confirm the exact event name in @opencode-ai/plugin/dist/index.d.ts.
  2. Add the hook invocation in:
    • examples/claude-code-hooks/ (shell script variant).
    • An OpenCode plugin that pipes { user_prompt } JSON into terraphim-agent learn hook --format opencode --learn-hook-type user-prompt-submit.
  3. Unit tests covering the three pattern variants plus negative cases ("I prefer tea over coffee" should NOT be captured as a tool preference).
  4. Docs: append a Phase 2 section to docs/src/command-rewriting-howto.md and content/docs/command-rewriting-howto.md on the terraphim.ai Zola site.

Acceptance: uttering "use uv instead of pip" in a fresh session creates one file under .terraphim/learnings/correction-*.md or the global equivalent.

Phase 3 – Compile captured corrections into a thesaurus

Goal: captured ToolPreference corrections are turned into live replace rules without manual KG authoring.

Work in crates/terraphim_agent/src/learnings/capture.rs:

/// Compile stored corrections of given types into a Thesaurus usable by `replace`.
pub fn compile_corrections_to_thesaurus(
    storage_dir: &Path,
    correction_types: &[CorrectionType],
) -> Result<Thesaurus, LearningError>

/// Export as Logseq-style KG markdown (one file per corrected term) for review / version control.
pub fn export_corrections_as_kg(
    storage_dir: &Path,
    correction_type: CorrectionType,
    output_dir: &Path,
) -> Result<usize, LearningError>

CLI subcommands in crates/terraphim_agent/src/main.rs:

terraphim-agent learn compile-thesaurus \
    --type tool-preference \
    --output ~/.config/terraphim/kg/compiled/corrections.json

terraphim-agent learn export-kg \
    --type tool-preference \
    --output ~/.config/terraphim/kg/commands/

Extend replace (or add a new --extra-thesaurus <file> flag) so hooks can merge compiled corrections over the role's KG thesaurus. Merge semantics: compiled corrections override the base KG (learnt preferences win).

Invalidation: the SQLite thesaurus cache at /tmp/terraphim_sqlite/terraphim.db (keyed thesaurus_<role>.json) must be invalidated when corrections change. Options: (a) touch the mtime of the KG directory; (b) include the corrections-dir mtime in the cache key; (c) ship a terraphim-agent cache invalidate --role <role> command.

Acceptance:

  1. terraphim-agent learn capture-correction --original "pip install" --corrected "uv add" --correction-type tool-preference creates a file.
  2. terraphim-agent learn compile-thesaurus --type tool-preference produces a JSON with the mapping.
  3. terraphim-agent replace "pip install requests" --extra-thesaurus <compiled.json> returns uv add requests even if the base KG doesn't have that mapping.
  4. Integration test runs through steps 1-3 with #[tokio::test] in crates/terraphim_agent/tests/.

Phase 3.5 – OpenCode plugin extension (optional polish)

Modify terraphim-hooks.js (and the reference script in examples/claude-code-hooks/) to:

  • Detect when a new correction-*.md is written (mtime check on the learnings dir).
  • Automatically run terraphim-agent learn compile-thesaurus and pass --extra-thesaurus to the next replace invocation.

This closes the feedback loop: user says "use uv instead of pip" once → captured → compiled → applied on the next bash call.

Non-goals for this issue

  • Expanding the rewriteable-head whitelist beyond package managers. That is a separate conversation about risk (shell syntax is easy to corrupt).
  • Multi-user/shared corrections with trust levels (the existing shared_learning module is out of scope here; see CLAUDE.md for that roadmap).

Reference files

  • docs/src/command-rewriting-howto.md (this repo) – Phase 1 how-to, now on docs.terraphim.ai after next publish.
  • ~/projects/personal/private_agents_settings/opencode/plugin/terraphim-hooks.js – current Phase 1 hook implementation (pushed to AlexMikhalev/private_agents_settings).
  • crates/terraphim_agent/src/learnings/hook.rsprocess_user_prompt_submit, LearnHookType::UserPromptSubmit.
  • crates/terraphim_agent/src/learnings/capture.rsCorrectionEvent, capture_correction.
  • crates/terraphim_automata/src/builder.rs – Logseq thesaurus builder.
  • crates/terraphim_automata/src/matcher.rs – Aho-Corasick replace_matches, MIN_PATTERN_LENGTH = 2.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions