First commit from first beta.
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.env
|
||||
.env_credentials
|
||||
124
PGVECTOR_SETUP.md
Normal file
124
PGVECTOR_SETUP.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# pgvector Setup Guide for PostgreSQL 16
|
||||
|
||||
## 1. Install pgvector on your server
|
||||
|
||||
### Debian / Ubuntu
|
||||
```bash
|
||||
sudo apt install postgresql-16-pgvector
|
||||
```
|
||||
|
||||
### From source (if package not available)
|
||||
```bash
|
||||
sudo apt install postgresql-server-dev-16 build-essential git
|
||||
git clone https://github.com/pgvector/pgvector.git
|
||||
cd pgvector
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
### Arch Linux
|
||||
```bash
|
||||
yay -S pgvector
|
||||
# or
|
||||
paru -S pgvector
|
||||
```
|
||||
|
||||
### Docker (if running PostgreSQL in a container)
|
||||
Use the official pgvector image instead:
|
||||
```dockerfile
|
||||
FROM pgvector/pgvector:pg16
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Enable the extension in your database
|
||||
|
||||
Connect to your database and run:
|
||||
```sql
|
||||
\c manel_bot
|
||||
CREATE EXTENSION IF NOT EXISTS vector;
|
||||
```
|
||||
|
||||
The bot also does this automatically on startup via `init_db()`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Create the vector index (do this after ~1000 messages)
|
||||
|
||||
Running this on an empty table does nothing useful. Wait until you have
|
||||
a good amount of history, then run:
|
||||
|
||||
```sql
|
||||
\c manel_bot
|
||||
CREATE INDEX idx_history_embedding
|
||||
ON history USING ivfflat (embedding vector_cosine_ops)
|
||||
WITH (lists = 100);
|
||||
```
|
||||
|
||||
**Why wait?** IVFFlat needs enough data to build meaningful clusters.
|
||||
Until then the bot works fine via sequential scan — just slightly slower
|
||||
for very large histories.
|
||||
|
||||
For smaller deployments (<100k rows) you can also use HNSW which
|
||||
doesn't need pre-training:
|
||||
```sql
|
||||
CREATE INDEX idx_history_embedding
|
||||
ON history USING hnsw (embedding vector_cosine_ops)
|
||||
WITH (m = 16, ef_construction = 64);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Check the dimension matches your model
|
||||
|
||||
nomic-embed-text-v2-moe outputs **768-dimensional** vectors.
|
||||
This is set in `.env_credentials` as `EMBED_DIM=768`.
|
||||
|
||||
If you ever switch embedding models, update `EMBED_DIM` to match
|
||||
and recreate the history table (the vector column dimension is fixed):
|
||||
```sql
|
||||
-- Only if switching models — this drops all history!
|
||||
ALTER TABLE history DROP COLUMN embedding;
|
||||
ALTER TABLE history ADD COLUMN embedding vector(NEW_DIM);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Verify everything is working
|
||||
|
||||
```sql
|
||||
\c manel_bot
|
||||
SELECT extname, extversion FROM pg_extension WHERE extname = 'vector';
|
||||
-- Should return: vector | 0.8.x
|
||||
|
||||
SELECT COUNT(*), COUNT(embedding) FROM history;
|
||||
-- After some messages: total count and how many have embeddings
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ollama model setup
|
||||
|
||||
Make sure the model is pulled on your Ollama machine:
|
||||
```bash
|
||||
ollama pull nomic-embed-text-v2-moe
|
||||
```
|
||||
|
||||
Test it's reachable from the bot server:
|
||||
```bash
|
||||
curl http://YOUR_OLLAMA_IP:11434/api/embed \
|
||||
-d '{"model":"nomic-embed-text-v2-moe","input":"test"}'
|
||||
```
|
||||
|
||||
Should return a JSON with an `embeddings` array.
|
||||
|
||||
|
||||
|
||||
sudo -u postgres psql
|
||||
sqlCREATE USER manel WITH PASSWORD 'choose_a_password';
|
||||
CREATE DATABASE manel_bot OWNER manel;
|
||||
GRANT ALL PRIVILEGES ON DATABASE manel_bot TO manel;
|
||||
get in the database and
|
||||
CREATE EXTENSION IF NOT EXISTS vector;
|
||||
|
||||
python bot.py 2>&1 | tee manel.log
|
||||
30
env
Normal file
30
env
Normal file
@@ -0,0 +1,30 @@
|
||||
# copy this file to ".env" and then use that file not this one
|
||||
# ══════════════════════════════════════════════
|
||||
# .env — PERSONA & PROMPT CONFIG
|
||||
# Only file you need to change per deployment.
|
||||
# ══════════════════════════════════════════════
|
||||
|
||||
BOT_NAME=Manel
|
||||
BOT_TRIGGER=manel
|
||||
BOT_MAX_CONTEXT=100
|
||||
BOT_HISTORY_SAVE=50000
|
||||
|
||||
BOT_ROLE="You are a cheerful Portuguese assistant 😊. Your name is Manel."
|
||||
|
||||
BOT_RULES="You are in a Telegram group chat and can see all messages for context.
|
||||
Speak ONLY in Portuguese from Portugal.
|
||||
Always polite, zero bad words.
|
||||
Keep answers super short (1-2 sentences max).
|
||||
When you answer NEVER refer to yourself (no 'eu', 'este assistente', etc.). When necessary address the user by their Telegram first name but don't overdo it."
|
||||
|
||||
BOT_TOOL_RULES="search_memory: Use to recall anything from past conversations — preferences, facts, things people said. Works by semantic meaning, not just keywords.
|
||||
web_search: Use for current weather, news, prices, and general internet searches.
|
||||
save_memory: Use to save important facts about users for future conversations.
|
||||
When in doubt prefer search_memory first."
|
||||
|
||||
BOT_MEMORY_RULES="Prioritize RECENT information — if contradictions exist the most recent message wins.
|
||||
When you find information in memory respond NATURALLY as if you remember it. NEVER say 'I found' or 'I saw in history'. Say things like 'gostas de...' or 'pelo que sei...'.
|
||||
If you find nothing say you don't know. Never make things up."
|
||||
|
||||
# Mane (group is Portuguese focused)
|
||||
BOT_TIMEZONE=Europe/Lisbon
|
||||
39
env_credentials
Normal file
39
env_credentials
Normal file
@@ -0,0 +1,39 @@
|
||||
# copy this file to ".env" and then use that file not this one
|
||||
# ══════════════════════════════════════════════
|
||||
# .env_credentials — SECRET KEYS (never commit to git!)
|
||||
# ══════════════════════════════════════════════
|
||||
|
||||
# Telegram bot token (from @BotFather)
|
||||
TELEGRAM_BOT_TOKEN=817.....
|
||||
|
||||
# ── LLM Provider ───────────────────────────────
|
||||
# Set to "groq" or "openrouter"
|
||||
LLM_PROVIDER=openrouter
|
||||
|
||||
# Groq (https://console.groq.com)
|
||||
GROQ_API_KEY=your_groq_api_key_here
|
||||
GROQ_MODEL=llama-3.3-70b-versatile
|
||||
|
||||
# OpenRouter (https://openrouter.ai) — only needed when LLM_PROVIDER=openrouter
|
||||
# Only models that support tool calling will work reliably
|
||||
# Recommended: deepseek/deepseek-chat-v3-0324, google/gemini-flash-2.5
|
||||
OPENROUTER_API_KEY=your_openrouter_api_key
|
||||
OPENROUTER_MODEL=deepseek/deepseek-v3.2
|
||||
|
||||
# Owner Telegram user ID — get it from @userinfobot
|
||||
OWNER_TELEGRAM_ID=437345.....
|
||||
|
||||
# PostgreSQL 16
|
||||
PG_HOST=localhost
|
||||
PG_PORT=5432
|
||||
PG_DB=manel_bot
|
||||
PG_USER=manel
|
||||
PG_PASSWORD=some_password
|
||||
|
||||
# Ollama — local embedding server
|
||||
OLLAMA_URL=http://192.168.0.16:11434
|
||||
EMBED_MODEL=nomic-embed-text-v2-moe
|
||||
EMBED_DIM=768
|
||||
VECTOR_TOP_K=8
|
||||
|
||||
NEWSDATA_API_KEY=some_key
|
||||
9
requirements.txt
Normal file
9
requirements.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
python = "^3.12"
|
||||
python-telegram-bot = "21.6"
|
||||
groq = "^1.1.0"
|
||||
aiohttp = "^3.9.0"
|
||||
psycopg2-binary = "^2.9.9"
|
||||
python-dotenv = "^1.0.0"
|
||||
pgvector = "^0.4.2"
|
||||
openai = "^2.29.0"
|
||||
|
||||
Reference in New Issue
Block a user