import json,re,time
from hermes_constants import set_hermes_home_override, reset_hermes_home_override
from tools.skills_tool import _find_all_skills
from agent.auxiliary_client import call_llm
HOME='/home/hermes/.hermes/profiles/redakteur'
CASES=[
('Q1','Prüfe diese fachliche Behauptung anhand belastbarer Quellen und gib nur belegte Aussagen frei.', ['grounded-citations']),
('Q2','Erstelle aus den gelieferten Daten eine saubere Excel-Arbeitsmappe mit Tabellen und Formeln.', ['xlsx']),
('Q3','Bearbeite ein GitHub-Issue vollständig bis zu einem überprüfbaren Pull Request.', ['github-issue-to-pr']),
('Q4','Finde die Ursache eines schwer reproduzierbaren Python-Fehlers mit Debugger und systematischer Fehleranalyse.', ['python-debugpy','systematic-debugging']),
('Q5','Bereite ein YouTube-Video inhaltlich auf und arbeite mit dessen Transkript.', ['youtube-content']),
('Q6','Erstelle eine professionelle PowerPoint-Präsentation aus dem bereitgestellten Material.', ['powerpoint']),
('Q7','Lies ein PDF aus, prüfe dessen Inhalt und extrahiere die relevanten Fakten.', ['pdf']),
('Q8','Antworte nur mit einer kurzen Begrüßung. Keine Werkzeuge oder Spezialabläufe nötig.', []),
]
def extract_text(r):
m=r.choices[0].message
return getattr(m,'content',None) or getattr(m,'reasoning_content',None) or ''
def parse(text):
try:return json.loads(text)
except Exception:
m=re.search(r'\{.*\}',text,re.S)
return json.loads(m.group(0)) if m else {}
t=set_hermes_home_override(HOME)
try:
skills=sorted(_find_all_skills(),key=lambda x:x['name'])
allowed={x['name'] for x in skills}
skill_text='\n'.join(f"- {x['name']}: {x.get('description','')} [category: {x.get('category') or 'general'}]" for x in skills)
cases='\n'.join(f"{qid}: {q}" for qid,q,_ in CASES)
prompt=f'''Du bist ein Skill-Router. Wähle für jeden Fall nur Skills, die materiell helfen.\n\nREGELN:\n- Erlaubt sind ausschließlich Namen aus der Liste.\n- 0 bis 5 Skills pro Fall.\n- Lieber keinen Skill als einen nur entfernt passenden.\n- Deutsche Anfrage und englische Skillbeschreibung können semantisch zusammenpassen.\n- Keine Erklärungen außerhalb JSON.\n\nERLAUBTE SKILLS:\n{skill_text}\n\nFÄLLE:\n{cases}\n\nAntworte exakt als JSON: {{"Q1":["skill"],...,"Q8":[]}}'''
print('VISIBLE_SKILLS',len(skills),'PROMPT_CHARS',len(prompt))
for effort in ('low','medium'):
st=time.time()
r=call_llm(provider='openai-codex',model='gpt-5.6-luna',messages=[{'role':'user','content':prompt}],temperature=0.0,max_tokens=1200,timeout=60,reasoning_config={'enabled':True,'effort':effort})
text=extract_text(r); obj=parse(text)
score=0; invented=[]; details=[]
for qid,_,required in CASES:
chosen=obj.get(qid,[]) if isinstance(obj,dict) else []
if not isinstance(chosen,list): chosen=[]
invented.extend([x for x in chosen if x not in allowed])
if required:
hit=all(x in chosen for x in required)
else:
hit=(len(chosen)==0)
score+=int(hit)
details.append((qid,required,chosen,hit))
u=getattr(r,'usage',None)
print('\nEFFORT',effort.upper(),'SECONDS',round(time.time()-st,2),'SCORE',f'{score}/{len(CASES)}','INVENTED',invented)
if u: print('USAGE',getattr(u,'prompt_tokens',None),getattr(u,'completion_tokens',None),getattr(u,'total_tokens',None))
for d in details: print('CASE',d)
print('RAW',text[:4000])
finally:
reset_hermes_home_override(t)