"""EAgent local Chromium bridge. Uses its own profile; never uploads cookies.""" import argparse,json,os,time,sys,pathlib,getpass,urllib.request,urllib.error from playwright.sync_api import sync_playwright BASE='https://ai.xxxs.shop'; ROOT=pathlib.Path.home()/'.eagent-local-bridge'; SECRET=ROOT/'device.json' def http(method,path,body=None,token=None): headers={'Content-Type':'application/json','User-Agent':'EAgent-LocalBridge/0.1'} if token:headers['Authorization']='Bearer '+token req=urllib.request.Request(BASE+path,json.dumps(body).encode() if body is not None else None,headers=headers,method=method) with urllib.request.urlopen(req,timeout=35) as r:return json.load(r) def save(config): ROOT.mkdir(mode=0o700,parents=True,exist_ok=True) SECRET.write_text(json.dumps(config)); try:os.chmod(SECRET,0o600) except OSError:pass def pair(): code=input('Paste the one-time pairing code from EAgent: ').strip() name=input('Device name [My Windows PC]: ').strip() or 'My Windows PC' response=http('POST','/api/bridge/pair/claim',{'code':code,'name':name}) save({'token':response['device_token'],'name':name});print('Paired. Device token saved in',SECRET) def extract(page): # Site selectors are best effort; they may need updating as DeepSeek changes. selectors=['.ds-markdown','.markdown-body','[class*="markdown"]'] for selector in selectors: items=page.locator(selector) if items.count(): txt=items.last.inner_text(timeout=3000).strip() if txt:return txt return '' def answer(page,prompt): if '/sign_in' in page.url or '/login' in page.url:raise RuntimeError('Please log in to DeepSeek locally first') field=page.locator('textarea').first if field.count()==0:field=page.locator('[contenteditable="true"]').first if field.count()==0:raise RuntimeError('DeepSeek input not found; open the chat page') previous=extract(page) field.fill(prompt,timeout=8000);field.press('Enter') start=time.monotonic();last='';stable=0 while time.monotonic()-start<135: page.wait_for_timeout(1500);response=extract(page) if response and response!=previous: stable=stable+1 if response==last else 0 if stable>=3:return response last=response raise RuntimeError('Timed out waiting for the DeepSeek answer') def main(): parser=argparse.ArgumentParser(description='EAgent browser bridge; keeps cookies on this PC') parser.add_argument('--pair',action='store_true',help='Pair using a one-time code') args=parser.parse_args() if args.pair:pair() if not SECRET.exists():sys.exit('Not paired: run python bridge_client.py --pair') token=json.loads(SECRET.read_text())['token'] with sync_playwright() as pw: ROOT.mkdir(mode=0o700,parents=True,exist_ok=True) context=pw.chromium.launch_persistent_context(str(ROOT/'browser-profile'),headless=False) page=context.pages[0] if context.pages else context.new_page() page.goto('https://chat.deepseek.com/',wait_until='domcontentloaded',timeout=45000) print('Please log in to DeepSeek in this LOCAL Chromium window. Leave this client running.') while True: try: data=http('GET','/api/bridge/poll',token=token) job=data.get('job') if job: print('Task received:',job['id'], 'Preview:',job['prompt'][:80]);print('This will send the prompt to DeepSeek using your local browser.') if input('Approve sending? [y/N]: ').strip().lower()!='y': http('POST','/api/bridge/result',{'job_id':job['id'],'reply':'','error':'Rejected locally'},token=token) else: try:reply=answer(page,job['prompt']);http('POST','/api/bridge/result',{'job_id':job['id'],'reply':reply},token=token);print('Answer sent.') except Exception as ex:http('POST','/api/bridge/result',{'job_id':job['id'],'reply':'','error':str(ex)[:800]},token=token);print('Error:',ex) time.sleep(3) except KeyboardInterrupt:break except urllib.error.HTTPError as ex: if ex.code==401:sys.exit('Device authorization revoked or expired. Re-pair from EAgent.') print('Service returned',ex.code);time.sleep(8) except Exception as ex:print('Temporary error:',str(ex)[:200]);time.sleep(8) context.close() if __name__=='__main__':main()