Skip to content

Instantly share code, notes, and snippets.

@moisoto
Forked from nachoal/t2c.zsh
Last active December 11, 2024 03:32
Show Gist options
  • Save moisoto/53a164ae1bb6875345e376882819c23f to your computer and use it in GitHub Desktop.
Save moisoto/53a164ae1bb6875345e376882819c23f to your computer and use it in GitHub Desktop.
Text-to-Command (t2c): Convert natural language to shell commands using Ollama LLMs A zsh function that converts natural language queries into shell commands using Ollama's local API. Ask for commands in plain English, review them before execution. Customizable to use any Ollama model. Example: t2c list all python files modified in the last week
#!/bin/zsh
# Function to convert natural language queries into Unix commands using Ollama's API
# Usage: t2c list files in current folder
# Requirements: curl, jq, and Ollama running locally on port 11434
# Remember to run the command: source t2c.zsh
# in order for the command t2c to be available in your current shell session
t2c() {
# Store the entire command argument as the user's query
user_query="$*"
# Construct the prompt for the LLM to convert the query to a command
# The prompt specifically requests a single executable Unix command
prompt_content="Convert the following user query into a SINGLE Unix command that can be executed: \"$user_query\""
# Construct the JSON payload for Ollama's API using jq
# Note: You can change "HammerAI/hermes-3-llama-3.1" to any other model available in your Ollama installation
json_payload="$(jq -n \
--arg model "HammerAI/hermes-3-llama-3.1" \
--arg prompt "$prompt_content" \
'{
"model": $model,
"messages": [{"role":"user","content":$prompt}],
"stream": false,
# Format specification ensures the model returns a structured response
# with a "command" field containing the Unix command
"format": {
"type": "object",
"properties": {
"command": {"type":"string"}
},
"required": ["command"]
}
}')"
# Make POST request to Ollama's local API endpoint
# Default port is 11434 - ensure Ollama is running and this port is available
response_json=$(curl -s -X POST http://localhost:11434/api/chat \
-H "Content-Type: application/json" \
-d "$json_payload")
# Validate that the response is valid JSON
# If not, display error message and the invalid response
if ! echo "$response_json" | jq . >/dev/null 2>&1; then
echo "Error: Received invalid JSON from API"
echo "Response was:"
echo "$response_json"
return 1
fi
# Extract the command from the nested JSON response
# The command is nested within message.content as a JSON string that needs to be parsed
command_to_run="$(echo "$response_json" | jq -r '.message.content | fromjson | .command')"
# Validate that we got a non-empty command
# If empty or null, show error and raw response for debugging
if [ -z "$command_to_run" ] || [ "$command_to_run" = "null" ]; then
echo "No valid command returned."
echo "Raw response:"
echo "$response_json"
return 1
fi
# Show the generated command and ask for user confirmation
echo "The command is: $command_to_run"
echo -n "Would you like to put it on the command line? [Y/N] "
read -r confirm
# If user confirms, place the command in the shell's command buffer
# This allows the user to review/edit the command before execution
if [[ "$confirm" =~ ^[Yy](es)?$ ]]; then
# Uses zsh's print -z to place the command in the command buffer
# Note: This feature is specific to zsh shell
print -z "$command_to_run"
echo "Command placed on command line. You can edit it before pressing Enter."
else
echo "Aborted."
fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment