Skip to content

Improve natural language package install parsing#764

Open
wangxq-cc wants to merge 1 commit into
cxlinux-ai:mainfrom
wangxq-cc:codex/nl-install-polish
Open

Improve natural language package install parsing#764
wangxq-cc wants to merge 1 commit into
cxlinux-ai:mainfrom
wangxq-cc:codex/nl-install-polish

Conversation

@wangxq-cc
Copy link
Copy Markdown

@wangxq-cc wangxq-cc commented May 13, 2026

Addresses cxlinux-ai/cx-distro#25 by improving the package agent natural-language install parser in cx-core, where the CX package agent implementation lives.

Changes:

  • Adds natural-language install profiles for machine learning, Python development, Docker, Kubernetes, and nginx.
  • Adds typo normalization for common demo mistakes such as instal pyhton, dockr, kubernets, and ngnix.
  • Adds ambiguity handling for broad requests such as "I need a web server" with clarification suggestions.
  • Displays reasoning, confidence, selected packages, and confirmation commands for profile-based installs.
  • Adds 10+ parser unit cases covering the issue acceptance criteria.

Validation:

  • git diff --check passes.
  • Could not run cargo fmt or cargo test locally because this environment does not have Rust tooling installed.

Summary by CodeRabbit

  • New Features

    • Natural-language package installation requests with confidence scoring and reasoning explanations
    • Intelligent clarification prompts for ambiguous package queries with suggestions
    • Improved tolerance for common typos in package commands
  • Tests

    • Enhanced test coverage for machine learning, web server, Python development, and container setup scenarios

Review Change Stack

Copilot AI review requested due to automatic review settings May 13, 2026 02:04
@wangxq-cc wangxq-cc requested a review from a team as a code owner May 13, 2026 02:04
@github-actions
Copy link
Copy Markdown
Contributor

CLA Verification Failed

The following contributors have not signed the Contributor License Agreement:

How to Sign

  1. Read the CLA document
  2. Open a CLA signature request
  3. A maintainer will add you to the signers list
  4. Comment recheck on this PR to re-run verification

This check runs automatically. Maintainers can update .github/cla-signers.json to add signers.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

📝 Walkthrough

Walkthrough

The PR extends the package agent to interpret natural-language package installation requests. PackageCommand gains two new variants—NaturalInstall and Clarify—to handle goals expressed in prose rather than explicit package names. Command parsing adds normalization logic to correct typos and recognize intent patterns, delegating to specialized matchers that return appropriate command variants. Handler routing executes these new variants through multi-package installers or clarification flows. Agent inference heuristics expand to catch thematic keywords and typos.

Changes

Natural-language package installation support

Layer / File(s) Summary
Natural-language command variants
wezterm-gui/src/agents/package.rs
PackageCommand enum gains NaturalInstall and Clarify variants with associated fields (query, packages, confidence, reasoning, reason, suggestions).
Input normalization and natural-language intent detection
wezterm-gui/src/agents/package.rs
New normalize_package_request helper applies typo mappings (e.g., "pyhton"→"python"); new parse_natural_install helper recognizes natural-language goal phrases and returns NaturalInstall or Clarify with predefined package sets and metadata.
Command parsing with natural-language support
wezterm-gui/src/agents/package.rs
PackageCommand::parse normalizes input, attempts natural-language parsing before regular parsing, and uses normalized tokens when locating package names in the standard flow.
Handler execution for natural-language commands
wezterm-gui/src/agents/package.rs
New install_packages multi-package function formats install messages from natural-language metadata; new clarify_install helper produces clarification responses. PackageAgent::can_handle and ::handle are extended to route NaturalInstall and Clarify commands.
Agent inference keywords
wezterm-gui/src/agents/runtime.rs
infer_agent package detection expands with keywords for typos ("instal"), setup phrases, web-server references, and machine-learning/python-development contexts.
Natural-language parsing tests
wezterm-gui/src/agents/package.rs
Test suite validates parsing of machine-learning profiles, python-development setups, docker/kubernetes configurations, web-server ambiguity, and typo tolerance (e.g., "instal pyhton").

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A fluffy rabbit hops with glee,
Natural language's the way to be!
Type "i need python" and off it goes,
No typos fret—the agent knows 🐰
Smart parsing blooms in autumn's light,
Package dreams now built just right! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.19% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Improve natural language package install parsing' directly and accurately reflects the main change: enhancing the natural-language parser for package installation commands with support for new profiles, typo normalization, and ambiguity handling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sonarqubecloud
Copy link
Copy Markdown

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 natural language processing capabilities for package installation requests, allowing the agent to handle descriptive goals like "set up machine learning" or "I need a web server." It includes a normalization layer to handle common typos and adds a clarification mechanism for ambiguous requests. Feedback focuses on refining the heuristic matching logic to avoid false positives with removal commands, narrowing the "ml" keyword check to avoid matching substrings in unrelated words, and optimizing string processing within loops to reduce unnecessary allocations.

