
    jM                    4   d dl mZ d dlmZ d dlmZ d dlZd dlZd dlZd dlm	Z	m
Z
mZmZ  e	ded      Z ed	      Zd
ZdZd ZddZddZdZedz  Zej-                  d      d        Zej-                  d      d        Zej-                  d      d        Zy)    )annotations)datetime)PathN)	Blueprintjsonifyrequestrender_template_stringapolloz/apollo)
url_prefixz3/home/hermes/.hermes/profiles/hermesvps/config.yamlz/home/hermes/.local/bin/hermesz'/home/hermes/.hermes/profiles/hermesvpsc            	        t        j                  t        j                  d            xs i } | j	                  d      xs i }| j	                  d      xs i }| j	                  d      xs i }t        |j	                  d            |j	                  d      xs dt        |j	                  d	            t        |j	                  d
            t        |j	                  d            dS )Nzutf-8)encodingsttvoice	wake_wordenabledlanguageautoauto_ttsbarge_in)r   r   r   r   r   )yaml	safe_loadCONFIG	read_textgetbool)datar   r   wakes       */opt/struktur/projects-dashboard/apollo.py_voice_statusr      s    >>&**G*<=CD
((5/
RCHHW#E88K &BDCGGI&'GGJ'16:./:./$((9-.     c                8    | dk(  rdnd}| dk(  rdnd}d| d| dS )	NdailyTagesbriefingWochenbriefingheutezdie laufende WochezErstelle ein kompaktes Hermes-u    auf Deutsch für u{  .
Nutze nur lesende Zugriffe und den aktuellen Hermes-Zustand. Keine Änderungen, keine externen Aktionen.
Priorisiere: 1) gestörte oder fehlgeschlagene Jobs oder Projekte, 2) laufende wichtige Arbeiten,
3) Entscheidungen oder Freigaben, die der Benutzer treffen muss, 4) die nächsten drei sinnvollen Schritte.
Keine Floskeln. Kennzeichne Unsicherheit. Maximal 12 kurze Punkte. )kindlabelhorizons      r   _briefing_promptr*      s?    #wO4DEg.BG-eW4Fwi PC F Fr    c                6   t         j                  j                         }|j                  dt        d       t
        ddddt        |       g}	 t        j                  |ddd|	      }|j                  xs dj                         }|j                  dk7  rd|j                  xs |xs ddd  fS |j                         D cg c]  }|j                  d      r| }}ddj!                  |      j                         fS # t        j                  $ r Y y
w xY wc c}w )Nz/home/hermes)HOMEHERMES_HOMEz-p	hermesvpsz--safe-modez-zTZ   )capture_outputtexttimeoutenv)Fz-Briefing-Zeitlimit nach 90 Sekunden erreicht. r   FzHermes-Briefing fehlgeschlagen.i<u   ⚠ A previous `hermes update`
)osenvironcopyupdatePROFILE_HOMEHERMESr*   
subprocessrunTimeoutExpiredstdoutstrip
returncodestderr
splitlines
startswithjoin)r'   r3   cmdresultr1   lineliness          r   _run_briefingrJ   )   s   
**//
CJJ|DE4mT;KD;Q
RCFDtRUXY MMR&&(DAv}}QQ0QSXSYZZZ"oo/idtGg7hTiEi5!''))) $$ FEF
 js   C= ?DD=DDa  <!doctype html>
