Skip to content

feat(prompt): add core tool taxonomy block#2292

Open
LING71671 wants to merge 2 commits into
Hmbown:mainfrom
LING71671:fix/2084-tool-taxonomy-prompt
Open

feat(prompt): add core tool taxonomy block#2292
LING71671 wants to merge 2 commits into
Hmbown:mainfrom
LING71671:fix/2084-tool-taxonomy-prompt

Conversation

@LING71671
Copy link
Copy Markdown
Contributor

@LING71671 LING71671 commented May 27, 2026

Summary

  • prepend a compact core tool taxonomy block to the composed system prompt
  • generate taxonomy tool names from the eager native-tool list instead of duplicating a separate prompt-only list
  • add prompt tests covering the taxonomy text, eager-tool sync, and locale-bookend guard behavior

Refs #2084

Verification

  • cargo test -p codewhale-tui --bin codewhale-tui tool_taxonomy --all-features
  • cargo test -p codewhale-tui --bin codewhale-tui compose_prompt --all-features
  • cargo test -p codewhale-tui --bin codewhale-tui prompts::tests --all-features
  • cargo fmt --all --check
  • git diff --check
  • cargo clippy -p codewhale-tui --all-targets --all-features

Greptile Summary

This PR prepends a compact ## Core Tool Taxonomy block to the assembled system prompt, grouping core tools into discovery, git-inspection, and verification categories. Tool names are derived at runtime from DEFAULT_ACTIVE_NATIVE_TOOLS (via the new default_active_native_tool_names accessor in engine.rs) so the taxonomy cannot silently diverge from the eager-load list.

  • render_core_tool_taxonomy_block correctly returns Option<String> per group, eliminating the malformed-sentence case; run_tests is filtered from Plan-mode prompts via core_taxonomy_tools_for_mode.
  • Three new tests cover taxonomy prefix order, Plan/Agent mode differences, and the sync invariant; the CJK guard is now scoped to BASE_PROMPT and each per-mode taxonomy string.

Confidence Score: 5/5

Safe to merge — the taxonomy block is generated entirely from the existing eagerly-loaded tool list, making the prompt change deterministic and self-consistent.

The logic is correct: render_core_tool_group returns Option so empty groups produce no output, the Plan-mode filter is explicit and tested, and the sync test guarantees taxonomy constants stay in step with the engine tool list.

No files require special attention. crates/tui/src/prompts.rs is the main change and its new tests cover the key invariants.

Important Files Changed

Filename Overview
crates/tui/src/core/engine.rs Adds a thin pub(crate) accessor that re-exports tool_catalog::DEFAULT_ACTIVE_NATIVE_TOOLS so prompts.rs can reference it without accessing a private sub-module directly. Change is minimal and correct.
crates/tui/src/prompts.rs Prepends a mode-aware Core Tool Taxonomy block to the composed system prompt; correctly guards empty groups via Option, filters run_tests from Plan mode, and adds three new tests covering taxonomy content, eager-tool sync, and the scoped CJK guard.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[compose_prompt_with_approval_and_model] --> B[render_core_tool_taxonomy_block mode]
    B --> C[core_taxonomy_tools_for_mode mode]
    C --> D[default_active_native_tool_names]
    C -->|Plan mode| E[filter out run_tests]
    B --> F[render_core_tool_group DISCOVERY]
    B --> G[render_core_tool_group GIT]
    B --> H[render_core_tool_group VERIFICATION]
    F -->|Some| I[Use ... for discovery.]
    G -->|Some| J[Use ... for git inspection.]
    H -->|Some if not Plan| K[Use ... for verification.]
    I & J & K --> L[Core Tool Taxonomy block]
    L --> M[parts array assembled]
    M --> N[Final system prompt]
Loading

Fix All in Codex Fix All in Claude Code Fix All in Cursor

Reviews (2): Last reviewed commit: "fix(prompt): make tool taxonomy mode-awa..." | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a dynamically generated "Core Tool Taxonomy" block prepended to the system prompt, helping guide the model on which tools to use for discovery, git inspection, and verification. It also includes corresponding unit tests and relaxes a test assertion regarding CJK characters. The review feedback suggests making the taxonomy block dynamic based on the active AppMode (for instance, omitting run_tests in read-only Plan mode) and formatting the output cleanly when certain tool groups are empty.

Comment thread crates/tui/src/prompts.rs Outdated
Comment on lines +514 to +522
fn render_core_tool_taxonomy_block() -> String {
let core_tools = crate::core::engine::default_active_native_tool_names();
format!(
"## Core Tool Taxonomy\n\nUse {} for discovery. Use {} for git inspection. Use {} for verification.",
render_core_tool_group(TOOL_TAXONOMY_DISCOVERY, core_tools),
render_core_tool_group(TOOL_TAXONOMY_GIT, core_tools),
render_core_tool_group(TOOL_TAXONOMY_VERIFICATION, core_tools)
)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The taxonomy block is currently static and does not account for the active mode. In Plan mode, code-execution tools like run_tests are not registered in the tool catalog to maintain read-only safety. However, the taxonomy prompt will still instruct the model to use run_tests for verification, which can lead to model confusion or hallucinations.

Additionally, if any tool group is empty, the current formatting will produce awkward strings with double spaces (e.g., Use for verification.).

We should update render_core_tool_taxonomy_block to accept the AppMode and dynamically filter out unavailable tools, while cleanly formatting only the non-empty tool groups.

fn render_core_tool_taxonomy_block(mode: AppMode) -> String {
    let core_tools = crate::core::engine::default_active_native_tool_names();
    let discovery = render_core_tool_group(TOOL_TAXONOMY_DISCOVERY, core_tools);
    let git = render_core_tool_group(TOOL_TAXONOMY_GIT, core_tools);
    let verification = if mode == AppMode::Plan {
        String::new()
    } else {
        render_core_tool_group(TOOL_TAXONOMY_VERIFICATION, core_tools)
    };

    let mut parts = Vec::new();
    if !discovery.is_empty() {
        parts.push(format!("Use {discovery} for discovery."));
    }
    if !git.is_empty() {
        parts.push(format!("Use {git} for git inspection."));
    }
    if !verification.is_empty() {
        parts.push(format!("Use {verification} for verification."));
    }

    format!("## Core Tool Taxonomy\n\n{}", parts.join(" "))
}

Comment thread crates/tui/src/prompts.rs Outdated
) -> String {
let parts: [&str; 4] = [
&apply_model_template(BASE_PROMPT.trim(), model_id),
let tool_taxonomy = render_core_tool_taxonomy_block();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Pass the mode parameter to render_core_tool_taxonomy_block to dynamically filter out tools that are not registered in the current mode (such as run_tests in Plan mode).

Suggested change
let tool_taxonomy = render_core_tool_taxonomy_block();
let tool_taxonomy = render_core_tool_taxonomy_block(mode);

Comment thread crates/tui/src/prompts.rs Outdated
Comment thread crates/tui/src/prompts.rs
Comment thread crates/tui/src/prompts.rs
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