"""Synthetic, disposable UI fixture; never uses model or database providers.""" import json import os import tempfile from pathlib import Path import uvicorn from viano_bug_analysis.api import APIConfig, Client, Project from viano_bug_analysis.api.app import create_app from viano_bug_analysis.lifecycle import Workspace, CheckpointStore from viano_bug_analysis.lifecycle.job import timestamp from viano_bug_analysis.lifecycle.storage import atomic_json, json_bytes from viano_bug_analysis.package.factory import PackageFactory from viano_bug_analysis.case import CaseBuilder import viano_bug_analysis.api.dashboard as dashboard import viano_bug_analysis.api.operations as operations TOKEN = 'ui_fixture_' + 'x' * 40 def seed(root, case_id, title, completed=False): workspace = Workspace(root) store = CheckpointStore(workspace) now = timestamp() manifest = {'format':'viano-bug-case-package','format_version':1,'case_id':case_id, 'package_id':'preview-'+case_id,'package_generation':0,'analysis_revision':0, 'project':{'id':'viano-core','type':'wow','profile':'vcore'},'created_at':now,'updated_at':now, 'state':'NEW','routing':{'destination':'inbox','reason':None,'retry_count':0,'retry_not_before':None}, 'artifacts':{'case':None,'diagnosis':None,'change_request':None,'case_inputs':'inputs.json'}, 'history':{'analysis_revisions':0,'reproductions':0,'evidence':0,'handoffs':0,'feedback':0,'events_ref':None},'integrity':{}} contents={'inputs.json':json_bytes({'format':'viano-case-inputs','format_version':1,'reports':['report.json']}), 'report.json':json_bytes({'format':'viano-bug-report','format_version':1,'title':title, 'observations':[{'text':'Synthetic UI fixture observation'}]})} path=workspace.inbox/(case_id+'.zip');PackageFactory().create(path,manifest,contents) store.intake(path);path.unlink() identity=case_id,manifest['package_id'];CaseBuilder(store).build(*identity) for state,pointer in [('INTERPRETING_CASE','case_interpretation'),('GENERATING_HYPOTHESES','hypotheses')]: ref=pointer+'.json';store.advance(*identity,state,step_id=state, artifacts={pointer:ref},additions={ref:json_bytes({'analysis_revision':1})}) store.advance(*identity,'INVESTIGATING_HYPOTHESES',step_id='investigate') hypothesis={'id':'H1','proposal':{'title':'Synthetische Arbeitshypothese','mechanism':'Die erwartete Aktion bleibt aus.'}, 'confidence':'supported','disposition':'open','iterations':2,'evidence_refs':['E000001'],'working_brief_ref':'brief.json'} store.advance(*identity,'INVESTIGATING_HYPOTHESES',step_id='fixture-state', artifacts={'investigation_state':'state.json'},details={'operation':'investigation-state','state_ref':'state.json'}, additions={'state.json':json_bytes({'analysis_revision':1,'hypotheses':{'H1':hypothesis}}), 'brief.json':json_bytes({'analysis_revision':1,'hypothesis_id':'H1','brief':{'findings':[ {'direction':'support','text':'Die Beobachtung passt zur Hypothese.','evidence_refs':['E000001']}, {'direction':'against','text':'Der vorhandene Handler spricht dagegen.','evidence_refs':['E000002']}], 'uncertainties':['Die Laufzeitkonfiguration ist noch ungeklärt.']}})}) measured = [ ('BUILDING_CASE','entity_resolution_plan_v4','regular',2500,500), ('INTERPRETING_CASE','case_interpretation_v1','regular',2000,500), ('GENERATING_HYPOTHESES','hypotheses_v4','regular',1500,500), ('INVESTIGATING_HYPOTHESES','investigation_lean_v21','regular',4000,1000), ] if completed: measured += [ ('BUILDING_DIAGNOSIS','diagnosis_v8','regular',1500,500), ('BUILDING_DIAGNOSIS','change_request_v9','regular',500,0), ] measured.append(('INVESTIGATING_HYPOTHESES','investigation_format_repair_v1','correction',3000,900)) for i,(phase,prompt,category,inp,out) in enumerate(measured): ref=f'call{i}.json';request=f'request{i}.json' call={'rounds':1,'phase':phase,'request_ref':request,'outcome':{ 'usage_classification':category,'metadata':{'input_tokens':inp,'output_tokens':out, 'reasoning_tokens':out//2,'cached_input_tokens':1000}}} store.advance(*identity,'INVESTIGATING_HYPOTHESES',step_id=f'call{i}', details={'operation':'llm-round','result_ref':ref}, additions={ref:json_bytes(call),request:json_bytes({'prompt_version':prompt})}) if completed: store.advance(*identity,'BUILDING_DIAGNOSIS',step_id='diagnosis') documents={ 'diagnosis.json':{'analysis_revision':1,'diagnosis':{'status':'confirmed','root_cause':'Synthetische Diagnose für die Oberflächenprüfung','confidence':'strongly_supported'}}, 'coding.json':{'analysis_revision':1,'assignment':'assigned','human_dev_assigned':True, 'request':{'required_change':'SQL-Vorlage mit Platzhaltern erstellen.','placeholders':['Passende Koordinaten ergänzen.']}}, 'decision.json':{'human_dev':{'status':'assigned','summary':'Passende Spawndaten ermitteln und prüfen.'}}, } store.advance(*identity,'BUILDING_DIAGNOSIS',step_id='diagnosis-document', details={'operation':'diagnosis-complete','diagnosis_ref':'diagnosis.json'}, artifacts={'diagnosis':'diagnosis.json'},additions={ref:json_bytes(doc) for ref,doc in documents.items()}) store.advance(*identity,'BUILDING_DIAGNOSIS',step_id='handoff-document', details={'operation':'change-request-complete','change_request_ref':'coding.json','decision_ref':'decision.json'}, artifacts={'change_request':'coding.json'}) store.advance(*identity,'OUTPUT_READY',step_id='done') return identity if __name__ == '__main__': with tempfile.TemporaryDirectory(prefix='vba-dashboard-', dir=os.environ.get('VBA_UI_TEST_WORKSPACE')) as temporary: root=Path(temporary) identity=seed(root,'BUG-000020','Wolpertinger fehlen in Dun Morogh') seed(root,'BUG-000017','Leuchtbrille – Kontrolllauf',completed=True) # Display-only test request fixture; real feedback/budget binding is tested # independently through the actual coordinator in test_human_web.py. store=CheckpointStore(Workspace(root));ref='ui-test-request.json' request={'case_id':identity[0],'package_id':identity[1],'analysis_revision':1,'request_id':'ui-test', 'executor':'human','hypothesis_id':'H1','question':'Ist die Kreatur nach Questannahme sichtbar?', 'environment':'Lokaler Testserver','prerequisites':['Quest noch nicht angenommen'], 'steps':['Quest annehmen','Umgebung beobachten'],'requested_observations':['Sichtbarkeit und Build notieren'], 'deadline':'2099-01-01T00:00:00Z'} store.advance(*identity,'BLOCKED',step_id='ui-test-wait',reason='AWAITING_TEST_FEEDBACK', retry_not_before=request['deadline'],artifacts={'async_test_request':ref}, details={'operation':'async-test-wait','request_ref':ref},additions={ref:json_bytes(request)}) config=APIConfig(root,(Project('viano-core','wow','vcore'),), (Client('preview','VBA_UI_TEST_TOKEN',('viano-core',),operator=True),)) from viano_bug_analysis.api.users import Users Users(root/'auth/users.sqlite3').manage('create_user','preview','ui-fixture-password') os.environ['VBA_UI_TEST_TOKEN']=TOKEN dashboard.read_status=lambda _: {'observer':'LIVE','service_id':'fixture-worker'} operations.read_status=dashboard.read_status folder=root/'runtime/worker';folder.mkdir(exist_ok=True) atomic_json(folder/'status.json',{'status':'ANALYZING','service_id':'fixture-worker','updated_at':timestamp(), 'case':{'case_id':identity[0],'package_id':identity[1]}}) uvicorn.run(create_app(config),host='127.0.0.1',port=int(os.environ.get('VBA_UI_TEST_PORT','8765')),access_log=False)