sentinel-ai-os 1.0__py3-none-any.whl
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.
- sentinel/__init__.py +0 -0
- sentinel/auth.py +40 -0
- sentinel/cli.py +9 -0
- sentinel/core/__init__.py +0 -0
- sentinel/core/agent.py +298 -0
- sentinel/core/audit.py +48 -0
- sentinel/core/cognitive.py +94 -0
- sentinel/core/config.py +99 -0
- sentinel/core/llm.py +143 -0
- sentinel/core/registry.py +351 -0
- sentinel/core/scheduler.py +61 -0
- sentinel/core/schema.py +11 -0
- sentinel/core/setup.py +101 -0
- sentinel/core/ui.py +112 -0
- sentinel/main.py +110 -0
- sentinel/paths.py +77 -0
- sentinel/tools/__init__.py +0 -0
- sentinel/tools/apps.py +462 -0
- sentinel/tools/audio.py +30 -0
- sentinel/tools/browser.py +66 -0
- sentinel/tools/calendar_ops.py +163 -0
- sentinel/tools/clock.py +25 -0
- sentinel/tools/context.py +40 -0
- sentinel/tools/desktop.py +116 -0
- sentinel/tools/email_ops.py +62 -0
- sentinel/tools/factory.py +125 -0
- sentinel/tools/file_ops.py +81 -0
- sentinel/tools/flights.py +62 -0
- sentinel/tools/gmail_auth.py +47 -0
- sentinel/tools/indexer.py +156 -0
- sentinel/tools/installer.py +69 -0
- sentinel/tools/macros.py +58 -0
- sentinel/tools/memory_ops.py +281 -0
- sentinel/tools/navigation.py +109 -0
- sentinel/tools/notes.py +78 -0
- sentinel/tools/office.py +67 -0
- sentinel/tools/organizer.py +150 -0
- sentinel/tools/smart_index.py +76 -0
- sentinel/tools/sql_index.py +186 -0
- sentinel/tools/system_ops.py +86 -0
- sentinel/tools/vision.py +94 -0
- sentinel/tools/weather_ops.py +59 -0
- sentinel_ai_os-1.0.dist-info/METADATA +282 -0
- sentinel_ai_os-1.0.dist-info/RECORD +48 -0
- sentinel_ai_os-1.0.dist-info/WHEEL +5 -0
- sentinel_ai_os-1.0.dist-info/entry_points.txt +2 -0
- sentinel_ai_os-1.0.dist-info/licenses/LICENSE +21 -0
- sentinel_ai_os-1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import psutil
|
|
2
|
+
import pyperclip
|
|
3
|
+
import subprocess
|
|
4
|
+
import typer
|
|
5
|
+
from sentinel.core.config import ConfigManager
|
|
6
|
+
from sentinel.core.ui import UI
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def switch_model(provider, model=None):
|
|
10
|
+
"""
|
|
11
|
+
Updates configuration and interactively asks for API keys if missing.
|
|
12
|
+
"""
|
|
13
|
+
provider = provider.lower()
|
|
14
|
+
|
|
15
|
+
# Smart Defaults
|
|
16
|
+
defaults = {
|
|
17
|
+
"openai": "gpt-4o",
|
|
18
|
+
"groq": "llama-3.3-70b-versatile",
|
|
19
|
+
"anthropic": "claude-3-5-sonnet-20241022",
|
|
20
|
+
"ollama": "llama3"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if not model:
|
|
24
|
+
model = defaults.get(provider, "gpt-4o")
|
|
25
|
+
|
|
26
|
+
cfg = ConfigManager()
|
|
27
|
+
|
|
28
|
+
# 1. Check if we actually have a key for this provider
|
|
29
|
+
# Ollama is local, so it doesn't need a key.
|
|
30
|
+
existing_key = cfg.get_key(provider)
|
|
31
|
+
needs_key = (provider != "ollama" and not existing_key)
|
|
32
|
+
|
|
33
|
+
if needs_key:
|
|
34
|
+
UI.console.print(f"\n[bold yellow]⚠️ Configuration Required[/bold yellow]")
|
|
35
|
+
UI.console.print(
|
|
36
|
+
f"You are switching to [cyan]{provider.upper()}[/cyan], but no API key was found in the secure vault.")
|
|
37
|
+
|
|
38
|
+
confirm = typer.confirm(f"Would you like to set up {provider.upper()} now?")
|
|
39
|
+
|
|
40
|
+
if confirm:
|
|
41
|
+
new_key = typer.prompt(f"Enter API Key for {provider.upper()}", hide_input=True)
|
|
42
|
+
if new_key:
|
|
43
|
+
cfg.set_key(provider, new_key)
|
|
44
|
+
UI.print_success("API Key stored securely in system keychain.")
|
|
45
|
+
else:
|
|
46
|
+
return "❌ Operation cancelled. Key cannot be empty."
|
|
47
|
+
else:
|
|
48
|
+
return f"❌ Switch cancelled. {provider.upper()} requires an API key."
|
|
49
|
+
|
|
50
|
+
# 2. Apply the switch
|
|
51
|
+
cfg.update_llm(provider, model)
|
|
52
|
+
return f"⚡ Brain updated to [bold green]{provider.upper()}[/bold green] | Model: {model}"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# ... (Keep get_clipboard, get_system_stats, run_cmd, kill_process as they were) ...
|
|
56
|
+
def get_clipboard():
|
|
57
|
+
try:
|
|
58
|
+
return pyperclip.paste()
|
|
59
|
+
except Exception as e:
|
|
60
|
+
return f"Error reading clipboard: {e}"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def get_system_stats():
|
|
64
|
+
cpu = psutil.cpu_percent(interval=0.1)
|
|
65
|
+
memory = psutil.virtual_memory().percent
|
|
66
|
+
return f"CPU: {cpu}% | RAM: {memory}%"
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def run_cmd(cmd):
|
|
70
|
+
try:
|
|
71
|
+
result = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
|
|
72
|
+
return result.decode('utf-8').strip()
|
|
73
|
+
except Exception as e:
|
|
74
|
+
return f"Error: {e}"
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def kill_process(name):
|
|
78
|
+
killed_count = 0
|
|
79
|
+
for proc in psutil.process_iter(['pid', 'name']):
|
|
80
|
+
try:
|
|
81
|
+
if name.lower() in proc.info['name'].lower():
|
|
82
|
+
proc.kill()
|
|
83
|
+
killed_count += 1
|
|
84
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
|
85
|
+
pass
|
|
86
|
+
return f"Killed {killed_count} process(es) matching '{name}'."
|
sentinel/tools/vision.py
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import os
|
|
3
|
+
import pyautogui
|
|
4
|
+
import cv2
|
|
5
|
+
from litellm import completion
|
|
6
|
+
from sentinel.core.config import ConfigManager
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_llm_env():
|
|
10
|
+
"""
|
|
11
|
+
Dynamically load latest keys into env for LiteLLM.
|
|
12
|
+
"""
|
|
13
|
+
cfg = ConfigManager()
|
|
14
|
+
provider = cfg.get("llm.provider")
|
|
15
|
+
model = cfg.get("llm.model")
|
|
16
|
+
|
|
17
|
+
if provider == "openai":
|
|
18
|
+
os.environ["OPENAI_API_KEY"] = cfg.get_key("openai") or ""
|
|
19
|
+
elif provider == "anthropic":
|
|
20
|
+
os.environ["ANTHROPIC_API_KEY"] = cfg.get_key("anthropic") or ""
|
|
21
|
+
elif provider == "groq":
|
|
22
|
+
os.environ["GROQ_API_KEY"] = cfg.get_key("groq") or ""
|
|
23
|
+
|
|
24
|
+
full_model = f"{provider}/{model}"
|
|
25
|
+
return full_model
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def encode_image(path):
|
|
29
|
+
with open(path, "rb") as f:
|
|
30
|
+
return base64.b64encode(f.read()).decode("utf-8")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _analyze_image(image_path, prompt):
|
|
34
|
+
try:
|
|
35
|
+
full_model = get_llm_env()
|
|
36
|
+
base64_img = encode_image(image_path)
|
|
37
|
+
|
|
38
|
+
message = {
|
|
39
|
+
"role": "user",
|
|
40
|
+
"content": [
|
|
41
|
+
{"type": "text", "text": prompt},
|
|
42
|
+
{
|
|
43
|
+
"type": "image_url",
|
|
44
|
+
"image_url": {"url": f"data:image/png;base64,{base64_img}"}
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
response = completion(
|
|
50
|
+
model=full_model,
|
|
51
|
+
messages=[message],
|
|
52
|
+
max_tokens=500
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
return response.choices[0].message.content
|
|
56
|
+
|
|
57
|
+
except Exception as e:
|
|
58
|
+
return (
|
|
59
|
+
f"Vision Error: {e}\n"
|
|
60
|
+
f"Tip: Ensure model supports vision "
|
|
61
|
+
f"(e.g. gpt-4o, claude-3-5-sonnet, llava)."
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def analyze_screen(prompt="Describe the contents of this screen"):
|
|
66
|
+
screenshot_path = "temp_vision.png"
|
|
67
|
+
try:
|
|
68
|
+
pyautogui.screenshot(screenshot_path)
|
|
69
|
+
result = _analyze_image(screenshot_path, prompt)
|
|
70
|
+
return f"[Vision Result]: {result}"
|
|
71
|
+
except Exception as e:
|
|
72
|
+
return f"Screen capture error: {e}"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def capture_webcam(prompt="Describe what you see"):
|
|
76
|
+
try:
|
|
77
|
+
cap = cv2.VideoCapture(0)
|
|
78
|
+
if not cap.isOpened():
|
|
79
|
+
return "Error: Could not open webcam."
|
|
80
|
+
|
|
81
|
+
ret, frame = cap.read()
|
|
82
|
+
cap.release()
|
|
83
|
+
|
|
84
|
+
if not ret:
|
|
85
|
+
return "Error: Failed to capture image."
|
|
86
|
+
|
|
87
|
+
filename = "temp_webcam.png"
|
|
88
|
+
cv2.imwrite(filename, frame)
|
|
89
|
+
|
|
90
|
+
result = _analyze_image(filename, prompt)
|
|
91
|
+
return f"[Webcam Result]: {result}"
|
|
92
|
+
|
|
93
|
+
except Exception as e:
|
|
94
|
+
return f"Webcam error: {e}"
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def get_current_weather(location=""):
|
|
5
|
+
"""
|
|
6
|
+
Gets current weather for a location (or auto-detects if empty).
|
|
7
|
+
Uses wttr.in (No API key required).
|
|
8
|
+
"""
|
|
9
|
+
try:
|
|
10
|
+
# Format 3 gives a concise one-line output: "Paris: ⛅️ +14°C"
|
|
11
|
+
url = f"https://wttr.in/{location}?format=4"
|
|
12
|
+
response = requests.get(url, timeout=5)
|
|
13
|
+
|
|
14
|
+
if response.status_code == 200:
|
|
15
|
+
return f"Weather: {response.text.strip()}"
|
|
16
|
+
else:
|
|
17
|
+
return "Error fetching weather."
|
|
18
|
+
except Exception as e:
|
|
19
|
+
return f"Weather connection error: {e}"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_weather_forecast(location=""):
|
|
23
|
+
"""
|
|
24
|
+
Gets a 3-day forecast description from wttr.in
|
|
25
|
+
"""
|
|
26
|
+
try:
|
|
27
|
+
url = f"https://wttr.in/{location}?format=j2"
|
|
28
|
+
response = requests.get(url, timeout=5)
|
|
29
|
+
|
|
30
|
+
if response.status_code != 200:
|
|
31
|
+
return "Error fetching forecast."
|
|
32
|
+
|
|
33
|
+
data = response.json()
|
|
34
|
+
|
|
35
|
+
# ---- Current conditions ----
|
|
36
|
+
current = data["current_condition"][0]
|
|
37
|
+
desc = current["weatherDesc"][0]["value"]
|
|
38
|
+
temp = current["temp_C"]
|
|
39
|
+
feels = current["FeelsLikeC"]
|
|
40
|
+
|
|
41
|
+
# ---- 3-day forecast ----
|
|
42
|
+
forecast_lines = []
|
|
43
|
+
for day in data["weather"][:3]:
|
|
44
|
+
date = day["date"]
|
|
45
|
+
min_t = day["mintempC"]
|
|
46
|
+
max_t = day["maxtempC"]
|
|
47
|
+
forecast_lines.append(
|
|
48
|
+
f"{date}: {min_t}°C → {max_t}°C"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
forecast_text = "\n".join(forecast_lines)
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
f"Current: {desc}, {temp}°C (Feels like {feels}°C)\n\n"
|
|
55
|
+
f"3-Day Forecast:\n{forecast_text}"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
except Exception:
|
|
59
|
+
return get_current_weather(location)
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sentinel-ai-os
|
|
3
|
+
Version: 1.0
|
|
4
|
+
Summary: Autonomous AI Operating System layer
|
|
5
|
+
Author-email: Sam Selvaraj <samselvaraj1801@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: ai,agent,automation,llm
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: rich
|
|
14
|
+
Requires-Dist: typer[all]
|
|
15
|
+
Requires-Dist: pydantic
|
|
16
|
+
Requires-Dist: tabulate
|
|
17
|
+
Requires-Dist: markdown
|
|
18
|
+
Requires-Dist: schedule
|
|
19
|
+
Requires-Dist: keyring
|
|
20
|
+
Requires-Dist: tzlocal
|
|
21
|
+
Requires-Dist: psutil
|
|
22
|
+
Requires-Dist: litellm
|
|
23
|
+
Requires-Dist: anthropic
|
|
24
|
+
Requires-Dist: groq
|
|
25
|
+
Requires-Dist: openai
|
|
26
|
+
Requires-Dist: chromadb
|
|
27
|
+
Requires-Dist: tavily
|
|
28
|
+
Requires-Dist: requests
|
|
29
|
+
Requires-Dist: beautifulsoup4
|
|
30
|
+
Requires-Dist: duckduckgo-search
|
|
31
|
+
Requires-Dist: ddgs
|
|
32
|
+
Requires-Dist: googlemaps
|
|
33
|
+
Requires-Dist: google-auth
|
|
34
|
+
Requires-Dist: google-auth-oauthlib
|
|
35
|
+
Requires-Dist: google-auth-httplib2
|
|
36
|
+
Requires-Dist: google-api-python-client
|
|
37
|
+
Requires-Dist: pandas
|
|
38
|
+
Requires-Dist: openpyxl
|
|
39
|
+
Requires-Dist: python-docx
|
|
40
|
+
Requires-Dist: fpdf
|
|
41
|
+
Requires-Dist: docx2pdf
|
|
42
|
+
Requires-Dist: pymupdf
|
|
43
|
+
Requires-Dist: pypdf
|
|
44
|
+
Requires-Dist: pyautogui
|
|
45
|
+
Requires-Dist: pygetwindow
|
|
46
|
+
Requires-Dist: screen_brightness_control
|
|
47
|
+
Requires-Dist: pycaw
|
|
48
|
+
Requires-Dist: comtypes
|
|
49
|
+
Requires-Dist: pyperclip
|
|
50
|
+
Requires-Dist: plyer
|
|
51
|
+
Requires-Dist: pyttsx3
|
|
52
|
+
Requires-Dist: pillow
|
|
53
|
+
Requires-Dist: opencv-python
|
|
54
|
+
Requires-Dist: SpeechRecognition
|
|
55
|
+
Requires-Dist: pyaudio
|
|
56
|
+
Dynamic: license-file
|
|
57
|
+
|
|
58
|
+
<img width="1065" height="226" alt="image" src="https://github.com/user-attachments/assets/d8c6fede-1cd8-4517-b626-2deb2d9bd9c5" />
|
|
59
|
+
|
|
60
|
+
> **Your proactive OS assistant.** Sentinel is a terminal-based autonomous agent that integrates deeply with your local operating system, files, and cloud services to execute complex workflows via natural language.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 📖 Table of Contents
|
|
65
|
+
|
|
66
|
+
* [Overview](#-overview)
|
|
67
|
+
* [Key Features](#-key-features)
|
|
68
|
+
* [System Architecture](#-system-architecture)
|
|
69
|
+
* [Installation & Setup](#-installation--setup)
|
|
70
|
+
* [Configuration](#-configuration)
|
|
71
|
+
* [Usage Guide](#-usage-guide)
|
|
72
|
+
* [Available Tools](#-available-tools)
|
|
73
|
+
* [Contributing](#-contributing)
|
|
74
|
+
* [Safety & Privacy](#-safety--privacy)
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 🔭 Overview
|
|
79
|
+
<img width="1127" height="550" alt="image" src="https://github.com/user-attachments/assets/9ac617d6-a959-4a8c-b245-ff2c98f083ea" />
|
|
80
|
+
|
|
81
|
+
Sentinel is not just a chatbot; it is an **Action Engine**. Unlike web-based LLMs that live in a sandbox, Sentinel runs locally on your machine with access to your file system, applications, and peripherals.
|
|
82
|
+
|
|
83
|
+
It operates on a **Think-Plan-Act** loop:
|
|
84
|
+
|
|
85
|
+
1. **Perceives** user intent via natural language.
|
|
86
|
+
2. **Retrieves** context from its long-term vector memory and local SQL file index.
|
|
87
|
+
3. **Selects** specific tools from a registry (e.g., "Send Email", "Search Files", "Analyze Screen").
|
|
88
|
+
4. **Executes** the action safely (asking for permission when necessary).
|
|
89
|
+
5. **Learns** from the interaction to build a persistent user profile.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## ✨ Key Features
|
|
94
|
+
<img width="2836" height="1338" alt="image" src="https://github.com/user-attachments/assets/877e5ec8-f398-4c04-b0b0-0c45b12d08c8" />
|
|
95
|
+
|
|
96
|
+
* **🧠 Multi-Brain Support:** Powered by `litellm`, Sentinel can seamlessly switch between **OpenAI**, **Anthropic**, **Groq**, or run locally with **Ollama**.
|
|
97
|
+
* **💾 Hybrid Memory Architecture:**
|
|
98
|
+
* **Vector Database (ChromaDB):** Stores semantic memories, facts, and user preferences for long-term recall.
|
|
99
|
+
* **SQL Index (SQLite):** Maintains a lightning-fast index of your local filesystem for rapid file retrieval.
|
|
100
|
+
* **🔌 Deep OS Integration:**
|
|
101
|
+
* Launch/close apps, manage processes, and control system volume/brightness.
|
|
102
|
+
* Organize messy folders, bulk rename files, and create documents.
|
|
103
|
+
* "Digital Twin" context awareness (knows what app you are using).
|
|
104
|
+
* **☁️ Google Workspace Native:**
|
|
105
|
+
* Full 2-way sync with **Google Calendar** and **Gmail**.
|
|
106
|
+
* Natural language scheduling ("Clear my afternoon", "Draft an email to Bob").
|
|
107
|
+
* **👀 Computer Vision:** Analyze your screen or webcam feed using Vision-capable models (GPT-4o, Claude 3.5 Sonnet).
|
|
108
|
+
* **🛡️ Safety First:** "Human-in-the-loop" protocols require user approval for high-risk actions like deleting files, sending emails, or executing shell commands.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 🏗 System Architecture
|
|
113
|
+
|
|
114
|
+
Sentinel is built on a modular Python architecture designed for extensibility.
|
|
115
|
+
|
|
116
|
+
### Core Components
|
|
117
|
+
|
|
118
|
+
* **`main.py`**: The entry point. Handles CLI arguments using `typer` and initiates the boot sequence.
|
|
119
|
+
* **`core/agent.py`**: The main agent loop. Manages the context window, parses JSON responses from the LLM, and triggers tools.
|
|
120
|
+
* **`core/llm.py`**: A unified wrapper for different API providers (via `litellm`) that handles model selection, streaming, and error recovery.
|
|
121
|
+
* **`core/registry.py`**: The "Tool Belt." Maps natural language tool descriptions to actual Python functions and injects safety wrappers like `ask_permission`.
|
|
122
|
+
* **`tools/`**: A directory containing isolated modules for specific capabilities (e.g., `browser.py`, `file_ops.py`, `vision.py`).
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 🚀 Installation & Setup
|
|
127
|
+
|
|
128
|
+
### Prerequisites
|
|
129
|
+
|
|
130
|
+
* Python 3.9 or higher.
|
|
131
|
+
* (Optional) **Ollama** installed for local offline inference.
|
|
132
|
+
* (Optional) A Google Cloud Console project for Gmail/Calendar integration.
|
|
133
|
+
|
|
134
|
+
### Step 1: Install from PyPI
|
|
135
|
+
|
|
136
|
+
As a published package, you can install Sentinel directly using pip:
|
|
137
|
+
```bash
|
|
138
|
+
pip install sentinel-ai
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Step 2: System Boot & Configuration
|
|
142
|
+
|
|
143
|
+
Run the initial setup wizard. This will guide you through setting your name, location, and API keys, which are stored securely using the `keyring` library.
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
sentinel config
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Step 3: Google Authentication (Optional but Recommended)
|
|
150
|
+
|
|
151
|
+
To enable Calendar and Gmail features:
|
|
152
|
+
|
|
153
|
+
1. Download your OAuth 2.0 Client ID JSON from your Google Cloud Console project.
|
|
154
|
+
2. Rename it to `credentials.json` and place it in the directory where you run Sentinel.
|
|
155
|
+
3. Run the auth repair tool. This will open a browser window to authorize Sentinel.
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
sentinel auth
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## ⚙ Configuration
|
|
164
|
+
|
|
165
|
+
Sentinel stores its primary configuration in `config.json` and sensitive API keys in your OS's secure credential manager.
|
|
166
|
+
|
|
167
|
+
**Supported Services:**
|
|
168
|
+
|
|
169
|
+
* **Primary Brains:** OpenAI, Anthropic, Groq, Ollama
|
|
170
|
+
* **Search Tools:** Tavily (recommended for RAG), DuckDuckGo
|
|
171
|
+
* **Navigation:** Google Maps API
|
|
172
|
+
|
|
173
|
+
To view or update keys after the initial setup, you can re-run the configuration wizard:
|
|
174
|
+
```bash
|
|
175
|
+
sentinel config
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 🎮 Usage Guide
|
|
181
|
+
|
|
182
|
+
Start the agent's interactive shell:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
sentinel
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Or, start with a daily briefing (Weather, Calendar, Email summary):
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
sentinel --briefing
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Interactive CLI
|
|
195
|
+
|
|
196
|
+
Once inside the Sentinel shell, you can communicate with the agent using natural language.
|
|
197
|
+
|
|
198
|
+
### Example Natural Language Prompts
|
|
199
|
+
|
|
200
|
+
* *"Find all PDF files on my Desktop modified last week and move them to a folder named Reports."*
|
|
201
|
+
* *"Summarize the last 5 emails from my boss."*
|
|
202
|
+
* *"Take a screenshot and tell me what code is visible."*
|
|
203
|
+
* *"Plan a trip to New York for next weekend, check flights, and add it to my calendar."*
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 🛠 Available Tools
|
|
208
|
+
|
|
209
|
+
Sentinel comes equipped with a vast array of tools, dynamically registered and made available to the LLM. Below is a summary of its capabilities.
|
|
210
|
+
|
|
211
|
+
### 📂 File System & Indexing
|
|
212
|
+
|
|
213
|
+
* **Smart Search:** Uses SQLite `fts5` for fast filename search and a Vector index for semantic content search ("Find that document about the project budget").
|
|
214
|
+
* **File Operations:** Full CRUD (Create, Read, Write) for files.
|
|
215
|
+
* **Code Drafts:** Safely drafts code to a `drafts/` directory for user review, never executing it directly.
|
|
216
|
+
* **Organization:** Bulk rename files or sort them into folders based on date, extension, or other criteria.
|
|
217
|
+
* **Document Factory:** Create Word (`.docx`) and Excel (`.xlsx`) files from scratch.
|
|
218
|
+
|
|
219
|
+
### 🌐 Web & Knowledge
|
|
220
|
+
|
|
221
|
+
* **Deep Research:** Uses Tavily API to browse the web, scrape content, and synthesize answers.
|
|
222
|
+
* **Browser Automation:** Can open URLs and extract text from webpages.
|
|
223
|
+
* **Flight Search:** Find flight information via the SerperDev API.
|
|
224
|
+
|
|
225
|
+
### 🖥️ Desktop Automation & OS
|
|
226
|
+
|
|
227
|
+
* **App Launcher:** Intelligent fuzzy matching to launch and close applications.
|
|
228
|
+
* **System Control:** Set volume, brightness, or execute shell commands (with permission).
|
|
229
|
+
* **Process Management:** List and kill running processes.
|
|
230
|
+
* **Macros:** Execute pre-defined sequences of actions.
|
|
231
|
+
|
|
232
|
+
### 👀 Perception & Vision
|
|
233
|
+
|
|
234
|
+
* **Screen Analysis:** `analyze_screen` allows the agent to "see" and understand the content on your display.
|
|
235
|
+
* **Webcam Capture:** Use the webcam to capture images for analysis.
|
|
236
|
+
* **Speech I/O:** `listen` to user voice commands and `speak` to provide audio responses.
|
|
237
|
+
* **Context Awareness:** Can identify the currently active application window.
|
|
238
|
+
|
|
239
|
+
### 🧠 Memory & Cognition
|
|
240
|
+
|
|
241
|
+
* **Long-term Memory:** Stores facts and user preferences (e.g., "User prefers dark mode") in ChromaDB for future interactions.
|
|
242
|
+
* **Note Taking:** A simple system for adding and retrieving categorized notes.
|
|
243
|
+
* **Reflection:** Can look back at logs to provide continuity across sessions.
|
|
244
|
+
|
|
245
|
+
### 📅 Calendar & Email (Google Workspace)
|
|
246
|
+
|
|
247
|
+
* **Full Calendar Control:** List, create, and query events on your Google Calendar.
|
|
248
|
+
* **Gmail Integration:** Read and send emails through your Gmail account.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## 🤝 Contributing
|
|
253
|
+
|
|
254
|
+
We welcome contributions! Sentinel is designed to be easily extensible.
|
|
255
|
+
|
|
256
|
+
### Directory Structure
|
|
257
|
+
|
|
258
|
+
* `sentinel/core/`: The brain. Modify this if you are improving the LLM loop, context management, or configuration.
|
|
259
|
+
* `sentinel/tools/`: The hands. **This is the best place to start.** Add new capabilities here.
|
|
260
|
+
|
|
261
|
+
### How to Add a New Tool
|
|
262
|
+
|
|
263
|
+
1. Create a new Python file in `sentinel/tools/` (e.g., `spotify.py`).
|
|
264
|
+
2. Define your function(s) in that file.
|
|
265
|
+
3. Import your function into `sentinel/core/registry.py`.
|
|
266
|
+
4. Add the function to the `TOOLS` dictionary in `registry.py`, wrapping it in `ask_permission` if it's a high-risk action.
|
|
267
|
+
5. Add a description of the tool and its arguments to the `SYSTEM_PROMPT` in `registry.py` so the LLM knows how to use it.
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## 🛡 Safety & Privacy
|
|
272
|
+
|
|
273
|
+
Because Sentinel has deep access to your system, safety is a core design principle.
|
|
274
|
+
|
|
275
|
+
1. **Permission Gate:** Critical tools (File Deletion, Shell Commands, Sending Email, etc.) are wrapped in the `ask_permission` function. The agent's execution pauses until you explicitly approve the action by typing `y`.
|
|
276
|
+
2. **Safe Code Drafting:** Sentinel never executes code it generates. It uses the `draft_code` tool to save scripts to a `drafts/` directory, allowing you to review them before manual execution.
|
|
277
|
+
3. **Command Guardrails:** The `run_cmd` tool has extra checks to prevent accidental use of destructive commands like `rm` or `format`.
|
|
278
|
+
4. **Local First:** All file indexes (SQL and ChromaDB) are stored locally in your user directory. No file data is sent to the cloud except for the specific text chunks required by the LLM API for a given task. Your API keys are stored securely in your operating system's native credential manager.
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
**Disclaimer:** *Sentinel is an autonomous agent. While many safety checks are in place, always review the actions it proposes before approving them, especially those involving file modification or shell command execution.*
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
sentinel/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
sentinel/auth.py,sha256=T_cP-0NEtnrWU93vlkKYaqUDRVKCO1PD5T616v_YbyM,1071
|
|
3
|
+
sentinel/cli.py,sha256=nMGUOc5BrBNj9wnzpv8GNt8-c1a19V6RBvtdmD8KFIM,226
|
|
4
|
+
sentinel/main.py,sha256=42ijKl0119pFpXXZipT4BtOI174_KwwkC8XSLwSHt_M,3092
|
|
5
|
+
sentinel/paths.py,sha256=IeG4p4nUrJDrS7wpp7c2lM2hk3HHzBITVxqzUpf8K3k,2551
|
|
6
|
+
sentinel/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
sentinel/core/agent.py,sha256=Z4qK1r3-xGz8PZHJj7q49Fb-h0TrInrDcYHiBYQVVj0,11431
|
|
8
|
+
sentinel/core/audit.py,sha256=EgtNeDY76ZKFufMTuH3yqnUBXyI6uEo_-s6P5PBqdq4,1453
|
|
9
|
+
sentinel/core/cognitive.py,sha256=2GSOeDaVgpVbIIhriThhZkbcs2NvZuu95OHYx9BgOFg,2749
|
|
10
|
+
sentinel/core/config.py,sha256=LaeSoDIc0YpRZEAgwf3d0Pi1wcnep2yPtiqH9U_KiVY,3296
|
|
11
|
+
sentinel/core/llm.py,sha256=qzxtZyRsx8ac_gcy9BcZncD41ZP617OIbF9Iirw0z60,5917
|
|
12
|
+
sentinel/core/registry.py,sha256=Holt9TLwK7Wks_uhMk6VkyNsnOIVKqynKV57nagtPHU,11497
|
|
13
|
+
sentinel/core/scheduler.py,sha256=s_WynyY1P2pxUq-v72bfDg8285talEZU0NBt1nPyF4Y,1807
|
|
14
|
+
sentinel/core/schema.py,sha256=x3oabPJIP3o2fH8cQo6BMCyoFJ65RvqqY5fHFGrzRuM,349
|
|
15
|
+
sentinel/core/setup.py,sha256=P0Lh-PMXa0ULWSjVQ84iCG4PIB0Push1gdWZe5WKpRY,3573
|
|
16
|
+
sentinel/core/ui.py,sha256=ZjiUWUgGtTmuoVwS2fa_LFA6TsCQ9eFFoAWX-9w0XSQ,4381
|
|
17
|
+
sentinel/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
+
sentinel/tools/apps.py,sha256=YN5kIPNV1M4UYH5FbQGCwWNyVMlLAz9_B9ibKfJm2lE,16667
|
|
19
|
+
sentinel/tools/audio.py,sha256=UFEZvxtaLT243-bwvrBPouDqaUX_I9w-yf6MJiGJpfc,934
|
|
20
|
+
sentinel/tools/browser.py,sha256=qi9tWNtssUgEbodpaG_18c4CoibddW9GwJYlS8pSUmQ,2168
|
|
21
|
+
sentinel/tools/calendar_ops.py,sha256=ru57V_DE8nH__gAPwGMuN2FsdDr73uLtTSr5gq6qRg8,4848
|
|
22
|
+
sentinel/tools/clock.py,sha256=T-v3Flh6oQk-lK8gsG3HlPuu07stK-s94naJvBxRn7Y,984
|
|
23
|
+
sentinel/tools/context.py,sha256=9cmy-rs_BdbtYMlrTYW3xu2nIpH7EEKbKRZdzRmU2T4,1194
|
|
24
|
+
sentinel/tools/desktop.py,sha256=0ApWHU-Qxkmf_e0nRq2m3c40MWluCb4VmLS4du_-4fs,2907
|
|
25
|
+
sentinel/tools/email_ops.py,sha256=mEg6xL-wDRk6-Eid44hXDGtiSIITT06IKmQrCExDk7o,2251
|
|
26
|
+
sentinel/tools/factory.py,sha256=FsgVJrqd0WkNsS7yojPu_4uQ_fLKAmMiTMtqcbahCFA,4520
|
|
27
|
+
sentinel/tools/file_ops.py,sha256=aXUmwp-UIRNBPvQDXvXOKeNGDLJ_trgbvyzvPu2Qq_I,2568
|
|
28
|
+
sentinel/tools/flights.py,sha256=Hq7uLo_6RI7ymOITD0TZKypUdr0uYnJtGXBliScLL08,1822
|
|
29
|
+
sentinel/tools/gmail_auth.py,sha256=d9VFjApohlTQsvtCatoxQEtHR0aWRsWO0CQn10dGHvs,1691
|
|
30
|
+
sentinel/tools/indexer.py,sha256=G4I1t8h7FgYKVMP1IIM8EMYhNtQTtOsJvsUiCypwJG8,5645
|
|
31
|
+
sentinel/tools/installer.py,sha256=ItCKH2SlW019_D4K-3hbhuKAEmStFnUg7cF2WxeLIVY,1723
|
|
32
|
+
sentinel/tools/macros.py,sha256=iLhn781z4XObfhd0bJvaScRkL9fMIRk8_MiFrea3sA0,1578
|
|
33
|
+
sentinel/tools/memory_ops.py,sha256=ZNbtfuX6kfu0eMHsS_w5W50cUpJXGJ-gK_mwx1r6K5M,8123
|
|
34
|
+
sentinel/tools/navigation.py,sha256=8tB37xUIcO-57JlHa5bzuShffyhYoGNoJkAXOQQ5Cos,3282
|
|
35
|
+
sentinel/tools/notes.py,sha256=67eD9HQZfbGsYmFm2hQ6OUtS0zQsw_k6NSX7S5n__xM,2019
|
|
36
|
+
sentinel/tools/office.py,sha256=qoICUPdmhDjnBbgV0FJHQrihTXD7PyRSLgC-bt27Fdk,2177
|
|
37
|
+
sentinel/tools/organizer.py,sha256=zUabr6CRXOV5LAGYqFlB021AvSzh1K5dojLlxTZ_sUA,5191
|
|
38
|
+
sentinel/tools/smart_index.py,sha256=pgemHu4JlVdQbUFS7z85ilsH4ZPi0jGfmXqhYvvNcIA,1840
|
|
39
|
+
sentinel/tools/sql_index.py,sha256=xm9ey2Rjy8EnHYRU5mDOwp5s6MspF_s_BGxp84I0SKw,6367
|
|
40
|
+
sentinel/tools/system_ops.py,sha256=2yhDQe6pAb626jbf3FMXcP4fj33c7IIBVaNBPelb81E,2809
|
|
41
|
+
sentinel/tools/vision.py,sha256=VfCSiZ-RJvqxQWm1jl6xfVdJv-OB6MHvt8OmEujn4CY,2582
|
|
42
|
+
sentinel/tools/weather_ops.py,sha256=e32FCR9HtE-DqlVJIb6QgPqoNoUd7esE0Fut5p1DygA,1774
|
|
43
|
+
sentinel_ai_os-1.0.dist-info/licenses/LICENSE,sha256=40oa9ZxNrrfZI6ezONZ1Mhm8uIaXviB4sC6GOFPTDPk,1088
|
|
44
|
+
sentinel_ai_os-1.0.dist-info/METADATA,sha256=YEzfabkonOdulajAgQxBVVxrfcgwC6zKXSsqd8vGtZg,11780
|
|
45
|
+
sentinel_ai_os-1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
46
|
+
sentinel_ai_os-1.0.dist-info/entry_points.txt,sha256=lM13uXDC1VH0W4OITOhMkcxEJVyF_Xlw3rJEsgDs0nM,47
|
|
47
|
+
sentinel_ai_os-1.0.dist-info/top_level.txt,sha256=tffn0oUCkyTZs6yuGcwFCZJxRUrJi_wFmpKwWBYlzVE,9
|
|
48
|
+
sentinel_ai_os-1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sam Selvaraj
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
sentinel
|