AI-powered web search CLI with LLM tool-calling capabilities
Project description
asky is an AI-powered web search CLI with LLM tool-calling capabilities.
It (can be invoked as asky or ask) provides a powerful command-line interface that brings AI-powered search and research capabilities directly to your terminal. It uses LLMs and tools to synthesize answers from the web (or from files and cli commands you expose as tools).
Key Features
- Multi-Model Support: Easily define and switch between various LLMs and providers that supports OpenAI compatible API.
- Tool-Calling Integration: Models can autonomously perform web searches (via SearXNG or Serper API), fetch URL content, and get current date/time to provide accurate, up-to-date answers.
- Custom Tools: Expose any CLI command as a tool for the LLM. Define your own commands and parameters in
config.toml. - Intelligent Content Fetching: Automatically strips HTML noise (scripts, styles) to provide clean text context to the models. It can also summarize the content of the URLs and use the summaries for chat context.
- Conversation History: Maintains a local SQLite database of your queries and answers (with their summaries), allowing for context-aware follow-up questions.
- Deep Research Mode: Automatically performs multiple searches to provide comprehensive analysis of complex topics.
- Deep Dive Mode: Allows models to recursively explore the links found on web pages for in-depth information gathering.
- Predefined Prompts: Users can define and quickly invoke common prompt patterns using simple slashes (e.g.,
/gnfor get latest news from The Guardian). - Clipboard Integration: Use
/cpto expand the query with clipboard content. - Token Efficient: It counts token usage and keep the model informed about remaining context capacity to encourage it to finish the task before hitting the limit. Together with summaries, this makes asky very token efficient.
How it Works
- User Query: You provide a query to the
askycommand. - Model Selection: asky initializes the selected LLM based on your configuration.
- Tool Loop: The LLM analyzes your query. If it needs real-world data, it calls integrated tools (like
web_search). - Context Synthesis: asky fetches the data, cleans it, and feeds it back to the LLM. This process can repeat for up to 15 turns for complex research.
- Final Answer: The LLM synthesizes all gathered information into a concise, formatted response.
- Persistence: The interaction is saved to your local history for future reference.
Installation
pip install asky-cli
Or install from source:
pip install -e .
Usage
# Basic query
asky what is the weather in Berlin
# Continue from previous query (by ID)
asky -c 1 tell me more about that
# Continue from last query (relative ID)
asky -c~1 explain more
# OR
asky -c "~2" what about the one before that?
> [!NOTE]
> **Zsh Users**: When using `~` for relative IDs, you must either quote the value (e.g., `asky -c "~1"`) or place it immediately after the flag without a space (e.g., `asky -c~1`). If you use a space without quotes (e.g., `asky -c ~1`), zsh will attempt to expand it as a directory stack entry.
➜ ~ asky -p
=== USER PROMPTS ===
/gn : Give me latest news from The Guardian, use https://www.theguardian.com/europe
/wh : how is weather in
====================
➜ ~ asky /wh delft
Dispatching tool call: web_search with args {'q': 'weather in Delft'}
Dispatching tool call: get_url_content with args {'urls': ...}
The weather in **Delft, South Holland, Netherlands** is currently **45°F and Cloudy with Showers in the Vicinity** (as of 4:20 pm CET).
Here is the forecast for today and the next couple of days:
...
Query completed in 3.88 seconds
--------------------------------------------------------------------------------
➜ ~ asky --help
usage: asky [-h] [-m {gf,glmair,glmflash,q34t,q34,lfm,q8,q30,onano,omini}] [-d [DEEP_RESEARCH]] [-dd] [-c CONTINUE_IDS] [-s] [-fs] [--cleanup-db [CLEANUP_DB]] [--all]
[-H [HISTORY]] [-pa PRINT_IDS] [-p] [-v]
[query ...]
Tool-calling CLI with model selection.
positional arguments:
query The query string
options:
-h, --help show this help message and exit
-m, --model {gf,glmair,glmflash,q34t,q34,lfm,q8,q30,onano,omini}
Select the model alias
-d, --deep-research [DEEP_RESEARCH]
Enable deep research mode (optional: specify min number of queries, default 5)
-dd, --deep-dive Enable deep dive mode (extracts links and encourages reading more pages from same domain)
-c, --continue-chat CONTINUE_IDS
Continue conversation with context from specific history IDs (comma-separated, e.g. '1,2').
-s, --summarize Enable summarize mode (summarizes URL content and uses summaries for chat context)
-fs, --force-search Force the model to use web search (default: False).
Helpful for avoiding hallucinations with small models
--cleanup-db [CLEANUP_DB]
Delete history records. usage: --cleanup-db [ID|ID-ID|ID,ID] or --cleanup-db --all
--all Used with --cleanup-db to delete ALL history.
-H, --history [HISTORY]
Show last N queries and answer summaries (default 10).
Use with --print-answer to print the full answer(s).
-pa, --print-answer PRINT_IDS
Print the answer(s) for specific history IDs (comma-separated).
-p, --prompts List all configured user prompts.
-v, --verbose Enable verbose output (prints config and LLM inputs).
Deep research mode (encourages model to perform multiple searches)
asky -d 5 comprehensive analysis of topic
Deep dive mode (encourages model to read multiple pages from same domain)
asky -dd https://example.com
Use a specific model
asky -m gf what is quantum computing
Force web search
asky -fs latest news on topic
Pre-configured model definitions
Followin model definitions ship with default config.toml, but you can add any number of models that are served with an OpenAI compatible API.
gf- Google Gemini Flash (default)lfm- Liquid LFM 2.5q8- Qwen3 8Bq30- Qwen3 30Bq34- Qwen3 4Bq34t- Qwen3 4B Thinking
Custom Tools
You can define your own tools in config.toml that the LLM can use to interact with your local system. Each tool runs a CLI command and returns the output to the LLM.
Example configuration for a list_dir tool:
[tool.list_dir]
command = "ls"
description = "List the contents of a directory."
[tool.list_dir.parameters]
type = "object"
required = ["path"]
[tool.list_dir.parameters.properties.path]
type = "string"
default = "."
Example configuration for a grep_search tool:
[tool.grep_search]
command = "grep -r {pattern} {path}"
description = "Search for a pattern in files recursively."
[tool.grep_search.parameters]
type = "object"
required = ["pattern"]
[tool.grep_search.parameters.properties.pattern]
type = "string"
description = "The regex pattern to search for."
[tool.grep_search.parameters.properties.path]
type = "string"
description = "The directory path to search in."
default = "."
[!CAUTION] Security Risk: Custom tools execute commands using your system shell. While asky attempts to quote arguments safely, exposing powerful CLI tools to an LLM can be risky. Use this feature with caution.
How it works:
- Placeholders: Use
{param_name}in thecommandstring to inject arguments. If no placeholders are found, arguments are appended to the command. - Quoting: All arguments are automatically cleaned (inner double-quotes removed) and wrapped in double-quotes for safety.
- Execution: Commands are executed via terminal shell, allowing for advanced piping and redirection.
[!TIP] Performance Tip: When using recursive tools like
grep, consider excluding large directories like.venvornode_modulesto avoid timeouts:command = "grep -r --exclude-dir={.venv,node_modules} {pattern} {path}"
[!NOTE] Optional Parameters: If you define a parameter with a
defaultvalue inconfig.toml, it will be automatically injected into yourcommandif the LLM omits it.
Configuration options
On first run, a default configuration file is created at ~/.config/asky/config.toml. You can edit this file to configure models, API keys, and other settings.
API Keys
You can set API keys in two ways:
- Environment Variables: Set
GOOGLE_API_KEY(or other configured env vars) in your shell. - Config File: Add keys directly to
[api.name]sections inconfig.toml.
Example config.toml:
[general]
default_model = "gf"
[api.gemini]
api_key_env = "GOOGLE_API_KEY"
[api.lmstudio]
url = "http://localhost:1234/v1/chat/completions"
Verification
Run with -v to see the loaded configuration:
asky -v
Web Search
asky works best with a web search tool. You can use SearXNG or Serper API.
Serper API
Serper is a paid service, but gives 2500 requests for free.
Install & configure SearXNG
SearXNG is free and open source, it's easy to set up with a single docker command.
Following command taken from SearXNG docs.
docker pull docker.io/searxng/searxng:latest
# Create directories for configuration and persistent data
$ mkdir -p ./searxng/config/ ./searxng/data/
$ cd ./searxng/
# Run the container
$ docker run --name searxng -d \
-p 8888:8080 \
-v "./config/:/etc/searxng/" \
-v "./data/:/var/cache/searxng/" \
docker.io/searxng/searxng:latest
You need to add "-json" to the formats section of the default searxng config.yaml file.
# remove format to deny access, use lower case.
# formats: [html, csv, json, rss]
formats:
- html
- json
Then restart the container.
docker restart searxng
Requirements
- Python 3.10+
- Running SearXNG instance or Serper API key.
- LM Studio (for local models) or API keys for remote models
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file asky_cli-0.1.7.tar.gz.
File metadata
- Download URL: asky_cli-0.1.7.tar.gz
- Upload date:
- Size: 7.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0c3da17b7db2bc3b370fb0c8bc04882e3ecf952f9c8e6222c40179aa00ccf1f
|
|
| MD5 |
d3eb40e08319df02845ba5414a2d732e
|
|
| BLAKE2b-256 |
bbe29e4b2c9a57a528089f84a16877f78537160d0c1cf344f91e4fc2a3b74a44
|
File details
Details for the file asky_cli-0.1.7-py3-none-any.whl.
File metadata
- Download URL: asky_cli-0.1.7-py3-none-any.whl
- Upload date:
- Size: 45.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
444c346ea3faf70aae94a5bbe3b6930fc077a78b2883f583580f4cdce2413de3
|
|
| MD5 |
0c58ad03b820e7d7bc06edb7115fb1e0
|
|
| BLAKE2b-256 |
5ddfe26d87ae257c017c8501a0adbb1a41d07c50afbd20158de069cbb1234444
|