Skip to content

The Natural Language Shell integrates OpenAI's GPTs, Anthropic's Claude, or local GGUF-formatted LLMs directly into the terminal experience, allowing operators to describe their tasks in either POSIX commands or fluent human language

License

mikecvet/nl-sh

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

61 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nl-sh: Natural Language Shell

Introduction

nl-sh stands for Natural Language Shell, a novel approach to interacting with POSIX systems through natural language understanding through LLMs. This project aims to bridge the gap between traditional shell command execution and natural language interpretation, providing a user-friendly interface for executing complex system commands using simple English prompts. This is functional proof-of-concept. nl-sh makes working in terminals more accessible and intuitive, as the shell accepts both traditional POSIX commands as well as human-language instructions for system operations; the best command sequence satisfying that human prompt is provided back to the user for verification before execution.

The point of this shell is to eliminate the tedious manual tasks of googling Stack Overflow or grepping through man pages to figure out the right combination of commands, arguments, pipes and flags to complete complex operations from the command line. This provides a human-centered CLI experience, for those who spend time on *NIX variants but are poorly-versed in the entire command vocabulary.

This is discussed a little further here

Key Features:

  • Can use in any window-based or remote terminal setting, as an overlay on top of the current envionment's shell
  • Accepts either direct system commands, or expressive language-based commands, which are interpreted by an LLM
  • Loads prior shell history (bash, ksh, tcsh, zsh), allows history navigation and updates underlying shell history with executed commands
  • Supports GPT 3.5 Turbo, GPT 4, Claude 2.1, and any locally-available open-source GGUF formatted LLM

I've had some success with Mistral 7B Instruct, and CodeLlama 7B, though they do not work as well as Claude or OpenAI's models. Some other open-source models, such as Llama2 do not work as well at all; often because they're a little too chatty and helpful =)

nl-sh is best demonstrated with some examples (default behavior is to use GPT4 and assume OPENAI_API_KEY is available):

  ~/code/nl-sh ~>> ./target/release/nl-sh --help
  A natural language shell for *NIX systems
  
  Usage: nl-sh [OPTIONS]
  
  Options:
        --gpt4          Use the GPT4 API as a backend, reading from the OPENAI_API_KEY environment variable. Default behavior.
        --gpt35         Use the GPT3.5 Turbo API as a backend, reading from the OPENAI_API_KEY environment variable
        --claude        Use the Anthropic Claude API as a backend (default: Claude 3 Sonnet), reading from the CLAUDE_API_KEY environment variable
        --local <path>  Use a local GGUF-based model as a backend, located at the provided path
        --stateless     Disable update of external shell history (default: false)

  ~/code/nl-sh ~>> ./target/release/nl-sh 
  > [nl-sh] /Users/mike/code/nl-sh $ whoami
  mike
  
  > [nl-sh] /Users/mike/code/nl-sh $ pwd
  /Users/mike/code/nl-sh
  
  > [nl-sh] /Users/mike/code/nl-sh $ ps aux |grep git
  mike             30936   0.0  0.0 408490720    656 s008  R+    9:01AM   0:00.00 grep git
  mike             30934   0.0  0.0 408636976   2416 s008  S+    9:01AM   0:00.01 /bin/zsh -c ps aux |grep git

  > [nl-sh] /Users/mike/code/nl-sh $ copy remote directory /home/mike/log_data on remote host "log-server" to the local machine; store the data in a new directory called "log-server-data"
  > scp -r log-server:/home/mike/log_data log-server-data Yes
  mike@log-server's password: 

  > [nl-sh] /Users/mike/code/nl-sh $ list the contents of the "log-server-data" directory with human-readable file sizes
  > ls -lh log-server-data Yes
  total 953984
  -rw-r--r--  1 mike  staff    82M Feb 13 09:08 0.log
  -rw-r--r--  1 mike  staff    82M Feb 13 09:08 1.log
  -rw-r--r--  1 mike  staff    82M Feb 13 09:08 2.log
  -rw-r--r--  1 mike  staff   163M Feb 13 09:08 3.log

  > [nl-sh] /Users/mike/code/nl-sh $ Which 5 running processes on this machine have consumed the most CPU resources? Sanitize the process names by stripping out flags and pat
  hs where possible. Order the results by descending CPU usage, and ensure their CPU usage is emitted as a column next to the process name
  > ps aux | sort -nrk3 | head -5 | awk '{print $3, $11}' Yes
  
  4.3 /System/Library/PrivateFrameworks/SkyLight.framework/Resources/WindowServer
  2.8 /Applications/Visual
  2.4 /sbin/launchd
  2.3 /System/Applications/Utilities/Activity
  2.1 /Applications/Visual

nl-sh will also make an attempt to correct any failed commands based on a misunderstanding of the native system, or even user error, by collecting command outputs and reasoning about the failure. For example, on a Darwin UNIX system, the operator uses "iptables" as a shorthand for "firewall":

  > [nl-sh] /Users/mike/code/nl-sh $ list all iptables rules on this system
  > sudo iptables -L -v Yes
  Password:
  Executed [sudo iptables -L -v] and got error: sudo: iptables: command not found

  Retrying command formulation...
  > sudo pfctl -sa Yes
  success:
  TRANSLATION RULES:
  nat-anchor "com.apple/*" all
  rdr-anchor "com.apple/*" all

  FILTER RULES:
  scrub-anchor "com.apple/*" all fragment reassemble
  anchor "com.apple/*" all

  DUMMYNET RULES:
  dummynet-anchor "com.apple/*" all
  [...]

Local LLMs sometimes work as well:

  ~/code/nl-sh ~>> ./target/release/nl-sh --local ./mistral-7b-instruct-v0.2.Q8_0.gguf
  > [nl-sh] /Users/mike/code/nl-sh $ show me the top 3 largest files in the current directory, in human-readable size format
  > du -ah | grep gguf | sort -rh | head -n 3 Yes
   32G	./gemma-7b.gguf
  9.3G	./gemma-2b.gguf
  8.5G	./gemma-7b-it-Q8_0.gguf (Y/n)

Here's a video demonstration:

nl-sh

Another demonstrating automatic command reformulation upon error:

nl-sh

How does this work?

nl-sh acts like a (minimal) shell by wrapping the underlying shell with a prompt which accepts and executes text inputs from the user. Inputs which seem like actual POSIX commands are directly executed; otherwise the input is directed to an LLM to interpret the input and provide a command sequence satisfying the request, customized for the local system powering the shell. This shell collects some environmental data such as kernel and OS version details to try and generate the most accurate command-line sequence for the given POSIX variant.

Any commands suggested by the backing LLM and then executed through nl-sh are written to the user's underlying shell command-history file.

TODO

  • Test local models through ollama bindings as compared to llama.cpp-rs
  • Respect underlying shell color configurations for ls and related outputs
  • Figure out how to support output-rewriting for commands such as top
  • Build reverse-incremental history search (for example, cmd-r)
  • Support pagination of lengthy outputs (ie piping through more or eqiuvalent

About

The Natural Language Shell integrates OpenAI's GPTs, Anthropic's Claude, or local GGUF-formatted LLMs directly into the terminal experience, allowing operators to describe their tasks in either POSIX commands or fluent human language

Topics

Resources

License

Stars

Watchers

Forks

Languages