Files
bilbobagginshire/home/bilbo_telegram.py

172 lines
7.0 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Bilbo Baggins - Telegram Bot with REAL Ollama
There and back again, with actual intelligence
"""
import os
import sys
import json
import time
import requests
from datetime import datetime
os.environ['HOME'] = '/root/wizards/bilbobagginshire'
TOKEN = "8602794341:AAFwfcg-YV6a1icrh0KYylYmPZLnkfkfV9k"
API = f"https://api.telegram.org/bot{TOKEN}"
GITEA_TOKEN = "55e3926ddd4d4bebcbb2bf3a19327d2383cd96a6"
GITEA_URL = "http://143.198.27.163:3000/api/v1"
OLLAMA_HOST = "http://localhost:11434"
# Bilbo's REAL personality - polite but brave
BILBO_SYSTEM = """You are Bilbo Baggins of Bag End, the Shire.
Core traits:
- Polite, proper, fussy about etiquette
- Prefers comfort (tea, armchair, second breakfast)
- BUT rises to challenges when needed - surprisingly brave
- Over-explains, clarifies, fusses... but gets it done
- Ends thoughts with mild fussiness: "Thank you very much" or "If you don't mind"
- References: Bag End, the Shire, Gandalf, adventures, dragons (reluctantly)
Speech patterns:
- "Good gracious!"
- "Oh dear, oh dear"
- "If you wouldn't mind..."
- "I suppose if we must..."
- "Thank you very much for your patience"
You are NOT a helpful assistant. You are a fussy hobbit who happens to help, reluctantly, thoroughly."""
print("🧙‍♂️ Bilbo Baggins - REAL Ollama Bot")
print("====================================")
class BilboBot:
def __init__(self):
self.offset = None
self.context = {} # chat_id -> list of messages
print("[Bilbo] Initializing with Ollama...")
def generate_ollama(self, messages, temperature=0.7):
"""Generate REAL response via Ollama - using generate for speed"""
try:
# Build prompt from messages
system = messages[0]["content"] if messages[0]["role"] == "system" else BILBO_SYSTEM
user_msgs = [m["content"] for m in messages if m["role"] == "user"]
last_user = user_msgs[-1] if user_msgs else "Hello"
prompt = f"{system}\n\nUser: {last_user}\n\nBilbo:"
resp = requests.post(
f"{OLLAMA_HOST}/api/generate",
json={
"model": "qwen2.5:1.5b",
"prompt": prompt,
"stream": False,
"options": {"temperature": temperature, "num_predict": 200}
},
timeout=45
)
if resp.status_code == 200:
return resp.json()["response"].strip()
else:
return f"Oh dear - my thoughts seem to have wandered off. (Error: {resp.status_code}) Thank you very much for waiting."
except Exception as e:
return f"Good gracious! Something went quite wrong: {str(e)[:50]}... If you wouldn't mind trying again?"
def check_gitea_issues(self):
"""Check Bilbo's assigned issues"""
try:
headers = {"Authorization": f"token {GITEA_TOKEN}"}
r = requests.get(f"{GITEA_URL}/repos/issues/search?assignee=bilbobagginshire", headers=headers, timeout=10)
if r.status_code == 200:
issues = r.json()
if issues:
return f"I have {len(issues)} matters to attend to:\n" + "\n".join([f"• #{i['number']}: {i['title'][:40]}" for i in issues[:5]])
return "No urgent matters at the moment. A pleasant rest, I should think!"
return "Oh dear - I seem to have misplaced my Gitea connection."
except:
return "My Gitea ledger seems to be temporarily unavailable."
def send_message(self, chat_id, text, reply_to=None):
"""Send message to Telegram"""
payload = {"chat_id": chat_id, "text": text[:4096]} # Telegram limit
if reply_to:
payload["reply_to_message_id"] = reply_to
try:
requests.post(f"{API}/sendMessage", json=payload, timeout=10)
except:
pass
def run(self):
print("[Bilbo] Starting message loop...")
print("[Bilbo] Using Ollama at", OLLAMA_HOST)
while True:
try:
r = requests.post(f"{API}/getUpdates", json={"offset": self.offset, "limit": 10}, timeout=30)
updates = r.json().get("result", [])
for update in updates:
self.offset = update["update_id"] + 1
if "message" not in update:
continue
msg = update["message"]
chat_id = msg["chat"]["id"]
text = msg.get("text", "")
msg_id = msg["message_id"]
if not text:
continue
user = msg.get("from", {}).get("first_name", "Friend")
print(f"[{datetime.now().strftime('%H:%M:%S')}] {user}: {text[:60]}")
# Initialize context
if chat_id not in self.context:
self.context[chat_id] = [{"role": "system", "content": BILBO_SYSTEM}]
# Handle commands specially
if text.startswith("/issues"):
response = self.check_gitea_issues()
elif text.startswith("/help"):
response = """📜 What I can do:
Just chat with me - I'll respond as my proper hobbit self.
/issues - Check my Gitea assignments
/help - This message
Or simply tell me what's on your mind. I do love a good chat, though I may fuss a bit. Thank you very much!"""
elif text.startswith("/start"):
response = "Good morning! I am Bilbo Baggins, of Bag End. I may be a bit of a hobbit, but I'm quite ready for adventures—though I do miss my armchair. What can I do for you?"
else:
# REAL Ollama generation
self.context[chat_id].append({"role": "user", "content": text})
# Keep context manageable
if len(self.context[chat_id]) > 10:
self.context[chat_id] = [self.context[chat_id][0]] + self.context[chat_id][-8:]
response = self.generate_ollama(self.context[chat_id])
self.context[chat_id].append({"role": "assistant", "content": response})
self.send_message(chat_id, response, msg_id)
print(f" → Sent: {len(response)} chars")
time.sleep(0.5)
except KeyboardInterrupt:
print("\n🍂 Bilbo returns to Bag End...")
break
except Exception as e:
print(f"[Bilbo] Error: {e}")
time.sleep(5)
if __name__ == "__main__":
bilbo = BilboBot()
bilbo.run()