friday-neural-os 0.1.1__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.
- friday/__init__.py +3 -0
- friday/agent.py +348 -0
- friday/cli.py +13 -0
- friday/config.py +23 -0
- friday/installer.py +30 -0
- friday/prompts.py +315 -0
- friday/tools/__init__.py +9 -0
- friday/tools/communication.py +109 -0
- friday/tools/core.py +251 -0
- friday/tools/files.py +76 -0
- friday/tools/media.py +83 -0
- friday/tools/network.py +245 -0
- friday/tools/productivity.py +120 -0
- friday/tools/security.py +88 -0
- friday/tools/ui.py +226 -0
- friday_neural_os-0.1.1.dist-info/METADATA +86 -0
- friday_neural_os-0.1.1.dist-info/RECORD +29 -0
- friday_neural_os-0.1.1.dist-info/WHEEL +5 -0
- friday_neural_os-0.1.1.dist-info/entry_points.txt +4 -0
- friday_neural_os-0.1.1.dist-info/top_level.txt +1 -0
- tools/__init__.py +9 -0
- tools/communication.py +109 -0
- tools/core.py +251 -0
- tools/files.py +76 -0
- tools/media.py +83 -0
- tools/network.py +245 -0
- tools/productivity.py +85 -0
- tools/security.py +88 -0
- tools/ui.py +226 -0
friday/__init__.py
ADDED
friday/agent.py
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
from dotenv import load_dotenv
|
|
2
|
+
load_dotenv()
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
from mem0 import MemoryClient
|
|
6
|
+
from livekit import agents
|
|
7
|
+
from livekit.agents import Agent, AgentSession, RoomInputOptions, RunContext
|
|
8
|
+
from livekit.plugins import google, noise_cancellation
|
|
9
|
+
|
|
10
|
+
from .prompts import AGENT_INSTRUCTION, SESSION_INSTRUCTION
|
|
11
|
+
from .tools import *
|
|
12
|
+
|
|
13
|
+
# ==============================
|
|
14
|
+
# MEM0 SETUP
|
|
15
|
+
# ==============================
|
|
16
|
+
MEM0_API_KEY = os.getenv("MEM0_API_KEY")
|
|
17
|
+
USER_ID = "SHIVANSH"
|
|
18
|
+
|
|
19
|
+
mem0 = MemoryClient(api_key= os.getenv("MEM0_API_KEY"))
|
|
20
|
+
|
|
21
|
+
# ==============================
|
|
22
|
+
# TOOLS
|
|
23
|
+
# ==============================
|
|
24
|
+
ALL_TOOLS = [
|
|
25
|
+
# Core system & info
|
|
26
|
+
get_weather, search_web, send_email, current_time,
|
|
27
|
+
system_status, system_uptime, battery_status, check_internet, system_health_report,
|
|
28
|
+
control_bluetooth, control_windows_settings,
|
|
29
|
+
|
|
30
|
+
# Media & entertainment
|
|
31
|
+
play_music, control_lg_tv, control_jio_stb, youtube_search_results, select_video_by_index,
|
|
32
|
+
|
|
33
|
+
# App tracking & memory
|
|
34
|
+
track_active_application, weekly_app_usage_report,
|
|
35
|
+
remember, recall,
|
|
36
|
+
|
|
37
|
+
# Contact management
|
|
38
|
+
save_contact, get_contact_phone, list_all_contacts, delete_contact, search_contacts,
|
|
39
|
+
|
|
40
|
+
# File system operations
|
|
41
|
+
create_file, read_file, delete_file, rename_file, list_directory, create_folder,
|
|
42
|
+
open_file_or_folder,
|
|
43
|
+
|
|
44
|
+
# Window management
|
|
45
|
+
get_active_window, minimize_window, maximize_window, close_active_window, switch_window,
|
|
46
|
+
|
|
47
|
+
# OS automation
|
|
48
|
+
open_website_or_app, run_command, lock_system,
|
|
49
|
+
|
|
50
|
+
# Enhanced CMD/PowerShell access
|
|
51
|
+
execute_powershell, execute_cmd,
|
|
52
|
+
|
|
53
|
+
# Input control
|
|
54
|
+
keyboard_mouse_control, volume_control, take_screenshot,
|
|
55
|
+
|
|
56
|
+
# Clipboard
|
|
57
|
+
read_clipboard, copy_to_clipboard, open_clipboard_history,
|
|
58
|
+
|
|
59
|
+
# Process management
|
|
60
|
+
running_processes, terminate_process,
|
|
61
|
+
|
|
62
|
+
# Network scanning & monitoring
|
|
63
|
+
scan_network_devices, get_detailed_network_info, get_active_connections,
|
|
64
|
+
get_router_info, network_bandwidth_usage, get_network_speed,
|
|
65
|
+
ping_device, trace_route, port_scan, get_remote_device_info, get_device_services,
|
|
66
|
+
|
|
67
|
+
# Network control
|
|
68
|
+
ip_information, list_wifi_networks, connect_wifi, disconnect_wifi,
|
|
69
|
+
flush_dns, renew_ip_address, control_network_adapter,
|
|
70
|
+
|
|
71
|
+
# Advanced network control (requires admin)
|
|
72
|
+
disconnect_device_from_internet, reconnect_device_to_internet,
|
|
73
|
+
check_admin_privileges, enable_packet_forwarding,
|
|
74
|
+
get_router_admin_page, network_kill_switch,
|
|
75
|
+
monitor_network_traffic, limit_device_bandwidth, remove_bandwidth_limit,
|
|
76
|
+
get_network_devices_with_names,
|
|
77
|
+
|
|
78
|
+
# Remote device control
|
|
79
|
+
wake_on_lan, remote_shutdown, remote_restart, execute_remote_command,
|
|
80
|
+
remote_desktop_connect, send_network_message,
|
|
81
|
+
|
|
82
|
+
# Network file sharing
|
|
83
|
+
share_folder_on_network, remove_network_share, list_network_shares,
|
|
84
|
+
access_network_share, map_network_drive, disconnect_network_drive,
|
|
85
|
+
remote_file_copy,
|
|
86
|
+
|
|
87
|
+
# Router control
|
|
88
|
+
control_jio_router,
|
|
89
|
+
|
|
90
|
+
# Power management
|
|
91
|
+
restart_system, shutdown_system, sleep_system, hibernate_system,
|
|
92
|
+
|
|
93
|
+
# Advanced features
|
|
94
|
+
login_with_gmail, generate_image,
|
|
95
|
+
set_brightness, disk_usage, show_notification, schedule_task,
|
|
96
|
+
|
|
97
|
+
# Phone & messaging
|
|
98
|
+
universal_phone_unlocker, send_whatsapp_message, send_whatsapp_image, check_gmail_for_otp,
|
|
99
|
+
get_email_count, get_recent_email_senders, read_specific_email, reply_to_latest_email,
|
|
100
|
+
|
|
101
|
+
# Intelligence & Hacking
|
|
102
|
+
get_saved_wifi_passwords, analyze_screen_content, summarize_website,
|
|
103
|
+
|
|
104
|
+
# GitHub Automation
|
|
105
|
+
github_create_repo, github_push_changes,
|
|
106
|
+
|
|
107
|
+
# YouTube Automation
|
|
108
|
+
get_youtube_subscribers, open_youtube_studio,
|
|
109
|
+
|
|
110
|
+
# Strategic & Government Tools
|
|
111
|
+
generate_intelligence_briefing, satellite_recon, defense_protocol_alpha, perform_signal_intelligence_scan,
|
|
112
|
+
|
|
113
|
+
# New Features
|
|
114
|
+
send_whatsapp_message_background, make_phone_call, track_phone_number, get_latest_call_info, generate_phone_location_map, get_exact_location_via_adb, identify_object_from_camera,
|
|
115
|
+
whatsapp_call, google_duo_call, start_google_meet, add_smart_reminder,
|
|
116
|
+
play_chess_move_autonomously, detect_user_mood, perform_biometric_fingerprint_scan,
|
|
117
|
+
vulnerability_scanner, local_network_brute_force, metasploit_demo_console, sniff_network_packets,
|
|
118
|
+
remote_execute_psexec_hash,
|
|
119
|
+
|
|
120
|
+
# Productivity
|
|
121
|
+
enable_focus_mode, disable_focus_mode,
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
import asyncio
|
|
125
|
+
|
|
126
|
+
# Global storage for the current session to allow proactive notifications
|
|
127
|
+
active_session = None
|
|
128
|
+
|
|
129
|
+
# ==============================
|
|
130
|
+
# BACKGROUND WORKER
|
|
131
|
+
# ==============================
|
|
132
|
+
async def reminder_worker():
|
|
133
|
+
while True:
|
|
134
|
+
try:
|
|
135
|
+
await check_and_notify_reminders(active_session)
|
|
136
|
+
except:
|
|
137
|
+
pass
|
|
138
|
+
await asyncio.sleep(60) # Check every minute
|
|
139
|
+
|
|
140
|
+
# ==============================
|
|
141
|
+
# INTENT ROUTER
|
|
142
|
+
# ==============================
|
|
143
|
+
def route_intent(q: str):
|
|
144
|
+
q = q.lower()
|
|
145
|
+
if "on tv" in q: return control_lg_tv, {"command": "on_youtube", "value": q.replace("on tv", "").replace("play", "").strip()}
|
|
146
|
+
if q.startswith("play"): return youtube_search_results, {"query": q.replace("play", "").strip()}
|
|
147
|
+
if "email" in q: return send_email, {"query": q}
|
|
148
|
+
if "unlock phone" in q: return universal_phone_unlocker, {}
|
|
149
|
+
if "weather" in q: return get_weather, {"city": q.split()[-1]}
|
|
150
|
+
if "time" in q: return current_time, {}
|
|
151
|
+
if "internet" in q: return check_internet, {}
|
|
152
|
+
if "weekly report" in q: return weekly_app_usage_report, {}
|
|
153
|
+
if q.startswith("open"): return open_website_or_app, {"query": q}
|
|
154
|
+
if "shutdown" in q: return shutdown_system, {}
|
|
155
|
+
if "restart" in q: return restart_system, {}
|
|
156
|
+
if "hacking scan" in q: return vulnerability_scanner, {"target": q.split()[-1]}
|
|
157
|
+
if "brute force" in q: return local_network_brute_force, {"target_ip": q.split()[-1]}
|
|
158
|
+
if "metasploit" in q: return metasploit_demo_console, {}
|
|
159
|
+
if "jio" in q and ("pause" in q or "resume" in q or "play" in q or "stop" in q):
|
|
160
|
+
action = "pause" if "pause" in q else ("resume" if "resume" in q else ("play" if "play" in q else "stop"))
|
|
161
|
+
return control_jio_stb, {"action": action}
|
|
162
|
+
return None, None
|
|
163
|
+
|
|
164
|
+
# ==============================
|
|
165
|
+
# ASSISTANT
|
|
166
|
+
# ==============================
|
|
167
|
+
class Assistant(Agent):
|
|
168
|
+
def __init__(self):
|
|
169
|
+
super().__init__(
|
|
170
|
+
instructions=AGENT_INSTRUCTION,
|
|
171
|
+
llm=google.beta.realtime.RealtimeModel(
|
|
172
|
+
voice="Aoede",
|
|
173
|
+
temperature=0.9,
|
|
174
|
+
),
|
|
175
|
+
tools=ALL_TOOLS,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
async def on_user_message(self, context: RunContext, message: str):
|
|
179
|
+
global active_session
|
|
180
|
+
|
|
181
|
+
# š¹ SMART STORE MEMORY - Explicit remember command
|
|
182
|
+
if message.lower().startswith("remember"):
|
|
183
|
+
text = message.replace("remember", "").strip()
|
|
184
|
+
mem0.add(messages=[{"role": "user", "content": text}], user_id=USER_ID)
|
|
185
|
+
return "I've saved that to my long-term memory, Sir."
|
|
186
|
+
|
|
187
|
+
# š¹ AUTO-DETECT AND STORE IMPORTANT EVENTS
|
|
188
|
+
event_keywords = [
|
|
189
|
+
"meeting", "interview", "appointment", "event", "tomorrow", "next week",
|
|
190
|
+
"next month", "schedule", "basketball", "going to", "have to", "will be",
|
|
191
|
+
"presentation", "exam", "test", "trip", "travel", "flight", "doctor",
|
|
192
|
+
"dentist", "party", "celebration", "birthday", "anniversary", "deadline"
|
|
193
|
+
]
|
|
194
|
+
|
|
195
|
+
# Store events automatically
|
|
196
|
+
if any(keyword in message.lower() for keyword in event_keywords):
|
|
197
|
+
mem0.add(
|
|
198
|
+
messages=[{
|
|
199
|
+
"role": "user",
|
|
200
|
+
"content": f"[EVENT] {message}"
|
|
201
|
+
}],
|
|
202
|
+
user_id=USER_ID
|
|
203
|
+
)
|
|
204
|
+
print(f"š Stored event memory: {message}")
|
|
205
|
+
|
|
206
|
+
# š¹ AUTO-READ FILE PATHS
|
|
207
|
+
import re
|
|
208
|
+
if re.search(r'[a-zA-Z]:\\[\\\w\s.-]+', message) or ("/" in message and "." in message):
|
|
209
|
+
path_match = re.search(r'([a-zA-Z]:\\[\\\w\s.-]+)', message)
|
|
210
|
+
if path_match:
|
|
211
|
+
file_path = path_match.group(1).strip()
|
|
212
|
+
if os.path.exists(file_path) and os.path.isfile(file_path):
|
|
213
|
+
return await read_file(context, file_path)
|
|
214
|
+
|
|
215
|
+
# š¹ RETRIEVE RELEVANT MEMORIES
|
|
216
|
+
memories = mem0.search(query=message, user_id=USER_ID, limit=5)
|
|
217
|
+
memory_context = ""
|
|
218
|
+
if memories and len(memories) > 0:
|
|
219
|
+
memory_context = "IMPORTANT - You have the following memories about the user:\n"
|
|
220
|
+
for m in memories:
|
|
221
|
+
if 'memory' in m:
|
|
222
|
+
content = m['memory'].get('content', '') if isinstance(m['memory'], dict) else str(m['memory'])
|
|
223
|
+
memory_context += f"- {content}\n"
|
|
224
|
+
|
|
225
|
+
# š¹ INTENT ROUTING
|
|
226
|
+
tool, args = route_intent(message)
|
|
227
|
+
if tool:
|
|
228
|
+
return await tool(context, **args)
|
|
229
|
+
|
|
230
|
+
# š¹ STRONG MEMORY INJECTION INTO PROMPT
|
|
231
|
+
final_prompt = f"""
|
|
232
|
+
{memory_context}
|
|
233
|
+
|
|
234
|
+
User message:
|
|
235
|
+
{message}
|
|
236
|
+
|
|
237
|
+
IMPORTANT: If you have memories about past events the user mentioned (meetings, interviews, etc.),
|
|
238
|
+
ask them how it went in a natural, conversational way.
|
|
239
|
+
"""
|
|
240
|
+
return await super().on_user_message(context, final_prompt)
|
|
241
|
+
|
|
242
|
+
# ==============================
|
|
243
|
+
# ENTRYPOINT
|
|
244
|
+
# ==============================
|
|
245
|
+
async def entrypoint(ctx: agents.JobContext):
|
|
246
|
+
print("š Initializing Friday Agent...")
|
|
247
|
+
global active_session
|
|
248
|
+
|
|
249
|
+
try:
|
|
250
|
+
await ctx.connect()
|
|
251
|
+
print("ā
Connected to LiveKit Room.")
|
|
252
|
+
except Exception as e:
|
|
253
|
+
print(f"ā Connection failed: {e}")
|
|
254
|
+
return
|
|
255
|
+
|
|
256
|
+
session = AgentSession()
|
|
257
|
+
active_session = session
|
|
258
|
+
|
|
259
|
+
# š¹ START BACKGROUND WORKER
|
|
260
|
+
asyncio.create_task(reminder_worker())
|
|
261
|
+
|
|
262
|
+
await session.start(
|
|
263
|
+
room=ctx.room,
|
|
264
|
+
agent=Assistant(),
|
|
265
|
+
room_input_options=RoomInputOptions(
|
|
266
|
+
video_enabled=True,
|
|
267
|
+
noise_cancellation=noise_cancellation.BVC(),
|
|
268
|
+
),
|
|
269
|
+
)
|
|
270
|
+
print("ā
Session started.")
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
# š¹ STARTUP GREETING WITH MEMORY CONTEXT
|
|
274
|
+
try:
|
|
275
|
+
# Get all recent memories
|
|
276
|
+
all_memories = mem0.get_all(user_id=USER_ID, limit=10)
|
|
277
|
+
|
|
278
|
+
# Filter for event memories
|
|
279
|
+
event_memories = []
|
|
280
|
+
general_memories = []
|
|
281
|
+
|
|
282
|
+
if all_memories:
|
|
283
|
+
for mem in all_memories:
|
|
284
|
+
mem_content = ""
|
|
285
|
+
if isinstance(mem, dict):
|
|
286
|
+
if 'memory' in mem:
|
|
287
|
+
mem_content = mem['memory'].get('content', '') if isinstance(mem['memory'], dict) else str(mem['memory'])
|
|
288
|
+
else:
|
|
289
|
+
mem_content = str(mem)
|
|
290
|
+
else:
|
|
291
|
+
mem_content = str(mem)
|
|
292
|
+
|
|
293
|
+
if '[EVENT]' in mem_content or any(kw in mem_content.lower() for kw in ['meeting', 'interview', 'appointment', 'tomorrow', 'today']):
|
|
294
|
+
event_memories.append(mem_content.replace('[EVENT]', '').strip())
|
|
295
|
+
else:
|
|
296
|
+
general_memories.append(mem_content)
|
|
297
|
+
|
|
298
|
+
# Build context string
|
|
299
|
+
context_parts = []
|
|
300
|
+
if event_memories:
|
|
301
|
+
context_parts.append("RECENT EVENTS THE USER MENTIONED:")
|
|
302
|
+
context_parts.extend([f"- {mem}" for mem in event_memories[:5]])
|
|
303
|
+
|
|
304
|
+
if general_memories:
|
|
305
|
+
context_parts.append("\nOTHER MEMORIES:")
|
|
306
|
+
context_parts.extend([f"- {mem}" for mem in general_memories[:3]])
|
|
307
|
+
|
|
308
|
+
context_str = "\n".join(context_parts) if context_parts else ""
|
|
309
|
+
|
|
310
|
+
# Enhanced session instruction with memory
|
|
311
|
+
enhanced_instruction = f"""{SESSION_INSTRUCTION}
|
|
312
|
+
|
|
313
|
+
{context_str}
|
|
314
|
+
|
|
315
|
+
IMPORTANT INSTRUCTIONS:
|
|
316
|
+
- You detected past events in the user's memory (above).
|
|
317
|
+
- Your GOAL for this first message is to PROACTIVELY ask about the MOST RECENT event.
|
|
318
|
+
- Do NOT say "Hello" or "How can I help" generically if you have an event to ask about.
|
|
319
|
+
- Example: "Welcome back, Sir. How did your meeting go?"
|
|
320
|
+
- Example: "Good evening, Boss. usage: Did you manage to catch your flight?"
|
|
321
|
+
- BE SPECIFIC. Mention the event context.
|
|
322
|
+
"""
|
|
323
|
+
# If we have specific event memories, force the issue
|
|
324
|
+
if event_memories:
|
|
325
|
+
enhanced_instruction += "\n\nCRITICAL: You MUST start by asking about the event mentioned above: " + event_memories[0]
|
|
326
|
+
|
|
327
|
+
except Exception as e:
|
|
328
|
+
print(f"Greeting error: {e}")
|
|
329
|
+
await session.generate_reply(instructions=SESSION_INSTRUCTION)
|
|
330
|
+
|
|
331
|
+
# ==============================
|
|
332
|
+
# RUN
|
|
333
|
+
# ==============================
|
|
334
|
+
def main():
|
|
335
|
+
print("Friday online.")
|
|
336
|
+
# existing logic here
|
|
337
|
+
|
|
338
|
+
if __name__ == "__main__":
|
|
339
|
+
while True:
|
|
340
|
+
pwd = input("š ENTER ACCESS CODE: ")
|
|
341
|
+
if pwd.strip() == "JARVIS":
|
|
342
|
+
print("ā
ACCESS GRANTED")
|
|
343
|
+
break
|
|
344
|
+
print("ā ACCESS DENIED")
|
|
345
|
+
|
|
346
|
+
agents.cli.run_app(
|
|
347
|
+
agents.WorkerOptions(entrypoint_fnc=entrypoint)
|
|
348
|
+
)
|
friday/cli.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
def main():
|
|
4
|
+
if len(sys.argv) > 1 and sys.argv[1] == "config":
|
|
5
|
+
if len(sys.argv) > 2 and sys.argv[2] == "setup":
|
|
6
|
+
from friday.installer import setup
|
|
7
|
+
setup()
|
|
8
|
+
return
|
|
9
|
+
|
|
10
|
+
from friday.config import validate_env
|
|
11
|
+
from friday.agent import main as agent_main
|
|
12
|
+
|
|
13
|
+
agent_main()
|
friday/config.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from dotenv import load_dotenv
|
|
3
|
+
|
|
4
|
+
load_dotenv()
|
|
5
|
+
|
|
6
|
+
REQUIRED = [
|
|
7
|
+
"LIVEKIT_API_KEY",
|
|
8
|
+
"LIVEKIT_API_SECRET",
|
|
9
|
+
"LIVEKIT_URL",
|
|
10
|
+
"GMAIL_USER",
|
|
11
|
+
"GMAIL_APP_PASSWORD",
|
|
12
|
+
"MEM0_API_KEY",
|
|
13
|
+
"GITHUB_TOKEN",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
def validate_env():
|
|
17
|
+
missing = [k for k in REQUIRED if not os.getenv(k)]
|
|
18
|
+
if missing:
|
|
19
|
+
raise RuntimeError(
|
|
20
|
+
"Friday is not configured.\n"
|
|
21
|
+
"Run: friday config setup\n\nMissing:\n"
|
|
22
|
+
+ "\n".join(missing)
|
|
23
|
+
)
|
friday/installer.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
ENV_VARS = [
|
|
4
|
+
"LIVEKIT_API_KEY",
|
|
5
|
+
"LIVEKIT_API_SECRET",
|
|
6
|
+
"LIVEKIT_URL",
|
|
7
|
+
"GMAIL_USER",
|
|
8
|
+
"GMAIL_APP_PASSWORD",
|
|
9
|
+
"MEM0_API_KEY",
|
|
10
|
+
"GITHUB_TOKEN",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
def setup():
|
|
14
|
+
env_path = os.path.join(os.getcwd(), ".env")
|
|
15
|
+
|
|
16
|
+
if os.path.exists(env_path):
|
|
17
|
+
print("ā
.env already exists")
|
|
18
|
+
return
|
|
19
|
+
|
|
20
|
+
print("š Friday first-time setup\n")
|
|
21
|
+
|
|
22
|
+
lines = []
|
|
23
|
+
for var in ENV_VARS:
|
|
24
|
+
value = input(f"{var}: ").strip()
|
|
25
|
+
lines.append(f"{var}={value}")
|
|
26
|
+
|
|
27
|
+
with open(env_path, "w") as f:
|
|
28
|
+
f.write("\n".join(lines))
|
|
29
|
+
|
|
30
|
+
print("\nā
Setup complete")
|