<html lang="de"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Hermes Apollo</title>
<style>
*{box-sizing:border-box}body{margin:0;background:#080d14;color:#e8f2ff;font-family:Segoe UI,system-ui,sans-serif;min-height:100vh}
header{display:flex;justify-content:space-between;align-items:center;padding:22px 30px;border-bottom:1px solid #173044;background:#0b121c}
h1{margin:0;font-size:24px}.sub{color:#85a8c2;font-size:13px;margin-top:4px}.nav{display:flex;gap:8px;flex-wrap:wrap}
button,.link{border:1px solid #24516b;background:#102333;color:#8fe8ff;border-radius:8px;padding:9px 13px;cursor:pointer;text-decoration:none;font-size:13px}
button:hover,.link:hover{background:#17364a}.wrap{padding:28px;display:grid;grid-template-columns:1.2fr .8fr;gap:18px}
.panel{background:#0d1722;border:1px solid #173044;border-radius:14px;padding:18px}.panel h2{margin:0 0 14px;font-size:15px;color:#a9dff2;text-transform:uppercase;letter-spacing:.08em}
.orb{width:220px;height:220px;border-radius:50%;margin:18px auto;background:radial-gradient(circle,#7cf3ff 0,#178bb0 18%,#0d3448 40%,#09131e 67%);box-shadow:0 0 50px #28d7ff55;border:2px solid #4ce6ff;display:flex;align-items:center;justify-content:center;text-align:center}
.statusgrid{display:grid;grid-template-columns:repeat(2,1fr);gap:9px}.status{background:#0a111a;border:1px solid #183147;border-radius:9px;padding:11px}
.status b{display:block;color:#8fe8ff;font-size:12px}.status span{font-size:14px}.good{color:#5ee6a8}.briefing{white-space:pre-wrap;line-height:1.55;color:#d8e7f2;min-height:240px}
.actions{display:flex;gap:8px;margin-bottom:14px;flex-wrap:wrap}.projects{display:grid;grid-template-columns:repeat(2,1fr);gap:8px}
.project{border:1px solid #183147;border-radius:8px;padding:10px;background:#09121b}.project .name{font-size:13px}.project .state{font-size:11px;color:#8da8ba;margin-top:4px}
.clock{font-size:34px;font-variant-numeric:tabular-nums;text-align:center;margin-top:10px}.wall .wrap{grid-template-columns:1fr 1fr}.wall header{padding:14px 22px}
@media(max-width:900px){.wrap{grid-template-columns:1fr}.projects{grid-template-columns:1fr}.orb{width:180px;height:180px}}
</style></head><body>
uc
  
<header><div><h1>Hermes Apollo</h1><div class="sub">Voice · Briefings · Wall Mode · bestehendes Hermes</div></div>
<div class="nav"><a class="link" href="https://hermes.agentsolutions-mallorca.com" target="_blank">Hermes öffnen</a>
<a class="link" href="/">Projects</a><button onclick="toggleWall()">Wall Mode</button></div></header>
<main class="wrap">
<section class="panel"><h2>Realtime Voice</h2><div class="orb"><strong>HERMES<br>APOLLO</strong></div>
<div class="statusgrid" id="voiceStatus"><div class="status"><b>Status</b><span>Lade…</span></div></div>
<div class="clock" id="clock"></div></section>
<section class="panel"><h2>Briefing</h2><div class="actions">
<button onclick="briefing('daily')">Daily Briefing</button><button onclick="briefing('weekly')">Weekly Briefing</button></div>
<div class="briefing" id="briefing">Daily oder Weekly Briefing auswählen.</div></section>
<section class="panel"><h2>Projektstatus</h2><div class="projects" id="projects">Lade…</div></section>
<section class="panel"><h2>Apollo-Prinzip</h2>
<div class="briefing">Voice läuft nativ über Hermes. Diese Ansicht bündelt nur die fehlenden Apollo-Funktionen: zentraler Einstieg, Briefings und Wall Mode. Browser, Memory, Agenten, Routing und Tools bleiben im vorhandenen Hermes.</div>
</section></main>
<script>
function clock(){document.getElementById('clock').textContent=new Date().toLocaleTimeString('de-DE',{hour:'2-digit',minute:'2-digit',second:'2-digit'})}setInterval(clock,1000);clock();
function toggleWall(){document.body.classList.toggle('wall');if(!document.fullscreenElement){document.documentElement.requestFullscreen?.()}else{document.exitFullscreen?.()}}
async function loadVoice(){let d=await fetch('/apollo/api/voice').then(r=>r.json());let rows=[['STT',d.stt],['Sprache',d.language],['Auto-TTS',d.auto_tts],['Barge-in',d.barge_in],['Wake Word',d.wake_word]];document.getElementById('voiceStatus').innerHTML=rows.map(x=>`<div class="status"><b>${x[0]}</b><span class="${x[1]===true?'good':''}">${x[1]===true?'aktiv':x[1]===false?'aus':x[1]}</span></div>`).join('')}
async function loadProjects(){let d=await fetch('/api/status').then(r=>r.json());document.getElementById('projects').innerHTML=d.map(x=>`<div class="project"><div class="name">${x.id}</div><div class="state">${x.status}</div></div>`).join('')}
async function briefing(kind){let el=document.getElementById('briefing');el.textContent='Hermes erstellt das Briefing…';let d=await fetch('/apollo/api/briefing?kind='+kind).then(r=>r.json());el.textContent=d.text||d.error||'Kein Ergebnis';}
loadVoice();loadProjects();setInterval(loadProjects,30000);
</script></body></html>r4   c                      t        t              S )N)r	   APOLLO_HTMLr&   r    r   indexrM   d   s    !+..r    z
/api/voicec                     	 t        t                     S # t        $ r"} t        dt        |       i      dfcY d } ~ S d } ~ ww xY w)Nerror  )r   r   	Exceptionstr)excs    r   	api_voicerT   i   s=    1}'' 1S*+S001s    	A ;A A z/api/briefingc                 v   t         j                  j                  d      xs dj                         j	                         } | dvrt        ddi      dfS t        |       \  }}|| t        j                         j                         j                  d      d	}|r||d
<   t        |      S ||d<   t        |      dfS )Nr'   r"   >   r"   weeklyrO   z kind muss daily oder weekly seini  seconds)timespec)successr'   generated_atr1   rP   )r   argsr   r@   lowerr   rJ   r   now
astimezone	isoformat)r'   okr1   payloads       r   api_briefingrb   q   s    LLV$/668>>@D&&!CDEsJJT"HBdHLLN<U<U<W<a<akt<a<uvG	wGG7S  r    )r'   rR   returnrR   )r'   rR   rc   ztuple[bool, str])
__future__r   r   pathlibr   r6   r<   r   flaskr   r   r   r	   __name__	apollo_bpr   r;   r:   r   r*   rJ   rL   routerM   rT   rb   r&   r    r   <module>rj      s    "   	   E EhY?		C	D	)8F*(   0 / / 1 1 !
! "
!r    