Suhana (μνλ) is your self-hosted AI companion: a modular chat agent with a personality, local knowledge base, and the ability to run commands β all without giving away your data.
- π€ Chat with a personality β Suhana remembers you and responds in character
- π Search local knowledge β markdown, code, and notes in
/knowledgefolder - π Pluggable AI engines β supports Ollama (π¦) and OpenAI (π€)
- π§ Memory-aware β Suhana evolves with you via
!rememberandprofile.json - π Voice input/output β speak naturally to Suhana and hear her reply (Whisper + Coqui)
- π Self-hosted & portable β no cloud dependencies, runs on macOS/Windows/Linux
- β‘ Execute commands β define your own actions like
send_message()orupdate_profile()
git clone https://github.com/Reterics/suhana.git
cd suhanaYou need Python 3.11+ installed. Then choose one of the following:
β Option A: Ollama β run models locally (recommended)
-
Install Ollama:
- macOS / Windows: https://ollama.com/download
- Linux:
curl -fsSL https://ollama.com/install.sh | sh
-
Start a model:
ollama run llama3
Other available models include:
mistralβ lightweight and fastllama3β larger and more capablegemmaβ Googleβs open modelphiβ compact and smartcodellamaβ optimized for coding tasksllavaβ for multimodal (image + text) input
-
You can change model in
settings.template.jsonor at runtime.
-
Add your OpenAI key in a
.envfile:OPENAI_API_KEY=sk-...
-
Set model and backend:
{ "llm_backend": "openai", "openai_model": "gpt-4" }
You can switch between engines at runtime using
!switch ollamaor!switch openai.
./setup.shsetup.batThis will create a virtualenv, install runtime dependencies from
requirements.txt, and auto-generatesettings.jsonandprofile.jsonif missing.
Put .md, .txt, or .code files into /knowledge, then run:
python ingest.pypython main.pyYouβll see:
Hello, I'm Suhana π¦ β powered by: OLLAMA (llama3)
| Command | Description |
|---|---|
!engine |
Show the current model + backend |
!switch openai |
Switch between Ollama and OpenAI |
!exit |
Leave the session |
help |
Show available tools and commands |
!remember fact |
Add a memory fact |
!recall |
List all memory facts |
!forget keyword |
Remove memory entries matching keyword |
Suhana comes with a variety of built-in tools that extend its capabilities:
| Tool | Description | Example Usage |
|---|---|---|
help |
Lists available tools and commands | "help" or "what can you do?" |
get_date |
Tells the current date | "what is the date today?" |
get_time |
Tells the current time | "what is the time now?" |
add_note |
Adds a personal note or reminder | "remember to buy milk" |
list_notes |
Lists all stored notes by date | "show my notes" |
update_profile |
Updates user preferences or profile | "set preference theme to dark" |
web_search |
Searches the web using various engines | "search for Python programming" |
calculator |
Performs basic math calculations | "calculate 2 + 2 * 3" |
weather |
Gets current weather for a location | "what's the weather in New York?" |
The web search tool supports multiple search engines:
search for Python programming # Uses DuckDuckGo by default
search with bing for machine learning # Uses Bing search engine
search with brave for climate change # Uses Brave search engine
The calculator tool supports various mathematical operations and functions:
- Basic arithmetic:
+,-,*,/,**(power),%(modulo),//(floor division) - Functions:
abs,round,min,max,sum,sin,cos,tan,sqrt,log,log10,exp - Constants:
pi,e
Example: "calculate sin(pi/2) + sqrt(16)"
suhana/
ββ engine/ # Core logic
β ββ agent.py # Main loop
β ββ engine_config.py # Settings and backend switching
β ββ profile.py # Memory and preferences
β ββ history.py # Summarization + trimming
β ββ backends/ # ollama.py / openai.py
ββ knowledge/ # Your documents and notes
ββ vectorstore/ # Auto-generated FAISS index
ββ models/ # Prompt templates
ββ assets/ # Logos and visuals
ββ docs/ # Documentation
β ββ architecture.md # Component relationships diagram
ββ ingest.py # Knowledge indexer
ββ main.py # Entrypoint and setup runner
ββ settings.template.json # Safe config defaults
ββ profile.json # Runtime user profile (generated)
ββ settings.json # Runtime config (generated)
ββ .gitignore # Excludes local state
ββ setup.sh / setup.bat # Easy one-step setup
A sample profile.json:
{
"name": "Attila",
"preferences": {
"communication_style": "technical, friendly"
},
"memory": [
{ "type": "fact", "content": "Attila prefers local models over cloud ones." }
]
}| Engine | Status | Notes |
|---|---|---|
| Ollama | β Required if selected | llama3, mistral, gemma, phi, etc. |
| OpenAI | β Optional | Requires API key |
| LocalHF | π Planned | Hugging Face local models |
For testing and development, you'll need additional dependencies:
pip install -r requirements-dev.txtThis will install both runtime dependencies and development tools like pytest and pytest-cov.
The project uses pytest for testing. To run tests:
# Run all tests
python -m pytest
# Run specific test file
python -m pytest tests/test_profile_meta.py
# Run with verbose output
python -m pytest -v
# Run with coverage report
python -m pytest --cov --cov-config=.coveragercThe project includes code coverage reporting in the GitHub Actions CI pipeline. The coverage report is generated using pytest-cov and uploaded to Codecov.
To view the coverage report locally:
python -m pytest --cov --cov-config=.coveragerc --cov-report=htmlThen open coverage_html_report/index.html in your browser.
- Create a new file in the
testsdirectory with the naming patterntest_<module_name>.py - Import the module/function to be tested
- Write test functions that assert expected behavior
- Use fixtures for common setup/teardown operations
From the project root:
uvicorn engine.api_server:app --reloadIf api_keys.json does not exist, it will be created automatically using:
- The
SUHANA_DEFAULT_API_KEYfrom your.envfile - Or a secure randomly generated key
Open in your browser:
http://localhost:8000/docs
Use the /query endpoint, and set the x-api-key header.
curl -X POST http://localhost:8000/query \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY_HERE" \
-d '{"input": "What is Suhana?", "backend": "ollama"}'import requests
res = requests.post("http://localhost:8000/query", json={
"input": "Hello, who are you?",
"backend": "ollama"
}, headers={
"x-api-key": "YOUR_API_KEY_HERE"
})
print(res.json())- API keys are stored in
api_keys.json(excluded from Git via.gitignore) - To customize the default dev key, define
SUHANA_DEFAULT_API_KEYin your.env - All keys must be marked
"active": trueto be accepted - You can edit
api_keys.jsonwhile the server is running β no restart needed
MIT β use freely, modify locally, and share improvements.