Comment on lines +243 to +251
let is_install_request = input.contains("install")
|| input.contains("set up")
|| input.contains("setup")
|| input.contains("i need")
|| input.contains("something for");

if !is_install_request {
return None;
}
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.

high

The is_install_request logic is prone to false positives because input.contains("install") matches "uninstall", and generic phrases like "i need" or "something for" don't distinguish between installation and removal. For example, "uninstall nginx" or "I need to remove docker" would incorrectly trigger the natural language installation profiles. Consider explicitly excluding removal intent.

Suggested change
let is_install_request = input.contains("install")
|| input.contains("set up")
|| input.contains("setup")
|| input.contains("i need")
|| input.contains("something for");
if !is_install_request {
return None;
}
let is_removal = input.contains("uninstall") || input.contains("remove");
let is_install_request = (input.contains("install")
|| input.contains("set up")
|| input.contains("setup")
|| input.contains("i need")
|| input.contains("something for")) && !is_removal;
if !is_install_request {
return None;
}

});
}

if input.contains("machine learning") || input.contains("ml") {
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.

high

The check input.contains("ml") is too broad and will trigger for any word containing these characters, such as "yaml", "html", "compiler", or "xml". This leads to incorrect triggering of the machine learning profile. Use a word-boundary check or verify that "ml" exists as a standalone word in the input.

Suggested change
if input.contains("machine learning") || input.contains("ml") {
if input.contains("machine learning") || input.split_whitespace().any(|w| w == "ml") {

let package = words
.iter()
.skip_while(|&w| w.to_lowercase() != "install")
.skip_while(|&w| normalize_package_request(w).to_lowercase() != "install")
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

Calling normalize_package_request(w) inside a loop is inefficient as it performs multiple string allocations, splitting, and joining for every word in the input. Since you only need to check if the word represents an 'install' command, a lighter word-level check is preferred.

                .skip_while(|&w| {
                    let w_lower = w.to_lowercase();
                    let trimmed = w_lower.trim_matches(|c: char| !c.is_alphanumeric() && c != '-');
                    !matches!(trimmed, "install" | "instal" | "isntall" | "isntal")
                })

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (2)
wezterm-gui/src/agents/runtime.rs (2)

197-197: ⚡ Quick win

Consider broader pattern matching for Python-related requests.

The phrase "i need python" is highly specific and won't match reasonable variations like "i want python", "i require python", or "need python". Consider adding a few more common variations to make the natural-language detection more robust and user-friendly.

🔍 Suggested broader patterns
     || input.contains("python development")
     || input.contains("i need python")
+    || input.contains("i want python")
+    || input.contains("need python")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wezterm-gui/src/agents/runtime.rs` at line 197, The literal check
input.contains("i need python") is too narrow; replace it with a
case-insensitive pattern match that catches common variants (e.g. "need",
"want", "require", "install") near "python". For example, convert the input to
lowercase or use a Regex (e.g.
r"(?i)\b(?:need|want|require|install)\b.*\bpython\b" or
r"(?i)\bpython\b.*\b(?:need|want|require|install)\b") and use Regex::is_match or
input.to_lowercase().contains with multiple tokens; update the condition that
currently uses input.contains("i need python") to this broader check and add the
regex crate import if you opt for Regex.

190-196: ⚡ Quick win

Add comment explaining the intent of these keyword additions.

The coding guidelines specify that comments should explain WHY. Consider adding a brief comment above this block explaining that these keywords support natural-language package installation requests, including typo tolerance ("instal") and thematic profiles ("machine learning", "web server", etc.). As per coding guidelines, comments should explain WHY, never WHAT or HOW.

📝 Example comment
 // Package agent keywords
+// Extended to support natural-language installation requests and common typos
+// per cxlinux-ai/cx-distro#25
 if input.contains("package")
     || input.contains("install")
     || input.contains("instal")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wezterm-gui/src/agents/runtime.rs` around lines 190 - 196, Add a brief
comment above the series of input.contains checks explaining WHY these specific
keywords are included: they enable natural-language detection of package
installation or environment setup requests (including common typos like "instal"
and broader thematic profiles such as "machine learning" or "web server") so the
agent can map user intent to package actions; place the comment immediately
above the block containing the input.contains(...) checks referencing "input" so
future readers understand the intent rather than the mechanics.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@wezterm-gui/src/agents/package.rs`:
- Around line 268-277: The package vectors (e.g., the packages: vec![ "python3",
"python3-pip", "python3-venv", ... ]) and the profile lists are using apt-style
names but are passed unchanged to other managers (pacman/dnf/brew/nix), which
will break; replace these hard-coded apt names with abstract package keys and
implement a translation layer that maps each abstract key to the correct package
name per package manager (APT, DNF, Pacman, Homebrew, Nix), add special handling
for Nix to use attribute names rather than apt strings, and call that translator
wherever the "packages" vec or profile package lists are used (e.g., the code
that constructs install commands) so the install commands use manager-specific
names.
- Around line 447-452: The code builds a shell command from packages (packages,
package_list) without validating identifiers which risks injection; before
creating cmd_str based on self.package_manager, validate each package name
against a strict allow-list (e.g., a regex that permits only expected characters
like ASCII alphanumerics, hyphen, underscore, dot—and optionally version
separators) and reject any package that fails by returning AgentResponse::error
with a clear message; apply this check to the packages vector before
packages.join(" ") and ensure different package manager flavors
(self.package_manager) enforce any manager-specific constraints.
- Around line 265-266: The substring check input.contains("ml") is too broad and
causes false positives (e.g., matching "xml"); update the matching logic in the
branch that returns PackageCommand::NaturalInstall to only match standalone
tokens for "ml" (and case-insensitive variants) — for example, split or tokenize
the input or use a word-boundary regex to check for "\bml\b" (or equivalent)
instead of contains("ml"), keeping the existing check for "machine learning" and
using the same variable names (input and PackageCommand::NaturalInstall).
- Around line 119-121: The natural-language parser parse_natural_install
currently runs before explicit install handling and preempts commands like
"install docker-compose"; fix this by ensuring explicit install parsing runs
first (or by adding a guard in parse_natural_install to ignore inputs that begin
with "install " or match the explicit install pattern). Concretely, either move
the parse_natural_install(input, &input_lower) call to after the explicit
install parse function (the code path that handles "install <package>") or
update parse_natural_install to check input/input_lower and return None when the
string starts with "install " (or otherwise matches the explicit-install
syntax), so explicit installs are parsed correctly.

---

Nitpick comments:
In `@wezterm-gui/src/agents/runtime.rs`:
- Line 197: The literal check input.contains("i need python") is too narrow;
replace it with a case-insensitive pattern match that catches common variants
(e.g. "need", "want", "require", "install") near "python". For example, convert
the input to lowercase or use a Regex (e.g.
r"(?i)\b(?:need|want|require|install)\b.*\bpython\b" or
r"(?i)\bpython\b.*\b(?:need|want|require|install)\b") and use Regex::is_match or
input.to_lowercase().contains with multiple tokens; update the condition that
currently uses input.contains("i need python") to this broader check and add the
regex crate import if you opt for Regex.
- Around line 190-196: Add a brief comment above the series of input.contains
checks explaining WHY these specific keywords are included: they enable
natural-language detection of package installation or environment setup requests
(including common typos like "instal" and broader thematic profiles such as
"machine learning" or "web server") so the agent can map user intent to package
actions; place the comment immediately above the block containing the
input.contains(...) checks referencing "input" so future readers understand the
intent rather than the mechanics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: db534c06-525e-428a-a30f-9fdd04b2b552

📥 Commits

Reviewing files that changed from the base of the PR and between bf87c78 and 74d923b.

📒 Files selected for processing (2)
  • wezterm-gui/src/agents/package.rs
  • wezterm-gui/src/agents/runtime.rs

Comment on lines +119 to +121
if let Some(command) = parse_natural_install(input, &input_lower) {
return command;
}
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Natural-language parsing currently preempts explicit install <package> commands.

Running parse_natural_install before explicit install parsing causes regressions like install docker-compose being interpreted as a profile instead of a direct package install.

Suggested fix
-        if let Some(command) = parse_natural_install(input, &input_lower) {
-            return command;
-        }
-
         // Install
         if input_lower.contains("install") {
             let package = words
                 .iter()
                 .skip_while(|&w| normalize_package_request(w).to_lowercase() != "install")
                 .nth(1)
                 .map(|s| s.to_string())
                 .or_else(|| words.last().map(|s| s.to_string()))
                 .unwrap_or_default();
             return Self::Install { package };
         }
+
+        if let Some(command) = parse_natural_install(input, &input_lower) {
+            return command;
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if let Some(command) = parse_natural_install(input, &input_lower) {
return command;
}
// Install
if input_lower.contains("install") {
let package = words
.iter()
.skip_while(|&w| normalize_package_request(w).to_lowercase() != "install")
.nth(1)
.map(|s| s.to_string())
.or_else(|| words.last().map(|s| s.to_string()))
.unwrap_or_default();
return Self::Install { package };
}
if let Some(command) = parse_natural_install(input, &input_lower) {
return command;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wezterm-gui/src/agents/package.rs` around lines 119 - 121, The
natural-language parser parse_natural_install currently runs before explicit
install handling and preempts commands like "install docker-compose"; fix this
by ensuring explicit install parsing runs first (or by adding a guard in
parse_natural_install to ignore inputs that begin with "install " or match the
explicit install pattern). Concretely, either move the
parse_natural_install(input, &input_lower) call to after the explicit install
parse function (the code path that handles "install <package>") or update
parse_natural_install to check input/input_lower and return None when the string
starts with "install " (or otherwise matches the explicit-install syntax), so
explicit installs are parsed correctly.

Comment on lines +265 to +266
if input.contains("machine learning") || input.contains("ml") {
return Some(PackageCommand::NaturalInstall {
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

"ml" substring matching is too broad and causes false positives.

input.contains("ml") will match unrelated tokens (e.g., xml), incorrectly selecting the machine-learning profile.

Suggested fix
-    if input.contains("machine learning") || input.contains("ml") {
+    let tokens: std::collections::HashSet<&str> = input.split_whitespace().collect();
+    if input.contains("machine learning") || tokens.contains("ml") {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if input.contains("machine learning") || input.contains("ml") {
return Some(PackageCommand::NaturalInstall {
let tokens: std::collections::HashSet<&str> = input.split_whitespace().collect();
if input.contains("machine learning") || tokens.contains("ml") {
return Some(PackageCommand::NaturalInstall {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wezterm-gui/src/agents/package.rs` around lines 265 - 266, The substring
check input.contains("ml") is too broad and causes false positives (e.g.,
matching "xml"); update the matching logic in the branch that returns
PackageCommand::NaturalInstall to only match standalone tokens for "ml" (and
case-insensitive variants) — for example, split or tokenize the input or use a
word-boundary regex to check for "\bml\b" (or equivalent) instead of
contains("ml"), keeping the existing check for "machine learning" and using the
same variable names (input and PackageCommand::NaturalInstall).

Comment on lines +268 to +277
packages: vec![
"python3",
"python3-pip",
"python3-venv",
"python3-numpy",
"python3-scipy",
"python3-pandas",
"python3-sklearn",
"jupyter-notebook",
]
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.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Natural-install package lists are distro-specific but executed across all package managers.

Profiles use apt-style names (python3-venv, build-essential, docker.io) and are passed directly to pacman/dnf/brew/nix commands. This will fail on non-apt systems and is especially fragile for Nix attribute installs.

Also applies to: 293-299, 311-312, 452-466

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wezterm-gui/src/agents/package.rs` around lines 268 - 277, The package
vectors (e.g., the packages: vec![ "python3", "python3-pip", "python3-venv", ...
]) and the profile lists are using apt-style names but are passed unchanged to
other managers (pacman/dnf/brew/nix), which will break; replace these hard-coded
apt names with abstract package keys and implement a translation layer that maps
each abstract key to the correct package name per package manager (APT, DNF,
Pacman, Homebrew, Nix), add special handling for Nix to use attribute names
rather than apt strings, and call that translator wherever the "packages" vec or
profile package lists are used (e.g., the code that constructs install commands)
so the install commands use manager-specific names.

Comment on lines +447 to 452
if packages.is_empty() || packages.iter().any(|p| p.trim().is_empty()) {
return AgentResponse::error("No package name was provided".to_string());
}

let package_list = packages.join(" ");
let cmd_str = match self.package_manager {
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate package identifiers with an allow-list before command construction.

packages.join(" ") is used to build executable command text without character allow-list validation. Add strict package-name validation before command generation.

Suggested fix
     fn install_packages(
         &self,
         packages: &[String],
         confidence: Option<u8>,
         reasoning: Option<&str>,
         query: Option<&str>,
     ) -> AgentResponse {
         if packages.is_empty() || packages.iter().any(|p| p.trim().is_empty()) {
             return AgentResponse::error("No package name was provided".to_string());
         }
+        if packages
+            .iter()
+            .any(|p| !p.chars().all(|c| c.is_ascii_alphanumeric() || c == '+' || c == '.' || c == '-' || c == '_'))
+        {
+            return AgentResponse::error("Invalid package name format".to_string());
+        }
 
         let package_list = packages.join(" ");

As per coding guidelines, "Use allow-lists for input validation to prevent injection attacks".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if packages.is_empty() || packages.iter().any(|p| p.trim().is_empty()) {
return AgentResponse::error("No package name was provided".to_string());
}
let package_list = packages.join(" ");
let cmd_str = match self.package_manager {
if packages.is_empty() || packages.iter().any(|p| p.trim().is_empty()) {
return AgentResponse::error("No package name was provided".to_string());
}
if packages
.iter()
.any(|p| !p.chars().all(|c| c.is_ascii_alphanumeric() || c == '+' || c == '.' || c == '-' || c == '_'))
{
return AgentResponse::error("Invalid package name format".to_string());
}
let package_list = packages.join(" ");
let cmd_str = match self.package_manager {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wezterm-gui/src/agents/package.rs` around lines 447 - 452, The code builds a
shell command from packages (packages, package_list) without validating
identifiers which risks injection; before creating cmd_str based on
self.package_manager, validate each package name against a strict allow-list
(e.g., a regex that permits only expected characters like ASCII alphanumerics,
hyphen, underscore, dot—and optionally version separators) and reject any
package that fails by returning AgentResponse::error with a clear message; apply
this check to the packages vector before packages.join(" ") and ensure different
package manager flavors (self.package_manager) enforce any manager-specific
constraints.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enhances the wezterm-gui package agent’s natural-language parsing so user intents like “set up python development” or typo’d install requests map to richer install actions (profiles, clarification prompts), with accompanying unit tests.

Changes:

  • Expanded agent keyword inference to route more natural-language install intents to the package agent.
  • Added NaturalInstall and Clarify command variants, plus request normalization and profile-based parsing.
  • Updated install handling to support installing multiple packages and to display reasoning/confidence for profile installs; added new parser unit tests.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
wezterm-gui/src/agents/runtime.rs Extends keyword-based agent inference to better route install/setup requests to the package agent.
wezterm-gui/src/agents/package.rs Adds normalization + natural-language profile parsing, new command variants, multi-package install formatting, and new unit tests.
Comments suppressed due to low confidence (2)

wezterm-gui/src/agents/package.rs:312

  • The PR description mentions adding a Kubernetes install profile, but the only Kubernetes-related profile here requires both "docker" and "kubernetes". A request like "install kubernetes" (or typo-normalized "kubernets") will fall back to the generic Install path and likely try to install a non-existent package name. Either add a Kubernetes-only profile (e.g., install kubectl/kubeadm/minikube depending on intent) or adjust the PR description to reflect the actual supported cases.
    if input.contains("docker") && input.contains("kubernetes") {
        return Some(PackageCommand::NaturalInstall {
            query: original.to_string(),
            packages: vec!["docker.io", "docker-compose-plugin", "kubectl"]
                .into_iter()

wezterm-gui/src/agents/package.rs:318

  • New natural-language parsing branches don’t have coverage for Kubernetes-only requests and the documented typo normalization for "kubernets" (without also mentioning Docker). Add unit tests that assert the intended PackageCommand output for inputs like "install kubernetes" and "instal kubernets" so regressions are caught.
    if input.contains("docker") && input.contains("kubernetes") {
        return Some(PackageCommand::NaturalInstall {
            query: original.to_string(),
            packages: vec!["docker.io", "docker-compose-plugin", "kubectl"]
                .into_iter()
                .map(str::to_string)
                .collect(),
            confidence: 82,
            reasoning: "I understood this as container tooling plus the Kubernetes command-line client.".to_string(),
        });
    }

Comment on lines 136 to 140
if input_lower.contains("install") {
let package = words
.iter()
.skip_while(|&w| w.to_lowercase() != "install")
.skip_while(|&w| normalize_package_request(w).to_lowercase() != "install")
.nth(1)
Comment on lines +265 to +266
if input.contains("machine learning") || input.contains("ml") {
return Some(PackageCommand::NaturalInstall {
Comment on lines +266 to +283
return Some(PackageCommand::NaturalInstall {
query: original.to_string(),
packages: vec![
"python3",
"python3-pip",
"python3-venv",
"python3-numpy",
"python3-scipy",
"python3-pandas",
"python3-sklearn",
"jupyter-notebook",
]
.into_iter()
.map(str::to_string)
.collect(),
confidence: 86,
reasoning: "I understood this as a Python-based machine learning workstation setup."
.to_string(),
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.

3 participants