sigoden/aichat
All-in-one LLM CLI tool featuring Shell Assistant, Chat-REPL, RAG, AI Tools & Agents, with access to OpenAI, Claude, Gemini, Ollama, Groq, and more.
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2mo ago
- ✓13 active contributors
- ✓Apache-2.0 licensed
Show all 6 evidence items →Show less
- ✓CI configured
- ⚠Single-maintainer risk — top contributor 87% of recent commits
- ⚠No test directory detected
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/sigoden/aichat)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/sigoden/aichat on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: sigoden/aichat
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/sigoden/aichat shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit 2mo ago
- 13 active contributors
- Apache-2.0 licensed
- CI configured
- ⚠ Single-maintainer risk — top contributor 87% of recent commits
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live sigoden/aichat
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/sigoden/aichat.
What it runs against: a local clone of sigoden/aichat — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in sigoden/aichat | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 103 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of sigoden/aichat. If you don't
# have one yet, run these first:
#
# git clone https://github.com/sigoden/aichat.git
# cd aichat
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of sigoden/aichat and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "sigoden/aichat(\\.git)?\\b" \\
&& ok "origin remote is sigoden/aichat" \\
|| miss "origin remote is not sigoden/aichat (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "src/main.rs" \\
&& ok "src/main.rs" \\
|| miss "missing critical file: src/main.rs"
test -f "src/cli.rs" \\
&& ok "src/cli.rs" \\
|| miss "missing critical file: src/cli.rs"
test -f "src/client/mod.rs" \\
&& ok "src/client/mod.rs" \\
|| miss "missing critical file: src/client/mod.rs"
test -f "src/config/mod.rs" \\
&& ok "src/config/mod.rs" \\
|| miss "missing critical file: src/config/mod.rs"
test -f "src/repl/mod.rs" \\
&& ok "src/repl/mod.rs" \\
|| miss "missing critical file: src/repl/mod.rs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 103 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~73d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/sigoden/aichat"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
AIChat is a unified CLI tool that provides a single interface to interact with 20+ LLM providers (OpenAI, Claude, Gemini, Ollama, Groq, etc.) through multiple modes: a shell assistant that converts natural language to shell commands, a Chat-REPL with tab completion and history, and a CMD mode for one-off queries. It supports multi-form input (stdin, files, directories, URLs) and features RAG, AI tools, and agent capabilities—solving the friction of switching between different provider CLIs and integrating LLMs into shell workflows. Monolithic binary architecture: src/cli.rs is the entry point, src/client/ (with subdirectories for each provider: openai.rs, claude.rs, bedrock.rs, gemini.rs, azure_openai.rs, etc.) handles provider-specific protocol logic, and src/client/common.rs and stream.rs contain shared abstractions. Assets (assets/roles/, assets/syntaxes.bin, theme files) are embedded for the REPL and shell assistant features. Shell integration scripts in scripts/ enable terminal-specific functionality (bash, zsh, fish, nushell, powershell).
👥Who it's for
DevOps engineers and developers who want to quickly invoke any LLM from the terminal without context-switching to web interfaces or managing separate CLI tools for each provider; also power users building shell automation who want to enhance their scripts with AI capabilities. Contributors are Rust developers interested in async systems, LLM integrations, and cross-platform CLI tooling.
🌱Maturity & risk
Actively developed and production-ready. The project is at v0.30.0 with organized CI/CD workflows (ci.yaml, release.yaml in .github/workflows), multi-platform release automation, and comprehensive language support (543K lines of Rust). However, the 0.x version suggests some API stability is still evolving; the presence of example configs (config.example.yaml, config.agent.example.yaml) and shell integration scripts indicates mature deployment patterns.
Medium risk: the dependency footprint is substantial (tokio, reqwest, hyper, serde ecosystem, AWS SDK components like aws-smithy-eventstream) creating a broader attack surface, but all are well-maintained crates. Single maintainer (sigoden) is a concern for long-term sustainability. The 0.x versioning means breaking changes can occur between releases. The codebase relies heavily on async/await patterns and stream handling, which can be fragile if not tested comprehensively.
Active areas of work
The repo is being actively maintained with version 0.30.0 released. The presence of multiple client provider implementations (claude.rs, bedrock.rs, cohere.rs, gemini.rs, openai_compatible.rs) suggests ongoing expansion of provider support. The inclusion of RAG-related configuration (config.agent.example.yaml) and agent capabilities indicates feature development beyond basic chat.
🚀Get running
# Clone the repository
git clone https://github.com/sigoden/aichat.git
cd aichat
# Install via Cargo (requires Rust 1.70+)
cargo build --release
# Or install directly
cargo install aichat
# Verify installation
./target/release/aichat --version
Daily commands:
# Development mode with logs
RUST_LOG=debug cargo run -- --help
# Interactive REPL mode
cargo run
# CMD mode (one-off query)
cargo run -- "Explain this code: fn main() {}"
# With file input
cargo run -- -f README.md "Summarize this file"
🗺️Map of the codebase
src/main.rs— Entry point orchestrating CLI setup, mode selection (REPL/Shell/Serve), and main application flow—essential for understanding initialization.src/cli.rs— CLI argument parsing and command routing using clap derive macro—defines all user-facing interface contracts.src/client/mod.rs— Abstract LLM client interface and provider router dispatching to 20+ backend implementations—core abstraction layer.src/config/mod.rs— Configuration loading and merging (YAML/JSON) for models, roles, agents, and sessions—source of truth for runtime behavior.src/repl/mod.rs— REPL loop implementation with reedline completion and streaming response handling—primary interactive mode.src/client/stream.rs— Token streaming abstraction across heterogeneous LLM providers with buffering and event parsing.Cargo.toml— Dependency manifest defining tokio async runtime, serde for serialization, and reedline for terminal UI.
🛠️How to make changes
Add a New LLM Provider
- Create new provider module file (e.g., src/client/myprovider.rs) implementing Client trait with request/streaming methods. (
src/client/myprovider.rs) - Add provider variant to ClientConfig enum and instantiate in Client::new() router in src/client/mod.rs. (
src/client/mod.rs) - Add provider-specific model definitions to models.yaml with credentials/endpoint configuration. (
models.yaml) - Implement request building and token streaming using src/client/stream.rs utilities for common patterns. (
src/client/stream.rs) - Add integration test in CI workflow and document in README.md Features section. (
.github/workflows/ci.yaml)
Add a New Role (System Prompt Template)
- Create markdown file in assets/roles/ following naming convention (e.g., %myrole%.md) with system prompt and optional metadata. (
assets/roles/%myrole%.md) - Load role at runtime via src/config/role.rs which reads from assets/roles/ directory. (
src/config/role.rs) - Register role in config.example.yaml and update CLI help text in src/cli.rs. (
config.example.yaml)
Add an Agent with Tools
- Define tool schema and execution logic in src/function.rs function registry. (
src/function.rs) - Create agent config in config.agent.example.yaml with tool bindings and model selection. (
config.agent.example.yaml) - Load and bind agent in src/config/agent.rs, parsing tool definitions. (
src/config/agent.rs) - Add agent invocation in REPL/CLI via src/cli.rs --agent flag routing. (
src/cli.rs)
Extend RAG Knowledge Base
- Add document files to a knowledge base directory (auto-discovered or configured in config.yaml). (
src/rag/mod.rs) - Configure embedding model and vector store backend in src/config/mod.rs. (
src/config/mod.rs) - Customize text splitting strategy in src/rag/splitter/mod.rs for your document types. (
src/rag/splitter/mod.rs) - Invoke RAG queries in client message building logic to inject context before LLM call. (
src/client/mod.rs)
🔧Why these technologies
- Tokio async runtime — Enables non-blocking I/O for streaming LLM responses and concurrent HTTP requests across multiple providers without thread overhead.
- Reedline REPL library — Provides terminal editing, command history, syntax highlighting, and completion—critical for responsive interactive chat sessions.
- Serde + YAML/JSON — Declarative configuration (models.yaml, config.yaml, roles) allows users to add providers and roles without code recompilation.
- Reqwest HTTP client — Unified async HTTP layer abstracts away provider-specific networking details while supporting streaming bodies.
- Clap CLI framework — Derive-based argument parsing reduces boilerplate and auto-generates help/completion scripts across shells.
⚖️Trade-offs already made
-
Provider abstraction via trait Client instead of unified API wrapper
- Why: Providers (OpenAI, Claude, Gemini) have fundamentally different request/response schemas, token limits, and capabilities.
- Consequence: Each provider needs custom implementation; payload conversion overhead, but enables full feature parity (tool use, vision, etc).
-
Config files (YAML) instead of code-generated models
- Why: Users deploy new LLM models without recompiling; supports OpenAI-compatible endpoints, local Ollama, etc.
- Consequence: Config validation is runtime; schema changes require careful migration.
-
Streaming-first output (token-by-token) over batch responses
- Why: Long completions are perceived as
- Consequence: undefined
🪤Traps & gotchas
API key management: The tool requires provider API keys (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.) set as environment variables or via config files; no built-in key rotation. Config file location: Uses XDG directories (dirs crate) on Linux/macOS, AppData on Windows—paths differ by OS. Streaming mode assumptions: Many tests likely assume streaming is available; Ollama or older model versions may behave differently. Shell integration sourcing: The shell scripts in scripts/shell-integration must be explicitly sourced (. integration.bash) in shell rc files; not automatic after install. Unicode handling: Uses unicode-width and unicode-segmentation for display math; terminal encoding mismatches (non-UTF8) can cause column alignment issues in REPL.
🏗️Architecture
💡Concepts to learn
- Server-Sent Events (SSE) — AIChat uses reqwest-eventsource to stream LLM responses in real-time; understanding SSE vs WebSocket streaming is key to modifying src/client/stream.rs and debugging response handling
- Trait Objects & Dynamic Dispatch — The LLM provider abstraction in src/client/mod.rs likely uses trait objects (dyn Client) to support polymorphic behavior across 20+ providers without code duplication; essential for understanding how new providers integrate
- Tokio Async Runtime & Graceful Shutdown — The project uses tokio-graceful and tokio::signal for clean termination of long-running operations (streaming, REPL); critical for avoiding zombie processes and incomplete API calls
- Retrieval-Augmented Generation (RAG) — AIChat advertises RAG capabilities (config.agent.example.yaml references agents); understanding vector embeddings, semantic search, and context injection is needed to extend document-aware features
- XDG Base Directory Specification — AIChat uses the dirs crate to locate config and data files across platforms (XDG_CONFIG_HOME on Linux, ~/Library/Application Support on macOS); config paths are non-obvious and platform-dependent
- Prompt Injection & Role-Based Prompting — The assets/roles/ directory contains system prompts that guard against misuse (e.g., %shell%.md prevents dangerous commands); understanding prompt templating and role isolation prevents security regressions when adding new agent behaviors
- Terminal Capability Detection & ANSI Escape Codes — AIChat uses is-terminal and crossterm to detect whether stdout is a TTY and emit appropriate ANSI color/styling codes; mishandling can break colored output in piped scripts or non-interactive environments
🔗Related repos
oobabooga/text-generation-webui— Local-first LLM interface similar in philosophy but focuses on self-hosted model serving via WebUI, whereas AIChat unifies existing cloud/local providersjerryjliu/llama_index— RAG framework that AIChat's agent/RAG features overlap with; complementary for building document retrieval pipelinesjmorganca/ollama— Local LLM provider that AIChat supports; users installing Ollama locally will use AIChat as a CLI interface to itlm-sys/FastChat— Multi-provider inference orchestration similar in scope but Python-based and API-focused; AIChat is the CLI-first alternativeaider-ai/aider— Code-focused LLM assistant with shell integration similar to AIChat's Shell Assistant mode; different UX (file-aware editing vs one-off queries)
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive integration tests for RAG functionality
The repo has RAG implementation in src/rag/ with splitter modules and vector serialization, but there are no visible test files in the repo structure. A new contributor could add integration tests for the RAG pipeline including document splitting (src/rag/splitter/language.rs), vector storage (src/rag/serde_vectors.rs), and end-to-end RAG queries. This is critical for ensuring the RAG feature works correctly across different languages and document types.
- [ ] Create tests/rag_integration_tests.rs for end-to-end RAG workflows
- [ ] Add unit tests in src/rag/splitter/mod.rs for different language splitters (language.rs)
- [ ] Add tests for vector serialization/deserialization in src/rag/serde_vectors.rs
- [ ] Add test fixtures with sample documents and expected vector outputs
- [ ] Update Cargo.toml to include test dependencies if needed
Add client implementation tests for all LLM providers
The src/client/ directory contains implementations for multiple providers (openai.rs, claude.rs, gemini.rs, bedrock.rs, vertexai.rs, cohere.rs, azure_openai.rs, openai_compatible.rs) but there are no visible unit tests. A contributor could create mock-based tests to verify request/response handling, error cases, and stream parsing for each provider without making actual API calls.
- [ ] Create tests/client_mocks.rs with mock HTTP responses for each provider
- [ ] Add unit tests in src/client/openai.rs, src/client/claude.rs, etc. for message building
- [ ] Add tests for src/client/stream.rs to verify streaming response parsing
- [ ] Add tests for src/client/access_token.rs token refresh logic
- [ ] Test error handling and retry logic in src/client/common.rs
Implement CI workflow for building and testing on multiple Rust versions
The .github/workflows/ci.yaml exists but there's no evidence it tests against multiple Rust versions (MSRV validation) or architectures. A contributor could enhance the CI to ensure the MSRV is maintained and that builds succeed on stable/beta/nightly, which is critical for a widely-distributed CLI tool available via cargo, homebrew, pacman, scoop, etc.
- [ ] Update .github/workflows/ci.yaml to test against MSRV (likely 1.70+ based on dependencies)
- [ ] Add matrix strategy testing stable, beta, and nightly Rust versions
- [ ] Add cross-compilation checks for x86_64, aarch64, and armv7 targets
- [ ] Add test step that runs
cargo test --all-featureson each Rust version - [ ] Document the MSRV in README.md and Cargo.toml
🌿Good first issues
- Add comprehensive integration tests for each provider client in src/client/: currently no visible test directory structure; writing tests/client_integration_tests.rs with mocked HTTP responses for OpenAI, Claude, and Gemini flows would improve reliability and serve as documentation.
- Document the config schema in docs/config.md with examples for each supported provider (models.yaml and config.example.yaml exist but lack detailed field-by-field explanation); include troubleshooting section for common auth failures.
- Add support for stdin piping in the Shell Assistant role (assets/roles/%shell%.md): currently shell commands are suggested but not executed inline; implement a --execute flag in src/cli.rs that auto-runs shell suggestions with user confirmation.
⭐Top contributors
Click to expand
Top contributors
- @sigoden — 87 commits
- @cramosc — 2 commits
- @Curricane — 1 commits
- @renato-umeton — 1 commits
- @danbeibei — 1 commits
📝Recent commits
Click to expand
Recent commits
82976d3— chore: update models.yaml (sigoden)0493134— chore: update models.yaml (sigoden)236097b— chore: update models.yaml (sigoden)4ddc28d— chore: update models.yaml (sigoden)dc2df96— chore: update models.yaml (sigoden)ce3205d— chore: update models.yaml (sigoden)4a57c56— chore: update models.yaml (sigoden)b0d54b6— chore: update models.yaml (sigoden)4719fe8— chore: update models.yaml (sigoden)6536d63— chore: update models.yaml (sigoden)
🔒Security observations
- Medium · Incomplete Cargo.toml - Missing Dependency Specifications —
Cargo.toml. The Cargo.toml file appears truncated with an incomplete dependency specification for 'scraper'. The last line ends abruptly with 'deterministic' without closing the bracket. This could indicate a corrupted or incomplete configuration file that may cause build failures or unexpected behavior. Fix: Complete and validate the Cargo.toml file. Ensure all dependency declarations are properly closed with matching brackets and commas where needed. Run 'cargo check' to validate the manifest. - Medium · Use of Deprecated or Outdated Dependencies —
Cargo.toml. Several dependencies are pinned to versions from 2023-2024 without upper bounds specified. Notable examples: chrono 0.4.23, time 0.3.36, and others. These older versions may contain known security vulnerabilities that have been patched in newer releases. Fix: Regularly update dependencies to their latest versions. Use 'cargo update' and review changelogs for security patches. Consider using cargo-audit to identify known vulnerabilities: 'cargo install cargo-audit && cargo audit'. - Medium · Configuration Files with Sensitive Information —
config.example.yaml, config.agent.example.yaml, models.yaml. The project includes example configuration files (config.example.yaml, config.agent.example.yaml, models.yaml) that may serve as templates for API keys and credentials. If users copy these without proper security practices, sensitive data could be exposed. Fix: Ensure documentation clearly warns users never to commit actual config files with credentials to version control. Add config files to .gitignore. Use environment variables for sensitive data instead of config files. Document best practices for credential management. - Medium · HTTP Client with Potential Security Implications —
src/client/ (multiple provider implementations), src/utils/request.rs. The project uses reqwest and hyper for HTTP requests to communicate with multiple LLM providers (OpenAI, Claude, Gemini, etc.). Without explicit certificate pinning or validation, there's potential for MITM attacks. Fix: Ensure all HTTP clients properly validate SSL/TLS certificates. Use reqwest with default-features enabled for security. Implement certificate pinning for critical API endpoints. Review implementation in request.rs for proper validation. - Medium · Crypto Operations Without Clear Validation —
src/utils/crypto.rs, src/client/access_token.rs. The codebase includes crypto utilities (sha2, hmac, base64) used for operations like access token handling. Without clear review of src/utils/crypto.rs and src/client/access_token.rs, there's risk of improper cryptographic implementation. Fix: Conduct thorough security review of cryptographic implementations. Ensure proper use of HMAC algorithms, avoid custom crypto implementations, use well-tested libraries correctly. Consider security audit by cryptography experts. - Low · Shell Integration Scripts —
scripts/shell-integration/. The project includes shell integration scripts for multiple shells (bash, fish, nu, powershell, zsh). These could potentially be vulnerable to shell injection if user input is not properly escaped. Fix: Audit all shell integration scripts for proper quoting and escaping of variables. Use shellcheck for bash scripts. Ensure all user-controlled input is properly escaped before use in shell commands. - Low · Static Assets Without Integrity Checks —
assets/. The project includes static assets like HTML files (arena.html, playground.html) and binary theme files. These could be modified without detection if source control is compromised. Fix: Implement SRI (Subresource Integrity) for any remotely loaded assets. Document how assets are built and verified. Consider code signing for released binaries. Include checksums in release notes. - Low · Potential Sensitive Data in Logs —
src/ (throughout), logging configuration. The project uses logging (simplelog, log crate) throughout. There's risk that API keys, tokens, or user data could be inadvertently logged, especially in debug mode. Fix: Implement log filtering to sanitize sensitive data (API keys, tokens, passwords). Use structured logging. Set appropriate log levels for production. Review all logging calls to ensure no secrets are logged. Document sensitive data handling in logging.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.