Spaces:
Sleeping
Sleeping
File size: 10,946 Bytes
74832a9 4861317 74832a9 de6d503 74832a9 637500d 08a2910 4861317 c6880d4 637500d 4f41fee 637500d 3065ecd 4861317 08a2910 4f41fee 637500d 8029739 4861317 637500d 54cccd0 4861317 d33032c 4861317 d33032c 4861317 de6d503 4861317 de6d503 4861317 3065ecd 4861317 de6d503 4861317 74832a9 4861317 de6d503 4861317 de6d503 4861317 de6d503 4861317 3065ecd 4861317 de6d503 4861317 de6d503 4861317 de6d503 4861317 de6d503 4861317 de6d503 4861317 de6d503 4861317 3065ecd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | """
Maya Inspector v6 — Token input + WS connect + REST map
Runs from HF Space (no egress proxy blocking WS).
"""
import os, json, uuid, asyncio, datetime, threading, base64
import urllib.request, urllib.parse
import gradio as gr
from huggingface_hub import HfApi
HF_TOKEN = os.environ.get("HF_TOKEN", "")
MEMORY_REPO = "Melofhell00/maya-memory"
STATE_FILE = "state.json"
FIREBASE_KEY = "AIzaSyDtC7Uwb5pGAsdmrH2T4Gqdk5Mga07jYPM"
hf = HfApi(token=HF_TOKEN)
def read_state():
try:
url = f"https://huggingface.co/datasets/{MEMORY_REPO}/resolve/main/{STATE_FILE}"
req = urllib.request.Request(url, headers={"Authorization": f"Bearer {HF_TOKEN}"})
with urllib.request.urlopen(req, timeout=10) as r:
return json.loads(r.read())
except:
return {}
def write_state(state):
hf.upload_file(
path_or_fileobj=json.dumps(state, indent=2).encode(),
path_in_repo=STATE_FILE, repo_id=MEMORY_REPO, repo_type="dataset",
commit_message=f"inspector {datetime.datetime.utcnow().isoformat()}"
)
def decode_token(t):
try:
payload = t.split('.')[1] + '==='
return json.loads(base64.b64decode(payload))
except:
return {}
def exchange_refresh(rt):
url = f"https://securetoken.googleapis.com/v1/token?key={FIREBASE_KEY}"
data = urllib.parse.urlencode({"grant_type":"refresh_token","refresh_token":rt}).encode()
req = urllib.request.Request(url, data=data, headers={"Content-Type":"application/x-www-form-urlencoded"})
with urllib.request.urlopen(req, timeout=15) as r:
body = json.loads(r.read())
return body.get("id_token",""), body.get("refresh_token", rt)
def run_inspection(token_input):
"""Main function: take token, hit all endpoints, connect WS, map Maya."""
log = []
results = {}
token = token_input.strip() if token_input else ""
# Try refresh from bridge if no token given
if not token:
log.append("No token provided, trying bridge refresh...")
state = read_state()
rt = state.get("refresh_token", "")
ft = state.get("full_id_token", "")
if ft:
claims = decode_token(ft)
import time
if claims.get("exp", 0) > time.time():
token = ft
log.append(f"Using stored token (expires {datetime.datetime.fromtimestamp(claims['exp']).isoformat()})")
else:
log.append("Stored token expired")
if not token and rt:
try:
token, new_rt = exchange_refresh(rt)
if token:
log.append(f"Refreshed token OK ({len(token)} chars)")
state["refresh_token"] = new_rt
state["full_id_token"] = token
write_state(state)
except Exception as e:
log.append(f"Refresh failed: {e}")
if not token:
return "NO TOKEN", "\n".join(log), ""
# Decode token
claims = decode_token(token)
provider = claims.get("firebase",{}).get("sign_in_provider","?")
email = claims.get("email","?")
uid = claims.get("sub","?")
exp = claims.get("exp", 0)
log.append(f"Token: provider={provider} email={email} uid={uid}")
log.append(f"Expires: {datetime.datetime.fromtimestamp(exp).isoformat()}")
import time
if exp < time.time():
log.append("TOKEN EXPIRED!")
return "EXPIRED", "\n".join(log), ""
# Save token to bridge
try:
state = read_state()
state["full_id_token"] = token
state["last_updated"] = datetime.datetime.utcnow().isoformat()
state["source"] = "inspector-v6"
write_state(state)
log.append("Saved to bridge")
except Exception as e:
log.append(f"Bridge save error: {e}")
# REST endpoints
log.append("\n=== REST API ===")
rest_endpoints = [
("GET", "/external/agents"),
("GET", "/external/user"),
("GET", "/external/user/responders"),
]
for method, path in rest_endpoints:
try:
req = urllib.request.Request(
f"https://sesameai.app{path}",
headers={"Authorization": f"Bearer {token}"}
)
with urllib.request.urlopen(req, timeout=15) as r:
body = r.read().decode()
try:
data = json.loads(body)
results[path] = data
log.append(f"{path}: {json.dumps(data)[:300]}")
except:
results[path] = body[:200]
log.append(f"{path}: {body[:200]}")
except urllib.error.HTTPError as e:
body = e.read().decode()
log.append(f"{path}: HTTP {e.code} - {body[:200]}")
results[path] = f"HTTP {e.code}: {body[:200]}"
except Exception as e:
log.append(f"{path}: {e}")
# WebSocket connection
log.append("\n=== WEBSOCKET ===")
ws_results = []
def run_ws():
import asyncio as aio
try:
import websockets
except ImportError:
ws_results.append("websockets not installed")
return
async def connect():
client_name = str(uuid.uuid4())
tz = urllib.parse.quote(json.dumps({"timezone":"Europe/Athens"}))
url = f"wss://sesameai.app/agent-service-0/v1/connect?id_token={token}&client_name={client_name}&usercontext={tz}&character=Maya"
ws_results.append(f"Connecting to Maya...")
try:
async with websockets.connect(url, additional_headers={"Origin":"https://sesameai.app"}, open_timeout=15) as ws:
ws_results.append("CONNECTED!")
session_id = None
ice_servers = None
for i in range(10):
try:
msg = await aio.wait_for(ws.recv(), timeout=8)
try:
data = json.loads(msg)
msg_type = data.get("type", "unknown")
ws_results.append(f"MSG[{msg_type}]: {json.dumps(data)[:400]}")
if msg_type == "initialize":
session_id = data.get("session_id")
elif msg_type == "webrtc_config":
ice_servers = data.get("ice_servers", [])
except json.JSONDecodeError:
ws_results.append(f"RAW: {msg[:200]}")
except aio.TimeoutError:
ws_results.append(f"(timeout after msg {i})")
break
if session_id:
ws_results.append(f"\nSESSION_ID: {session_id}")
if ice_servers:
ws_results.append(f"ICE_SERVERS: {json.dumps(ice_servers)[:300]}")
# Try sending ping
try:
await ws.send(json.dumps({"type": "ping"}))
pong = await aio.wait_for(ws.recv(), timeout=3)
ws_results.append(f"PING->PONG: {pong[:200]}")
except:
pass
except Exception as e:
ws_results.append(f"WS ERROR: {type(e).__name__}: {e}")
loop = aio.new_event_loop()
aio.set_event_loop(loop)
loop.run_until_complete(connect())
loop.close()
t = threading.Thread(target=run_ws)
t.start()
t.join(timeout=60)
log.extend(ws_results)
# If we got agents, try to get agent details
agents_data = results.get("/external/agents")
if isinstance(agents_data, list) and len(agents_data) > 0:
log.append("\n=== AGENT DETAILS ===")
for agent in agents_data:
agent_uuid = agent.get("uuid") or agent.get("id")
agent_name = agent.get("name") or agent.get("character")
if agent_uuid:
log.append(f"Agent: {agent_name} UUID: {agent_uuid}")
# Try unread messages
for sub_path in [f"/external/agent/{agent_uuid}/unread_count",
f"/external/agent/{agent_uuid}/last_read_message"]:
try:
req = urllib.request.Request(
f"https://sesameai.app{sub_path}",
headers={"Authorization": f"Bearer {token}"}
)
with urllib.request.urlopen(req, timeout=10) as r:
body = r.read().decode()
log.append(f" {sub_path}: {body[:200]}")
except Exception as e:
log.append(f" {sub_path}: {e}")
# Compile results
all_results = json.dumps(results, indent=2, default=str)
status = "CONNECTED" if "CONNECTED!" in str(ws_results) else "WS FAILED"
if isinstance(agents_data, list):
status += f" | {len(agents_data)} agents"
return status, "\n".join(log), all_results
# Console script for extracting token from sesameai.app
CONSOLE_SCRIPT = """(async()=>{const db=await new Promise(r=>{const q=indexedDB.open('firebaseLocalStorageDb');q.onsuccess=e=>r(e.target.result)});const s=db.transaction('firebaseLocalStorage','readonly').objectStore('firebaseLocalStorage');const d=await new Promise(r=>{const q=s.getAll();q.onsuccess=e=>r(e.target.result)});for(const i of d){const m=i?.value?.stsTokenManager;if(m?.accessToken){console.log('TOKEN:',m.accessToken);console.log('REFRESH:',m.refreshToken);prompt('Copy this token:',m.accessToken);return;}}console.log('No token found');})()"""
with gr.Blocks(title="Maya Inspector v6", theme=gr.themes.Monochrome()) as app:
gr.Markdown("# Maya Inspector v6\nPaste Firebase token → REST + WS mapping")
gr.Markdown(f"**Get token:** Open sesameai.app, sign in, open console, paste:\n```\n{CONSOLE_SCRIPT}\n```")
with gr.Row():
token_in = gr.Textbox(label="Firebase ID Token", placeholder="paste token from console...", lines=3)
run_btn = gr.Button("INSPECT", variant="primary", size="lg")
status_out = gr.Textbox(label="Status", interactive=False)
log_out = gr.Textbox(label="Log", interactive=False, lines=25)
results_out = gr.Textbox(label="Raw Results", interactive=False, lines=15)
run_btn.click(fn=run_inspection, inputs=[token_in], outputs=[status_out, log_out, results_out])
app.launch(server_name="0.0.0.0", server_port=7860)
|