synapse-assistant-ai 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- synapse_assistant_ai-0.1.0/PKG-INFO +84 -0
- synapse_assistant_ai-0.1.0/README.md +63 -0
- synapse_assistant_ai-0.1.0/pyproject.toml +51 -0
- synapse_assistant_ai-0.1.0/setup.cfg +4 -0
- synapse_assistant_ai-0.1.0/super_ai/__init__.py +103 -0
- synapse_assistant_ai-0.1.0/super_ai/actions.py +217 -0
- synapse_assistant_ai-0.1.0/super_ai/config.py +118 -0
- synapse_assistant_ai-0.1.0/super_ai/llm.py +107 -0
- synapse_assistant_ai-0.1.0/super_ai/messaging.py +127 -0
- synapse_assistant_ai-0.1.0/super_ai/model_manager.py +256 -0
- synapse_assistant_ai-0.1.0/super_ai/speech.py +155 -0
- synapse_assistant_ai-0.1.0/super_ai/video.py +138 -0
- synapse_assistant_ai-0.1.0/synapse_assistant_ai.egg-info/PKG-INFO +84 -0
- synapse_assistant_ai-0.1.0/synapse_assistant_ai.egg-info/SOURCES.txt +16 -0
- synapse_assistant_ai-0.1.0/synapse_assistant_ai.egg-info/dependency_links.txt +1 -0
- synapse_assistant_ai-0.1.0/synapse_assistant_ai.egg-info/entry_points.txt +3 -0
- synapse_assistant_ai-0.1.0/synapse_assistant_ai.egg-info/requires.txt +13 -0
- synapse_assistant_ai-0.1.0/synapse_assistant_ai.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: synapse-assistant-ai
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Free offline voice-controlled AI assistant. Install β Run β Talk.
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: vosk>=0.3.45
|
|
9
|
+
Requires-Dist: sounddevice>=0.4.6
|
|
10
|
+
Requires-Dist: pyttsx3>=2.90
|
|
11
|
+
Requires-Dist: ollama>=0.4.0
|
|
12
|
+
Requires-Dist: python-telegram-bot>=21.0
|
|
13
|
+
Requires-Dist: opencv-python-headless>=4.8.0
|
|
14
|
+
Requires-Dist: ultralytics>=8.2.0
|
|
15
|
+
Requires-Dist: pytesseract>=0.3.10
|
|
16
|
+
Requires-Dist: apscheduler>=3.10.0
|
|
17
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
18
|
+
Requires-Dist: pywhatkit>=5.4
|
|
19
|
+
Requires-Dist: duckduckgo-search>=5.0
|
|
20
|
+
Requires-Dist: numpy
|
|
21
|
+
|
|
22
|
+
# π€ Super-AI β Free Offline Voice-Controlled Assistant
|
|
23
|
+
|
|
24
|
+
**Install. Run. Talk.** That's it.
|
|
25
|
+
|
|
26
|
+
## Install (one command)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd alright
|
|
30
|
+
pip install .
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Run (one command)
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
superai
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The first time you run it, an interactive setup will start right in your terminal:
|
|
40
|
+
- It will ask what you want to name your AI (e.g., Jarvis, Friday).
|
|
41
|
+
- It will ask if you want to set up Telegram notifications.
|
|
42
|
+
- **You simply paste your Telegram Bot Token and Chat ID directly in the terminal** when prompted.
|
|
43
|
+
|
|
44
|
+
Once setup is done, your AI will automatically message you on Telegram whenever it finishes a background task. Then it will auto-download the necessary AI files (~1.1 GB, one-time only).
|
|
45
|
+
|
|
46
|
+
After that, it starts instantly. Just talk:
|
|
47
|
+
|
|
48
|
+
> **"Jarvis, open youtube"**
|
|
49
|
+
|
|
50
|
+
## What it can do
|
|
51
|
+
|
|
52
|
+
| Say this | It does this |
|
|
53
|
+
|----------|-------------|
|
|
54
|
+
| "Jarvis, **open google**" | Opens google.com in browser |
|
|
55
|
+
| "Jarvis, **open youtube**" | Opens youtube.com |
|
|
56
|
+
| "Jarvis, **launch Safari**" | Opens Safari app |
|
|
57
|
+
| "Jarvis, **play** /path/to/song.mp3" | Plays media file |
|
|
58
|
+
| "Jarvis, **send whatsapp** to +919876543210 β hello" | Automates sending WhatsApp message |
|
|
59
|
+
| "Jarvis, **search web** for latest AI news" | Opens Chrome & tells you the top web result |
|
|
60
|
+
| "Jarvis, **send message** β meeting at 5" | Sends Telegram message |
|
|
61
|
+
| "Jarvis, **send voice note** β I'll be late" | Sends voice note on Telegram |
|
|
62
|
+
| "Jarvis, **set reminder** 5 minutes β drink water" | Reminds you in 5 min |
|
|
63
|
+
| "Jarvis, **what is Python?**" | Answers your question by voice |
|
|
64
|
+
| "Jarvis, **analyse video** /path/to/clip.mp4" | Tells what's in the video |
|
|
65
|
+
|
|
66
|
+
## Requirements
|
|
67
|
+
|
|
68
|
+
- Python 3.10+
|
|
69
|
+
- Microphone
|
|
70
|
+
- 6 GB RAM (minimum)
|
|
71
|
+
- ~1.5 GB disk space (for AI files)
|
|
72
|
+
- Internet (only for first-time download and web searches)
|
|
73
|
+
|
|
74
|
+
## How it works
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
You speak β AI Brain β Action / Answer β Speaks back
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Everything runs locally on your machine. No cloud. No API bills. No data leaves your computer.
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
MIT
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# π€ Super-AI β Free Offline Voice-Controlled Assistant
|
|
2
|
+
|
|
3
|
+
**Install. Run. Talk.** That's it.
|
|
4
|
+
|
|
5
|
+
## Install (one command)
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cd alright
|
|
9
|
+
pip install .
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Run (one command)
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
superai
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The first time you run it, an interactive setup will start right in your terminal:
|
|
19
|
+
- It will ask what you want to name your AI (e.g., Jarvis, Friday).
|
|
20
|
+
- It will ask if you want to set up Telegram notifications.
|
|
21
|
+
- **You simply paste your Telegram Bot Token and Chat ID directly in the terminal** when prompted.
|
|
22
|
+
|
|
23
|
+
Once setup is done, your AI will automatically message you on Telegram whenever it finishes a background task. Then it will auto-download the necessary AI files (~1.1 GB, one-time only).
|
|
24
|
+
|
|
25
|
+
After that, it starts instantly. Just talk:
|
|
26
|
+
|
|
27
|
+
> **"Jarvis, open youtube"**
|
|
28
|
+
|
|
29
|
+
## What it can do
|
|
30
|
+
|
|
31
|
+
| Say this | It does this |
|
|
32
|
+
|----------|-------------|
|
|
33
|
+
| "Jarvis, **open google**" | Opens google.com in browser |
|
|
34
|
+
| "Jarvis, **open youtube**" | Opens youtube.com |
|
|
35
|
+
| "Jarvis, **launch Safari**" | Opens Safari app |
|
|
36
|
+
| "Jarvis, **play** /path/to/song.mp3" | Plays media file |
|
|
37
|
+
| "Jarvis, **send whatsapp** to +919876543210 β hello" | Automates sending WhatsApp message |
|
|
38
|
+
| "Jarvis, **search web** for latest AI news" | Opens Chrome & tells you the top web result |
|
|
39
|
+
| "Jarvis, **send message** β meeting at 5" | Sends Telegram message |
|
|
40
|
+
| "Jarvis, **send voice note** β I'll be late" | Sends voice note on Telegram |
|
|
41
|
+
| "Jarvis, **set reminder** 5 minutes β drink water" | Reminds you in 5 min |
|
|
42
|
+
| "Jarvis, **what is Python?**" | Answers your question by voice |
|
|
43
|
+
| "Jarvis, **analyse video** /path/to/clip.mp4" | Tells what's in the video |
|
|
44
|
+
|
|
45
|
+
## Requirements
|
|
46
|
+
|
|
47
|
+
- Python 3.10+
|
|
48
|
+
- Microphone
|
|
49
|
+
- 6 GB RAM (minimum)
|
|
50
|
+
- ~1.5 GB disk space (for AI files)
|
|
51
|
+
- Internet (only for first-time download and web searches)
|
|
52
|
+
|
|
53
|
+
## How it works
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
You speak β AI Brain β Action / Answer β Speaks back
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Everything runs locally on your machine. No cloud. No API bills. No data leaves your computer.
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
|
|
63
|
+
MIT
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "synapse-assistant-ai"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Free offline voice-controlled AI assistant. Install β Run β Talk."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
|
|
13
|
+
dependencies = [
|
|
14
|
+
# Speech-to-Text (offline)
|
|
15
|
+
"vosk>=0.3.45",
|
|
16
|
+
"sounddevice>=0.4.6",
|
|
17
|
+
|
|
18
|
+
# Text-to-Speech (offline, system voices)
|
|
19
|
+
"pyttsx3>=2.90",
|
|
20
|
+
|
|
21
|
+
# LLM client (talks to auto-managed Ollama)
|
|
22
|
+
"ollama>=0.4.0",
|
|
23
|
+
|
|
24
|
+
# Telegram (optional at runtime, installed so it's ready)
|
|
25
|
+
"python-telegram-bot>=21.0",
|
|
26
|
+
|
|
27
|
+
# Video analysis (optional at runtime)
|
|
28
|
+
"opencv-python-headless>=4.8.0",
|
|
29
|
+
"ultralytics>=8.2.0",
|
|
30
|
+
"pytesseract>=0.3.10",
|
|
31
|
+
|
|
32
|
+
# Scheduler
|
|
33
|
+
"apscheduler>=3.10.0",
|
|
34
|
+
|
|
35
|
+
# Config
|
|
36
|
+
"python-dotenv>=1.0.0",
|
|
37
|
+
|
|
38
|
+
# WhatsApp & Web Search
|
|
39
|
+
"pywhatkit>=5.4",
|
|
40
|
+
"duckduckgo-search>=5.0",
|
|
41
|
+
|
|
42
|
+
# Utilities
|
|
43
|
+
"numpy",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[project.scripts]
|
|
47
|
+
synapse-ai = "super_ai:start_loop"
|
|
48
|
+
superai = "super_ai:start_loop"
|
|
49
|
+
|
|
50
|
+
[tool.setuptools.packages.find]
|
|
51
|
+
include = ["super_ai*"]
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""
|
|
2
|
+
super_ai
|
|
3
|
+
ββββββββ
|
|
4
|
+
Free, offline, voiceβcontrolled AI assistant.
|
|
5
|
+
|
|
6
|
+
Install: pip install .
|
|
7
|
+
Run: superai
|
|
8
|
+
|
|
9
|
+
That's it. Models autoβdownload. Telegram notifications autoβsend.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
__version__ = "0.1.0"
|
|
13
|
+
|
|
14
|
+
from .speech import listen, speak, check_wake_word, text_to_wav
|
|
15
|
+
from .llm import ask
|
|
16
|
+
from .actions import run_action
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def start_loop():
|
|
20
|
+
"""
|
|
21
|
+
The WHOLE assistant. One function. Called by `superai` CLI.
|
|
22
|
+
"""
|
|
23
|
+
from .config import interactive_setup, cfg
|
|
24
|
+
from .messaging import notify
|
|
25
|
+
|
|
26
|
+
# ββ Interactive Setup (if first run) ββ
|
|
27
|
+
interactive_setup()
|
|
28
|
+
|
|
29
|
+
# ββ Banner ββ
|
|
30
|
+
print()
|
|
31
|
+
print("ββββββββββββββββββββββββββββββββββββββββββββ")
|
|
32
|
+
print("β π€ S U P E R - A I v0.1.0 β")
|
|
33
|
+
print("β Free Β· Offline Β· Voice-Controlled β")
|
|
34
|
+
print("ββββββββββββββββββββββββββββββββββββββββββββ")
|
|
35
|
+
print()
|
|
36
|
+
|
|
37
|
+
# ββ Autoβdownload models (first run only) ββ
|
|
38
|
+
print("β³ Checking models...")
|
|
39
|
+
from .model_manager import ensure_all_models
|
|
40
|
+
ensure_all_models()
|
|
41
|
+
|
|
42
|
+
# ββ Warm up engines ββ
|
|
43
|
+
print("β³ Starting speech engine...")
|
|
44
|
+
from .speech import _ensure_vosk, _ensure_tts
|
|
45
|
+
_ensure_vosk()
|
|
46
|
+
_ensure_tts()
|
|
47
|
+
|
|
48
|
+
print("β³ Starting AI brain...")
|
|
49
|
+
from .llm import _ensure_llm
|
|
50
|
+
_ensure_llm()
|
|
51
|
+
|
|
52
|
+
# ββ Ready ββ
|
|
53
|
+
print()
|
|
54
|
+
print("β" * 44)
|
|
55
|
+
print(f" β
READY! Say \"{cfg.wake_word}\" + command")
|
|
56
|
+
print(f" Example: \"{cfg.wake_word} open youtube\"")
|
|
57
|
+
print(f" Press Ctrl+C to quit")
|
|
58
|
+
print("β" * 44)
|
|
59
|
+
print()
|
|
60
|
+
|
|
61
|
+
speak(f"Super AI is ready. Say {cfg.wake_word} followed by your command.")
|
|
62
|
+
|
|
63
|
+
# Notify on Telegram that AI is online
|
|
64
|
+
notify("π’ Super-AI is now online and listening!")
|
|
65
|
+
|
|
66
|
+
# ββ Main loop β runs forever until Ctrl+C ββ
|
|
67
|
+
while True:
|
|
68
|
+
try:
|
|
69
|
+
# 1. Listen
|
|
70
|
+
text = listen(timeout=15)
|
|
71
|
+
if not text:
|
|
72
|
+
continue
|
|
73
|
+
|
|
74
|
+
# 2. Wake word?
|
|
75
|
+
command = check_wake_word(text)
|
|
76
|
+
if command is None:
|
|
77
|
+
continue # not for us
|
|
78
|
+
|
|
79
|
+
print(f"\nπ― Command: \"{command}\"")
|
|
80
|
+
|
|
81
|
+
# 3. Ask LLM
|
|
82
|
+
response = ask(command)
|
|
83
|
+
|
|
84
|
+
# 4. Execute or speak
|
|
85
|
+
if isinstance(response, dict):
|
|
86
|
+
# Toolβcall β run action β speak result β Telegram notify (auto)
|
|
87
|
+
result = run_action(response)
|
|
88
|
+
speak(result)
|
|
89
|
+
else:
|
|
90
|
+
# Plain answer β speak it
|
|
91
|
+
speak(response)
|
|
92
|
+
|
|
93
|
+
print()
|
|
94
|
+
|
|
95
|
+
except KeyboardInterrupt:
|
|
96
|
+
print("\n\nπ Shutting down...")
|
|
97
|
+
speak("Goodbye!")
|
|
98
|
+
notify("π΄ Super-AI is now offline.")
|
|
99
|
+
break
|
|
100
|
+
except Exception as exc:
|
|
101
|
+
print(f"[error] {exc}")
|
|
102
|
+
speak("Sorry, something went wrong.")
|
|
103
|
+
notify(f"β οΈ Error: {exc}")
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"""
|
|
2
|
+
super_ai.actions
|
|
3
|
+
ββββββββββββββββ
|
|
4
|
+
OSβlevel action dispatcher.
|
|
5
|
+
|
|
6
|
+
LLM returns JSON β this module executes it β sends Telegram notification.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
|
+
import webbrowser
|
|
12
|
+
import subprocess
|
|
13
|
+
import platform
|
|
14
|
+
import urllib.parse
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from datetime import datetime, timedelta
|
|
17
|
+
|
|
18
|
+
from apscheduler.schedulers.background import BackgroundScheduler
|
|
19
|
+
|
|
20
|
+
from .config import cfg
|
|
21
|
+
|
|
22
|
+
# βββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
23
|
+
# Scheduler (reminders)
|
|
24
|
+
# βββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
25
|
+
|
|
26
|
+
_scheduler = BackgroundScheduler()
|
|
27
|
+
_scheduler.start()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# βββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
31
|
+
# Action functions
|
|
32
|
+
# βββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
33
|
+
|
|
34
|
+
def open_url(url: str) -> str:
|
|
35
|
+
"""Open a URL in the default browser."""
|
|
36
|
+
if not url.startswith(("http://", "https://")):
|
|
37
|
+
url = "https://" + url
|
|
38
|
+
webbrowser.open(url)
|
|
39
|
+
return f"Opened {url}"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def launch_app(name: str) -> str:
|
|
43
|
+
"""Launch a desktop app by name."""
|
|
44
|
+
system = platform.system()
|
|
45
|
+
try:
|
|
46
|
+
if system == "Darwin":
|
|
47
|
+
subprocess.Popen(["open", "-a", name])
|
|
48
|
+
elif system == "Linux":
|
|
49
|
+
subprocess.Popen(["xdg-open", name])
|
|
50
|
+
elif system == "Windows":
|
|
51
|
+
os.startfile(name)
|
|
52
|
+
else:
|
|
53
|
+
return f"Unsupported OS: {system}"
|
|
54
|
+
return f"Launched {name}"
|
|
55
|
+
except Exception as exc:
|
|
56
|
+
return f"Could not launch {name}: {exc}"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def play_media(path: str) -> str:
|
|
60
|
+
"""Play audio/video with default system player."""
|
|
61
|
+
filepath = Path(path).expanduser().resolve()
|
|
62
|
+
if not filepath.is_file():
|
|
63
|
+
return f"File not found: {filepath}"
|
|
64
|
+
|
|
65
|
+
system = platform.system()
|
|
66
|
+
try:
|
|
67
|
+
if system == "Darwin":
|
|
68
|
+
subprocess.Popen(["open", str(filepath)])
|
|
69
|
+
elif system == "Linux":
|
|
70
|
+
subprocess.Popen(["xdg-open", str(filepath)])
|
|
71
|
+
elif system == "Windows":
|
|
72
|
+
os.startfile(str(filepath))
|
|
73
|
+
return f"Playing {filepath.name}"
|
|
74
|
+
except Exception as exc:
|
|
75
|
+
return f"Could not play: {exc}"
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def send_message(to: str = "", body: str = "") -> str:
|
|
79
|
+
"""Send Telegram text message."""
|
|
80
|
+
from .messaging import send_text
|
|
81
|
+
return send_text(to, body)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def send_voice_note(to: str = "", text: str = "") -> str:
|
|
85
|
+
"""Generate voice note from text and send via Telegram."""
|
|
86
|
+
from .speech import text_to_wav
|
|
87
|
+
from .messaging import send_voice
|
|
88
|
+
|
|
89
|
+
wav_path = text_to_wav(text)
|
|
90
|
+
return send_voice(to, wav_path)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def analyse_video_action(path: str) -> str:
|
|
94
|
+
"""Analyse a video and return summary."""
|
|
95
|
+
from .video import analyse_video
|
|
96
|
+
return analyse_video(path)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def set_reminder(text: str, seconds: int = 60) -> str:
|
|
100
|
+
"""Set a reminder β speaks + sends Telegram notification when fires."""
|
|
101
|
+
from .speech import speak
|
|
102
|
+
from .messaging import notify
|
|
103
|
+
|
|
104
|
+
def _fire():
|
|
105
|
+
msg = f"β° Reminder: {text}"
|
|
106
|
+
print(f"\n[reminder] {msg}")
|
|
107
|
+
speak(f"Reminder: {text}")
|
|
108
|
+
notify(msg)
|
|
109
|
+
|
|
110
|
+
run_at = datetime.now() + timedelta(seconds=int(seconds))
|
|
111
|
+
_scheduler.add_job(_fire, "date", run_date=run_at)
|
|
112
|
+
return f"Reminder set for {seconds} seconds: {text}"
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def send_whatsapp(phone: str, message: str) -> str:
|
|
116
|
+
"""Send a WhatsApp message automatically using pywhatkit."""
|
|
117
|
+
try:
|
|
118
|
+
import pywhatkit
|
|
119
|
+
|
|
120
|
+
# Resolve contact name to phone number if it exists in config
|
|
121
|
+
contact_name = phone.lower().strip()
|
|
122
|
+
if contact_name in cfg.whatsapp_contacts:
|
|
123
|
+
phone = cfg.whatsapp_contacts[contact_name]
|
|
124
|
+
|
|
125
|
+
print(f"[action] Preparing to send WhatsApp message to {phone}...")
|
|
126
|
+
|
|
127
|
+
# sendwhatmsg_instantly opens whatsapp web, types the message, and presses enter.
|
|
128
|
+
pywhatkit.sendwhatmsg_instantly(phone, message, wait_time=15, tab_close=True, close_time=3)
|
|
129
|
+
return f"WhatsApp message sent to {phone}"
|
|
130
|
+
except ImportError:
|
|
131
|
+
return "pywhatkit library is not installed."
|
|
132
|
+
except Exception as exc:
|
|
133
|
+
return f"Could not send WhatsApp message: {exc}"
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def search_web(query: str) -> str:
|
|
137
|
+
"""Search the web using duckduckgo-search and open the browser so the user can see."""
|
|
138
|
+
try:
|
|
139
|
+
# Open browser to show the user
|
|
140
|
+
webbrowser.open(f"https://www.google.com/search?q={urllib.parse.quote(query)}")
|
|
141
|
+
|
|
142
|
+
from duckduckgo_search import DDGS
|
|
143
|
+
with DDGS() as ddgs:
|
|
144
|
+
results = list(ddgs.text(query, max_results=2))
|
|
145
|
+
|
|
146
|
+
if not results:
|
|
147
|
+
return f"I couldn't find any web results for {query}."
|
|
148
|
+
|
|
149
|
+
# Get the first snippet
|
|
150
|
+
snippet = results[0]['body']
|
|
151
|
+
|
|
152
|
+
return f"According to the web: {snippet}"
|
|
153
|
+
except ImportError:
|
|
154
|
+
return "duckduckgo-search library is not installed."
|
|
155
|
+
except Exception as exc:
|
|
156
|
+
return f"Could not search the web: {exc}"
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# βββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
160
|
+
# Dispatcher
|
|
161
|
+
# βββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
162
|
+
|
|
163
|
+
_ACTION_MAP = {
|
|
164
|
+
"open_url": open_url,
|
|
165
|
+
"launch_app": launch_app,
|
|
166
|
+
"play_media": play_media,
|
|
167
|
+
"send_message": send_message,
|
|
168
|
+
"send_voice_note": send_voice_note,
|
|
169
|
+
"analyse_video": analyse_video_action,
|
|
170
|
+
"set_reminder": set_reminder,
|
|
171
|
+
"send_whatsapp": send_whatsapp,
|
|
172
|
+
"search_web": search_web,
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def run_action(action_data: dict) -> str:
|
|
177
|
+
"""
|
|
178
|
+
Execute an action from LLM's JSON output.
|
|
179
|
+
After completion, auto-sends Telegram notification.
|
|
180
|
+
|
|
181
|
+
Parameters
|
|
182
|
+
----------
|
|
183
|
+
action_data : dict
|
|
184
|
+
{"action": "open_url", "args": {"url": "https://google.com"}}
|
|
185
|
+
|
|
186
|
+
Returns
|
|
187
|
+
-------
|
|
188
|
+
str β result message (spoken back to user)
|
|
189
|
+
"""
|
|
190
|
+
from .messaging import notify
|
|
191
|
+
|
|
192
|
+
action_name = action_data.get("action", "")
|
|
193
|
+
args = action_data.get("args", {})
|
|
194
|
+
|
|
195
|
+
func = _ACTION_MAP.get(action_name)
|
|
196
|
+
if func is None:
|
|
197
|
+
supported = ", ".join(sorted(_ACTION_MAP.keys()))
|
|
198
|
+
return f"Unknown action: {action_name}. I can do: {supported}"
|
|
199
|
+
|
|
200
|
+
try:
|
|
201
|
+
print(f"[action] βΆ {action_name}({args})")
|
|
202
|
+
result = func(**args)
|
|
203
|
+
print(f"[action] β {result}")
|
|
204
|
+
|
|
205
|
+
# ββ Autoβnotify on Telegram ββ
|
|
206
|
+
notify(f"β
Task done: {action_name}\n{result}")
|
|
207
|
+
|
|
208
|
+
return result
|
|
209
|
+
|
|
210
|
+
except Exception as exc:
|
|
211
|
+
err = f"Action {action_name} failed: {exc}"
|
|
212
|
+
print(f"[action] β {err}")
|
|
213
|
+
|
|
214
|
+
# ββ Notify failure too ββ
|
|
215
|
+
notify(f"β Task failed: {action_name}\n{exc}")
|
|
216
|
+
|
|
217
|
+
return err
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""
|
|
2
|
+
super_ai.config
|
|
3
|
+
βββββββββββββββ
|
|
4
|
+
Auto-config. User ko kuch set nahi karna.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
import json
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
|
|
12
|
+
# Models stored in ~/.superai/models/
|
|
13
|
+
DATA_DIR = Path.home() / ".superai"
|
|
14
|
+
MODELS_DIR = DATA_DIR / "models"
|
|
15
|
+
CONFIG_FILE = DATA_DIR / "config.json"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class Config:
|
|
20
|
+
"""All settings with defaults β works out of the box."""
|
|
21
|
+
|
|
22
|
+
# Paths
|
|
23
|
+
data_dir: Path = field(default_factory=lambda: DATA_DIR)
|
|
24
|
+
models_dir: Path = field(default_factory=lambda: MODELS_DIR)
|
|
25
|
+
|
|
26
|
+
# Speech Model
|
|
27
|
+
vosk_model_url: str = "https://alphacephei.com/vosk/models/vosk-model-small-en-in-0.4.zip"
|
|
28
|
+
vosk_model_name: str = "vosk-model-small-en-in-0.4"
|
|
29
|
+
|
|
30
|
+
# AI Brain
|
|
31
|
+
ollama_model: str = "llama3.2:1b"
|
|
32
|
+
|
|
33
|
+
# Wake word
|
|
34
|
+
wake_word: str = "hey ai"
|
|
35
|
+
|
|
36
|
+
# TTS
|
|
37
|
+
tts_rate: int = 150
|
|
38
|
+
tts_voice_index: int = 0
|
|
39
|
+
|
|
40
|
+
# Telegram (optional)
|
|
41
|
+
telegram_bot_token: str = ""
|
|
42
|
+
telegram_chat_id: str = ""
|
|
43
|
+
|
|
44
|
+
# WhatsApp Contacts (optional: {"name": "+91..."})
|
|
45
|
+
whatsapp_contacts: dict = field(default_factory=dict)
|
|
46
|
+
|
|
47
|
+
@classmethod
|
|
48
|
+
def load(cls) -> "Config":
|
|
49
|
+
DATA_DIR.mkdir(parents=True, exist_ok=True)
|
|
50
|
+
MODELS_DIR.mkdir(parents=True, exist_ok=True)
|
|
51
|
+
|
|
52
|
+
c = cls()
|
|
53
|
+
if CONFIG_FILE.exists():
|
|
54
|
+
try:
|
|
55
|
+
with open(CONFIG_FILE, "r") as f:
|
|
56
|
+
data = json.load(f)
|
|
57
|
+
c.wake_word = data.get("wake_word", c.wake_word)
|
|
58
|
+
c.tts_rate = data.get("tts_rate", c.tts_rate)
|
|
59
|
+
c.tts_voice_index = data.get("tts_voice_index", c.tts_voice_index)
|
|
60
|
+
c.telegram_bot_token = data.get("telegram_bot_token", c.telegram_bot_token)
|
|
61
|
+
c.telegram_chat_id = data.get("telegram_chat_id", c.telegram_chat_id)
|
|
62
|
+
c.whatsapp_contacts = data.get("whatsapp_contacts", c.whatsapp_contacts)
|
|
63
|
+
except Exception:
|
|
64
|
+
pass
|
|
65
|
+
return c
|
|
66
|
+
|
|
67
|
+
def save(self):
|
|
68
|
+
data = {
|
|
69
|
+
"wake_word": self.wake_word,
|
|
70
|
+
"tts_rate": self.tts_rate,
|
|
71
|
+
"tts_voice_index": self.tts_voice_index,
|
|
72
|
+
"telegram_bot_token": self.telegram_bot_token,
|
|
73
|
+
"telegram_chat_id": self.telegram_chat_id,
|
|
74
|
+
"whatsapp_contacts": self.whatsapp_contacts,
|
|
75
|
+
}
|
|
76
|
+
with open(CONFIG_FILE, "w") as f:
|
|
77
|
+
json.dump(data, f, indent=4)
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def vosk_model_path(self) -> Path:
|
|
81
|
+
return self.models_dir / self.vosk_model_name
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
cfg = Config.load()
|
|
85
|
+
|
|
86
|
+
def interactive_setup():
|
|
87
|
+
"""Prompt user for setup if not done yet."""
|
|
88
|
+
if CONFIG_FILE.exists():
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
print("\n" + "="*50)
|
|
92
|
+
print("π Welcome to Super-AI Setup!")
|
|
93
|
+
print("="*50)
|
|
94
|
+
|
|
95
|
+
# AI Name
|
|
96
|
+
print("\n1. Name your AI")
|
|
97
|
+
print("What should the AI respond to? (e.g., Jarvis, Friday, or Hey AI)")
|
|
98
|
+
name = input(f"Enter name [Default: {cfg.wake_word}]: ").strip()
|
|
99
|
+
if name:
|
|
100
|
+
cfg.wake_word = name.lower()
|
|
101
|
+
|
|
102
|
+
# Telegram
|
|
103
|
+
print("\n2. Telegram Notifications (Optional)")
|
|
104
|
+
print("Do you want to receive notifications on your phone when tasks are done?")
|
|
105
|
+
tg_choice = input("Enter y/n [Default: n]: ").strip().lower()
|
|
106
|
+
if tg_choice == 'y':
|
|
107
|
+
print("\n--- Telegram Setup Guide ---")
|
|
108
|
+
print("a. Open Telegram app and search for '@BotFather'")
|
|
109
|
+
print("b. Send '/newbot' and follow steps to get your HTTP API Token.")
|
|
110
|
+
cfg.telegram_bot_token = input("Paste your Bot Token here: ").strip()
|
|
111
|
+
|
|
112
|
+
print("\nc. Now search for '@userinfobot' on Telegram and send '/start'.")
|
|
113
|
+
print("d. It will reply with your 'Id'.")
|
|
114
|
+
cfg.telegram_chat_id = input("Paste your ID here: ").strip()
|
|
115
|
+
print("----------------------------")
|
|
116
|
+
|
|
117
|
+
cfg.save()
|
|
118
|
+
print("\nβ
Setup complete! Settings saved.\n")
|