ansh-assistant 1.0.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.
- ansh_assistant-1.0.0/MANIFEST.in +22 -0
- ansh_assistant-1.0.0/PKG-INFO +202 -0
- ansh_assistant-1.0.0/actions/automation_engine.py +250 -0
- ansh_assistant-1.0.0/actions/browser_control.py +1102 -0
- ansh_assistant-1.0.0/actions/code_helper.py +594 -0
- ansh_assistant-1.0.0/actions/computer_control.py +551 -0
- ansh_assistant-1.0.0/actions/computer_settings.py +724 -0
- ansh_assistant-1.0.0/actions/desktop.py +585 -0
- ansh_assistant-1.0.0/actions/dev_agent.py +620 -0
- ansh_assistant-1.0.0/actions/document_generator.py +256 -0
- ansh_assistant-1.0.0/actions/email_sender.py +20 -0
- ansh_assistant-1.0.0/actions/file_controller.py +728 -0
- ansh_assistant-1.0.0/actions/file_processor.py +840 -0
- ansh_assistant-1.0.0/actions/flight_finder.py +360 -0
- ansh_assistant-1.0.0/actions/game_updater.py +1054 -0
- ansh_assistant-1.0.0/actions/interactive_games.py +157 -0
- ansh_assistant-1.0.0/actions/memory_actions.py +125 -0
- ansh_assistant-1.0.0/actions/open_app.py +278 -0
- ansh_assistant-1.0.0/actions/phone_hub.py +176 -0
- ansh_assistant-1.0.0/actions/proactive.py +72 -0
- ansh_assistant-1.0.0/actions/reminder.py +337 -0
- ansh_assistant-1.0.0/actions/screen_peeler.py +134 -0
- ansh_assistant-1.0.0/actions/screen_processor.py +481 -0
- ansh_assistant-1.0.0/actions/send_message.py +481 -0
- ansh_assistant-1.0.0/actions/system_monitor.py +203 -0
- ansh_assistant-1.0.0/actions/weather_report.py +51 -0
- ansh_assistant-1.0.0/actions/web_search.py +334 -0
- ansh_assistant-1.0.0/actions/wormhole.py +169 -0
- ansh_assistant-1.0.0/actions/youtube_video.py +454 -0
- ansh_assistant-1.0.0/ansh_assistant.egg-info/PKG-INFO +202 -0
- ansh_assistant-1.0.0/ansh_assistant.egg-info/SOURCES.txt +100 -0
- ansh_assistant-1.0.0/ansh_assistant.egg-info/dependency_links.txt +1 -0
- ansh_assistant-1.0.0/ansh_assistant.egg-info/entry_points.txt +2 -0
- ansh_assistant-1.0.0/ansh_assistant.egg-info/requires.txt +39 -0
- ansh_assistant-1.0.0/ansh_assistant.egg-info/top_level.txt +12 -0
- ansh_assistant-1.0.0/config/__init__.py +26 -0
- ansh_assistant-1.0.0/config/security_config.py +24 -0
- ansh_assistant-1.0.0/core/__init__.py +1 -0
- ansh_assistant-1.0.0/core/agi_memory.py +125 -0
- ansh_assistant-1.0.0/core/agi_planner.py +233 -0
- ansh_assistant-1.0.0/core/agi_proactive.py +66 -0
- ansh_assistant-1.0.0/core/airtouch.py +284 -0
- ansh_assistant-1.0.0/core/authentication.py +185 -0
- ansh_assistant-1.0.0/core/auto_updater.py +167 -0
- ansh_assistant-1.0.0/core/cli_interface.py +159 -0
- ansh_assistant-1.0.0/core/installer.py +143 -0
- ansh_assistant-1.0.0/core/license_manager.py +141 -0
- ansh_assistant-1.0.0/core/llm_client.py +605 -0
- ansh_assistant-1.0.0/core/password_manager.py +147 -0
- ansh_assistant-1.0.0/core/permissions.py +78 -0
- ansh_assistant-1.0.0/core/prompt.txt +82 -0
- ansh_assistant-1.0.0/core/skills_manager.py +119 -0
- ansh_assistant-1.0.0/core/speaker_verification.py +215 -0
- ansh_assistant-1.0.0/core/stt.py +96 -0
- ansh_assistant-1.0.0/core/task_llm.py +235 -0
- ansh_assistant-1.0.0/core/telegram_bot.py +648 -0
- ansh_assistant-1.0.0/core/tts.py +579 -0
- ansh_assistant-1.0.0/core/voice_enrollment.py +100 -0
- ansh_assistant-1.0.0/dashboard/__init__.py +0 -0
- ansh_assistant-1.0.0/dashboard/screen_streamer.py +351 -0
- ansh_assistant-1.0.0/dashboard/server.py +960 -0
- ansh_assistant-1.0.0/dashboard/static/app.html +1236 -0
- ansh_assistant-1.0.0/dashboard/static/crypto-js.min.js +1 -0
- ansh_assistant-1.0.0/dashboard/static/login.html +109 -0
- ansh_assistant-1.0.0/dashboard/static/smart_island.html +1126 -0
- ansh_assistant-1.0.0/face.png +0 -0
- ansh_assistant-1.0.0/keys/valid_keys.json +204 -0
- ansh_assistant-1.0.0/location.py +116 -0
- ansh_assistant-1.0.0/main.py +2061 -0
- ansh_assistant-1.0.0/memory/__init__.py +1 -0
- ansh_assistant-1.0.0/memory/config_manager.py +129 -0
- ansh_assistant-1.0.0/memory/indexer.py +238 -0
- ansh_assistant-1.0.0/memory/long_term.json +31 -0
- ansh_assistant-1.0.0/memory/markdown_store.py +293 -0
- ansh_assistant-1.0.0/memory/memory_manager.py +158 -0
- ansh_assistant-1.0.0/memory/memory_service.py +340 -0
- ansh_assistant-1.0.0/memory/storage/identity.md +17 -0
- ansh_assistant-1.0.0/memory/storage/knowledge.md +1 -0
- ansh_assistant-1.0.0/memory/storage/notes.md +1 -0
- ansh_assistant-1.0.0/memory/storage/personal.md +18 -0
- ansh_assistant-1.0.0/memory/storage/preferences.md +10 -0
- ansh_assistant-1.0.0/memory/storage/procedures.md +1 -0
- ansh_assistant-1.0.0/memory/storage/projects.md +9 -0
- ansh_assistant-1.0.0/memory/storage/relationships.md +1 -0
- ansh_assistant-1.0.0/memory/storage/wishes.md +1 -0
- ansh_assistant-1.0.0/pyproject.toml +84 -0
- ansh_assistant-1.0.0/readme.md +144 -0
- ansh_assistant-1.0.0/requirements.txt +52 -0
- ansh_assistant-1.0.0/setup.cfg +4 -0
- ansh_assistant-1.0.0/skills/automation_workflows.json +16 -0
- ansh_assistant-1.0.0/skills/coding_agent.json +8 -0
- ansh_assistant-1.0.0/skills/hardware_telemetry.json +8 -0
- ansh_assistant-1.0.0/skills/phone_gateway.json +8 -0
- ansh_assistant-1.0.0/skills/screen_remote.json +14 -0
- ansh_assistant-1.0.0/skills/universal_clipboard.json +8 -0
- ansh_assistant-1.0.0/smart_island.py +1008 -0
- ansh_assistant-1.0.0/smart_ui.py +1104 -0
- ansh_assistant-1.0.0/tests/test_agi_engine.py +106 -0
- ansh_assistant-1.0.0/tests/test_license_manager.py +76 -0
- ansh_assistant-1.0.0/tests/test_voice_auth.py +178 -0
- ansh_assistant-1.0.0/ui.py +3736 -0
- ansh_assistant-1.0.0/version_info.txt +28 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
include face.png
|
|
2
|
+
include readme.md
|
|
3
|
+
include requirements.txt
|
|
4
|
+
include version_info.txt
|
|
5
|
+
include keys/valid_keys.json
|
|
6
|
+
|
|
7
|
+
recursive-include config *.json
|
|
8
|
+
recursive-include skills *.json
|
|
9
|
+
recursive-include memory/storage *.md
|
|
10
|
+
recursive-include actions *.py
|
|
11
|
+
recursive-include core *.py
|
|
12
|
+
recursive-include dashboard *
|
|
13
|
+
|
|
14
|
+
global-exclude *.pyc
|
|
15
|
+
global-exclude *.pyo
|
|
16
|
+
global-exclude *~
|
|
17
|
+
global-exclude keys/product_keys.txt
|
|
18
|
+
global-exclude keys/generate_keys.py
|
|
19
|
+
global-exclude config/api_keys.json
|
|
20
|
+
global-exclude config/license.json
|
|
21
|
+
global-exclude *.spec
|
|
22
|
+
global-exclude *.exe
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ansh-assistant
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: ANSH - Your Own AI Friend: Real-time Multimodal Voice Assistant, Smart Island HUD & Autonomous AI System
|
|
5
|
+
Author-email: Anshu Dubey <mastgamerz37@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://getyoursoft.page.gd
|
|
8
|
+
Project-URL: Repository, https://github.com/mastgamerz37-ux/ansh-ai
|
|
9
|
+
Keywords: ai,assistant,voice,gemini,groq,hud,desktop-automation
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Requires-Dist: PyQt6
|
|
22
|
+
Requires-Dist: sounddevice
|
|
23
|
+
Requires-Dist: keyboard
|
|
24
|
+
Requires-Dist: SpeechRecognition
|
|
25
|
+
Requires-Dist: google-genai
|
|
26
|
+
Requires-Dist: google-generativeai
|
|
27
|
+
Requires-Dist: groq
|
|
28
|
+
Requires-Dist: pillow
|
|
29
|
+
Requires-Dist: opencv-python
|
|
30
|
+
Requires-Dist: numpy<2.0.0
|
|
31
|
+
Requires-Dist: mss
|
|
32
|
+
Requires-Dist: pyautogui
|
|
33
|
+
Requires-Dist: pyperclip
|
|
34
|
+
Requires-Dist: pygetwindow
|
|
35
|
+
Requires-Dist: requests
|
|
36
|
+
Requires-Dist: beautifulsoup4
|
|
37
|
+
Requires-Dist: ddgs
|
|
38
|
+
Requires-Dist: playwright
|
|
39
|
+
Requires-Dist: fastapi
|
|
40
|
+
Requires-Dist: uvicorn[standard]
|
|
41
|
+
Requires-Dist: cryptography
|
|
42
|
+
Requires-Dist: python-multipart
|
|
43
|
+
Requires-Dist: qrcode[pil]
|
|
44
|
+
Requires-Dist: psutil
|
|
45
|
+
Requires-Dist: pynvml
|
|
46
|
+
Requires-Dist: send2trash
|
|
47
|
+
Requires-Dist: youtube-transcript-api
|
|
48
|
+
Requires-Dist: python-pptx
|
|
49
|
+
Requires-Dist: python-docx
|
|
50
|
+
Requires-Dist: pypdf
|
|
51
|
+
Requires-Dist: openpyxl
|
|
52
|
+
Requires-Dist: comtypes; sys_platform == "win32"
|
|
53
|
+
Requires-Dist: pycaw; sys_platform == "win32"
|
|
54
|
+
Requires-Dist: win10toast; sys_platform == "win32"
|
|
55
|
+
Requires-Dist: pywinauto; sys_platform == "win32"
|
|
56
|
+
Requires-Dist: pywin32; sys_platform == "win32"
|
|
57
|
+
Requires-Dist: wmi; sys_platform == "win32"
|
|
58
|
+
|
|
59
|
+
<div align="center">
|
|
60
|
+
|
|
61
|
+
# ⚡ ANSH — Your Own AI Friend
|
|
62
|
+
### Autonomous Multimodal Voice Assistant • Smart Island HUD • Real-Time AI Engine
|
|
63
|
+
**Created & Developed by [Anshu Dubey](https://getyoursoft.page.gd)**
|
|
64
|
+
|
|
65
|
+
[](https://www.python.org/)
|
|
66
|
+
[](https://opensource.org/licenses/MIT)
|
|
67
|
+
[](https://github.com/mastgamerz37-ux/ansh-ai)
|
|
68
|
+
[](https://pypi.org/project/ansh-ai/)
|
|
69
|
+
[](https://github.com/mastgamerz37-ux/ansh-ai)
|
|
70
|
+
|
|
71
|
+
> 🌐 **Website & Product Key Activation:** [https://getyoursoft.page.gd](https://getyoursoft.page.gd)
|
|
72
|
+
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 🌟 What is ANSH?
|
|
78
|
+
|
|
79
|
+
**ANSH** is a production-grade personal AI assistant that can **hear, see, speak, remember, and control your computer** in real time.
|
|
80
|
+
|
|
81
|
+
Powered by the **Gemini Live API** for ultra-low latency bidirectional audio streaming and **Groq** for high-speed sub-agent reasoning, ANSH lives seamlessly on your screen as a sleek **Smart Island HUD**, providing proactive assistance, desktop automation, and multi-step problem solving.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 🚀 Key Features
|
|
86
|
+
|
|
87
|
+
| Feature | Description |
|
|
88
|
+
|---|---|
|
|
89
|
+
| 🎙️ **Real-Time Live Voice** | Full duplex bidirectional voice conversation with zero perceptible latency via Gemini Live API. |
|
|
90
|
+
| 🏝️ **Smart Island HUD** | Modern floating desktop widget with audio visualizer, quick actions, status pills, and context menu. |
|
|
91
|
+
| 🧩 **System 2 Dual AI Planner** | Autonomous multi-step goal planning, web browsing, code execution, and self-healing error recovery. |
|
|
92
|
+
| 👁️ **Visual Intelligence** | Real-time continuous screen inspection and webcam vision piped directly into the live session. |
|
|
93
|
+
| 🧠 **Long-Term Memory** | Semantic facts and preferences store that remembers user details across sessions. |
|
|
94
|
+
| 🖥️ **Full Desktop Control** | Launch apps, control media, adjust brightness & volume, type text, manage windows, and execute commands. |
|
|
95
|
+
| 🔄 **Automated GitHub Updates** | Background auto-updater that syncs latest updates from GitHub without requiring Git CLI. |
|
|
96
|
+
| 🔐 **3-Day Free Trial & Licensing** | Built-in 72-hour trial with cryptographic product key activation (`ANSH-XXXX-XXXX-XXXX`). |
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 📦 Installation & Setup
|
|
101
|
+
|
|
102
|
+
### Option 1: Install via `pip` (Recommended)
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
pip install ansh-ai
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Run ANSH from any terminal:
|
|
109
|
+
```bash
|
|
110
|
+
ansh
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
### Option 2: Standalone Windows Installer
|
|
116
|
+
|
|
117
|
+
Download the official standalone installer:
|
|
118
|
+
👉 **[Download ANSH_Setup_v1.0.exe](https://getyoursoft.page.gd)**
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
### Option 3: From Source Code
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# 1. Clone repository
|
|
126
|
+
git clone https://github.com/mastgamerz37-ux/ansh-ai.git
|
|
127
|
+
cd ansh-ai
|
|
128
|
+
|
|
129
|
+
# 2. Install dependencies
|
|
130
|
+
pip install -e .
|
|
131
|
+
|
|
132
|
+
# 3. Launch ANSH
|
|
133
|
+
ansh
|
|
134
|
+
# or
|
|
135
|
+
python main.py
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 🔑 Initial Configuration
|
|
141
|
+
|
|
142
|
+
On first launch, ANSH will interactively ask for your configuration in the terminal:
|
|
143
|
+
|
|
144
|
+
1. **Gemini API Key** (Free from [Google AI Studio](https://aistudio.google.com/app/apikey))
|
|
145
|
+
2. **Groq API Key** (Free from [Groq Console](https://console.groq.com/keys))
|
|
146
|
+
3. **Your Nickname** (How ANSH should address you)
|
|
147
|
+
|
|
148
|
+
> 💡 **Tip:** You can change your API keys or nickname anytime by right-clicking the **Smart Island HUD** and selecting **🔑 Change API Keys & Nickname**.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 🎟️ 3-Day Free Trial & Product Keys
|
|
153
|
+
|
|
154
|
+
ANSH comes with a **3-Day Free Trial (72 Hours)** upon first launch.
|
|
155
|
+
|
|
156
|
+
- **Trial Period:** Full access to all capabilities with real-time trial countdown.
|
|
157
|
+
- **Product Activation:** Once trial concludes, enter your product key (`ANSH-XXXX-XXXX-XXXX`) to unlock lifetime access.
|
|
158
|
+
- **Get Keys:** Visit [https://getyoursoft.page.gd](https://getyoursoft.page.gd)
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## ⌨️ Desktop Shortcuts & Voice Commands
|
|
163
|
+
|
|
164
|
+
- **Toggle Mic / Listen:** `Ctrl + Space`
|
|
165
|
+
- **Wake Word:** Say *"Hey Ansh"* or *"Ansh"*
|
|
166
|
+
- **Sample Commands:**
|
|
167
|
+
- *"Search latest news on space exploration and save notes to desktop"*
|
|
168
|
+
- *"Open Spotify and turn the volume up"*
|
|
169
|
+
- *"Check the weather forecast for tomorrow"*
|
|
170
|
+
- *"Analyze what's on my screen right now"*
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## 🛠️ Project Structure
|
|
175
|
+
|
|
176
|
+
```text
|
|
177
|
+
ansh-ai/
|
|
178
|
+
├── actions/ # Desktop automation, tools, web search, computer settings
|
|
179
|
+
├── core/ # Voice engine, AGI planner, Task LLM, Auto-updater, Licensing
|
|
180
|
+
├── dashboard/ # Localhost command center (FastAPI + WebSocket)
|
|
181
|
+
├── memory/ # Semantic markdown memory store & config management
|
|
182
|
+
├── skills/ # Modular skill manifests & tool definitions
|
|
183
|
+
├── smart_island.py # PyQt6 floating Dynamic Island HUD interface
|
|
184
|
+
├── ui.py # Main UI & audio visualization window
|
|
185
|
+
├── main.py # Application entrypoint and orchestration loop
|
|
186
|
+
└── pyproject.toml # PEP 517 build configuration
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 👤 Author & Support
|
|
192
|
+
|
|
193
|
+
- **Lead Developer:** **Anshu Dubey**
|
|
194
|
+
- **Website:** [https://getyoursoft.page.gd](https://getyoursoft.page.gd)
|
|
195
|
+
- **GitHub:** [@mastgamerz37-ux](https://github.com/mastgamerz37-ux)
|
|
196
|
+
- **Repository:** [mastgamerz37-ux/ansh-ai](https://github.com/mastgamerz37-ux/ansh-ai)
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 📄 License
|
|
201
|
+
|
|
202
|
+
This project is licensed under the **MIT License**.
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"""
|
|
2
|
+
actions/automation_engine.py — Ansh Automation & Multi-Step Workflow Engine
|
|
3
|
+
|
|
4
|
+
Executes complex multi-step routines, custom task workflows, and scheduled triggers
|
|
5
|
+
across applications, system settings, browser, and files.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import json
|
|
10
|
+
import os
|
|
11
|
+
import platform
|
|
12
|
+
import shutil
|
|
13
|
+
import subprocess
|
|
14
|
+
import sys
|
|
15
|
+
import tempfile
|
|
16
|
+
import time
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from typing import Any, Dict, List, Optional
|
|
19
|
+
|
|
20
|
+
_IS_WIN = platform.system() == "Windows"
|
|
21
|
+
_IS_MAC = platform.system() == "Darwin"
|
|
22
|
+
_IS_LINUX = platform.system() == "Linux"
|
|
23
|
+
|
|
24
|
+
def _base_dir() -> Path:
|
|
25
|
+
if getattr(sys, "frozen", False):
|
|
26
|
+
return Path(sys.executable).parent
|
|
27
|
+
return Path(__file__).resolve().parent.parent
|
|
28
|
+
|
|
29
|
+
BASE_DIR = _base_dir()
|
|
30
|
+
WORKFLOWS_FILE = BASE_DIR / "config" / "workflows.json"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
BUILTIN_WORKFLOWS = {
|
|
34
|
+
"dev_mode": {
|
|
35
|
+
"id": "dev_mode",
|
|
36
|
+
"name": "Developer Setup",
|
|
37
|
+
"description": "Opens VS Code, Terminal, and Chrome developer tools; sets volume to 30%",
|
|
38
|
+
"icon": "💻",
|
|
39
|
+
"steps": [
|
|
40
|
+
{"type": "app", "target": "Code"},
|
|
41
|
+
{"type": "app", "target": "chrome"},
|
|
42
|
+
{"type": "volume", "value": 30},
|
|
43
|
+
{"type": "notify", "message": "Developer environment initialized."}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"focus_mode": {
|
|
47
|
+
"id": "focus_mode",
|
|
48
|
+
"name": "Deep Focus",
|
|
49
|
+
"description": "Mutes system audio, closes non-essential windows, opens Notepad",
|
|
50
|
+
"icon": "🎯",
|
|
51
|
+
"steps": [
|
|
52
|
+
{"type": "volume_mute"},
|
|
53
|
+
{"type": "app", "target": "notepad"},
|
|
54
|
+
{"type": "notify", "message": "Focus mode activated. Distractions silenced."}
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
"media_mode": {
|
|
58
|
+
"id": "media_mode",
|
|
59
|
+
"name": "Entertainment / Music",
|
|
60
|
+
"description": "Opens Spotify or YouTube and adjusts volume to 65%",
|
|
61
|
+
"icon": "🎵",
|
|
62
|
+
"steps": [
|
|
63
|
+
{"type": "app", "target": "spotify"},
|
|
64
|
+
{"type": "volume", "value": 65},
|
|
65
|
+
{"type": "notify", "message": "Media mode active."}
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
"night_mode": {
|
|
69
|
+
"id": "night_mode",
|
|
70
|
+
"name": "Night Relaxation",
|
|
71
|
+
"description": "Dims brightness, lowers audio to 20%, minimizes desktop windows",
|
|
72
|
+
"icon": "🌙",
|
|
73
|
+
"steps": [
|
|
74
|
+
{"type": "volume", "value": 20},
|
|
75
|
+
{"type": "hotkey", "keys": ["win", "d"]},
|
|
76
|
+
{"type": "notify", "message": "Good night. System prepared for rest."}
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
"clean_temp": {
|
|
80
|
+
"id": "clean_temp",
|
|
81
|
+
"name": "Clean Temporary Files",
|
|
82
|
+
"description": "Purges temporary files, cache, and frees system memory",
|
|
83
|
+
"icon": "🧹",
|
|
84
|
+
"steps": [
|
|
85
|
+
{"type": "clean_temp_files"},
|
|
86
|
+
{"type": "notify", "message": "Temporary cache and scratch files cleaned."}
|
|
87
|
+
]
|
|
88
|
+
},
|
|
89
|
+
"morning_routine": {
|
|
90
|
+
"id": "morning_routine",
|
|
91
|
+
"name": "Morning Brief & Launch",
|
|
92
|
+
"description": "Opens browser news, checks system telemetry, sets volume to 40%",
|
|
93
|
+
"icon": "🌅",
|
|
94
|
+
"steps": [
|
|
95
|
+
{"type": "volume", "value": 40},
|
|
96
|
+
{"type": "url", "url": "https://news.google.com"},
|
|
97
|
+
{"type": "notify", "message": "Good morning! News opened and system ready."}
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def load_all_workflows() -> Dict[str, Any]:
|
|
104
|
+
"""Loads built-in and user-customized workflows."""
|
|
105
|
+
workflows = dict(BUILTIN_WORKFLOWS)
|
|
106
|
+
if WORKFLOWS_FILE.exists():
|
|
107
|
+
try:
|
|
108
|
+
custom = json.loads(WORKFLOWS_FILE.read_text(encoding="utf-8"))
|
|
109
|
+
if isinstance(custom, dict):
|
|
110
|
+
workflows.update(custom)
|
|
111
|
+
except Exception:
|
|
112
|
+
pass
|
|
113
|
+
return workflows
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def save_custom_workflow(workflow_data: dict) -> bool:
|
|
117
|
+
"""Saves or updates a custom workflow."""
|
|
118
|
+
wf_id = workflow_data.get("id") or f"custom_{int(time.time())}"
|
|
119
|
+
workflow_data["id"] = wf_id
|
|
120
|
+
workflows = {}
|
|
121
|
+
if WORKFLOWS_FILE.exists():
|
|
122
|
+
try:
|
|
123
|
+
workflows = json.loads(WORKFLOWS_FILE.read_text(encoding="utf-8"))
|
|
124
|
+
except Exception:
|
|
125
|
+
workflows = {}
|
|
126
|
+
workflows[wf_id] = workflow_data
|
|
127
|
+
try:
|
|
128
|
+
WORKFLOWS_FILE.parent.mkdir(parents=True, exist_ok=True)
|
|
129
|
+
WORKFLOWS_FILE.write_text(json.dumps(workflows, indent=2), encoding="utf-8")
|
|
130
|
+
return True
|
|
131
|
+
except Exception:
|
|
132
|
+
return False
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class AutomationEngine:
|
|
136
|
+
"""Orchestrates and executes multi-step workflows."""
|
|
137
|
+
|
|
138
|
+
@staticmethod
|
|
139
|
+
def execute_step(step: dict) -> dict:
|
|
140
|
+
stype = step.get("type", "")
|
|
141
|
+
try:
|
|
142
|
+
if stype == "app":
|
|
143
|
+
target = step.get("target", "")
|
|
144
|
+
from actions.open_app import open_app
|
|
145
|
+
res = open_app({"app_name": target})
|
|
146
|
+
return {"ok": True, "result": res}
|
|
147
|
+
|
|
148
|
+
elif stype == "url":
|
|
149
|
+
url = step.get("url", "")
|
|
150
|
+
import webbrowser
|
|
151
|
+
webbrowser.open(url)
|
|
152
|
+
return {"ok": True, "url": url}
|
|
153
|
+
|
|
154
|
+
elif stype == "volume":
|
|
155
|
+
val = int(step.get("value", 50))
|
|
156
|
+
try:
|
|
157
|
+
from actions.computer_settings import volume_set
|
|
158
|
+
volume_set(val)
|
|
159
|
+
except Exception:
|
|
160
|
+
pass
|
|
161
|
+
return {"ok": True, "volume": val}
|
|
162
|
+
|
|
163
|
+
elif stype == "volume_mute":
|
|
164
|
+
if _IS_WIN:
|
|
165
|
+
subprocess.run(["powershell", "-c", "$wshell = New-Object -ComObject WScript.Shell; $wshell.SendKeys([char]173)"], check=False)
|
|
166
|
+
return {"ok": True}
|
|
167
|
+
|
|
168
|
+
elif stype == "hotkey":
|
|
169
|
+
keys = step.get("keys", [])
|
|
170
|
+
try:
|
|
171
|
+
import pyautogui
|
|
172
|
+
pyautogui.hotkey(*keys)
|
|
173
|
+
except Exception:
|
|
174
|
+
pass
|
|
175
|
+
return {"ok": True, "keys": keys}
|
|
176
|
+
|
|
177
|
+
elif stype == "wait":
|
|
178
|
+
secs = float(step.get("seconds", 1.0))
|
|
179
|
+
time.sleep(secs)
|
|
180
|
+
return {"ok": True, "waited": secs}
|
|
181
|
+
|
|
182
|
+
elif stype == "clean_temp_files":
|
|
183
|
+
freed_mb = 0.0
|
|
184
|
+
temp_dir = Path(tempfile.gettempdir())
|
|
185
|
+
for item in temp_dir.iterdir():
|
|
186
|
+
try:
|
|
187
|
+
if item.is_file():
|
|
188
|
+
sz = item.stat().st_size
|
|
189
|
+
item.unlink(missing_ok=True)
|
|
190
|
+
freed_mb += sz / (1024 * 1024)
|
|
191
|
+
elif item.is_dir():
|
|
192
|
+
shutil.rmtree(item, ignore_errors=True)
|
|
193
|
+
except Exception:
|
|
194
|
+
continue
|
|
195
|
+
return {"ok": True, "freed_mb": round(freed_mb, 2)}
|
|
196
|
+
|
|
197
|
+
elif stype == "notify":
|
|
198
|
+
msg = step.get("message", "")
|
|
199
|
+
return {"ok": True, "message": msg}
|
|
200
|
+
|
|
201
|
+
return {"ok": False, "error": f"Unknown step type: {stype}"}
|
|
202
|
+
except Exception as e:
|
|
203
|
+
return {"ok": False, "error": str(e)}
|
|
204
|
+
|
|
205
|
+
@classmethod
|
|
206
|
+
def run_workflow(cls, workflow_id_or_data: Any) -> dict:
|
|
207
|
+
"""Executes a workflow by ID or by passing the workflow dict."""
|
|
208
|
+
if isinstance(workflow_id_or_data, str):
|
|
209
|
+
all_wf = load_all_workflows()
|
|
210
|
+
wf = all_wf.get(workflow_id_or_data)
|
|
211
|
+
if not wf:
|
|
212
|
+
return {"ok": False, "error": f"Workflow '{workflow_id_or_data}' not found."}
|
|
213
|
+
else:
|
|
214
|
+
wf = workflow_id_or_data
|
|
215
|
+
|
|
216
|
+
steps = wf.get("steps", [])
|
|
217
|
+
results = []
|
|
218
|
+
for s in steps:
|
|
219
|
+
r = cls.execute_step(s)
|
|
220
|
+
results.append(r)
|
|
221
|
+
time.sleep(0.3)
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
"ok": True,
|
|
225
|
+
"workflow_id": wf.get("id"),
|
|
226
|
+
"name": wf.get("name"),
|
|
227
|
+
"steps_executed": len(results),
|
|
228
|
+
"results": results
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def automation_workflow(parameters: dict, **kwargs) -> str:
|
|
233
|
+
"""Tool function callable by Gemini / Ansh main loop."""
|
|
234
|
+
action = parameters.get("action", "run")
|
|
235
|
+
workflow_id = parameters.get("workflow_id", "")
|
|
236
|
+
|
|
237
|
+
if action == "list":
|
|
238
|
+
all_wf = load_all_workflows()
|
|
239
|
+
names = [f"- {v['name']} ({k}): {v['description']}" for k, v in all_wf.items()]
|
|
240
|
+
return "Available Workflows:\n" + "\n".join(names)
|
|
241
|
+
|
|
242
|
+
if action == "run":
|
|
243
|
+
if not workflow_id:
|
|
244
|
+
return "Please provide workflow_id (e.g. dev_mode, focus_mode, media_mode, night_mode, clean_temp)."
|
|
245
|
+
res = AutomationEngine.run_workflow(workflow_id)
|
|
246
|
+
if res.get("ok"):
|
|
247
|
+
return f"Workflow '{res.get('name')}' executed successfully with {res.get('steps_executed')} steps."
|
|
248
|
+
return f"Workflow execution failed: {res.get('error')}"
|
|
249
|
+
|
|
250
|
+
return f"Unknown workflow action '{action}'."
|