AISA v2.0 / Technical documentation / build_operations_examples.py
build_operations_examples.py
Python · 67 lines · 5,473 bytes · wiki path 10 Architecture/ui/build_operations_examples.py · download the raw file · cited from Case protocol · Decision register
Same folder: agent-catalog.json · agent_catalog.py · agent_map_svg.py · build_agent_map.py · build_case_content_docs.py · build_case_journeys.py · build_case_traces.py · case-content.json · case-journeys.json · case-runtime-traces.json · case-ui-specs.json · case_content.py · case_ui_model.py · frequent-operations.json · memory-capabilities.json · validate_agent_map.py · validate_case_content.py
"""Publish the same operations UI and stage vocabulary at all presentation levels."""
from pathlib import Path
import html
import json
from case_ui_model import LABELS
from _paths import WORKSPACE
HERE=Path(__file__).resolve().parent
PREVIEW_VIEWS={
'queue':('Inbox','DC-02','main/support/S1','internal','','main'),
'workspace':('Case chat','DC-02','main/data/S2','internal','','main'),
'decision':('Configuration sub-plans','CF-05','main/configuration/S2','internal','main/configuration/S2/state-plan','template-0'),
'approval':('Operator approval','DC-02','main/data/S5','internal','main/data/S5/state-send','main'),
'result':('Customer conversation','DC-02','main/support/closure','customer','','main'),
'learning':('Learning review','DC-02','after/data/S8','internal','','main'),
}
def build_preview(template,data,traces):
"""Use the complete shared renderer with one case; omit review chrome only."""
ids={v[1] for v in PREVIEW_VIEWS.values()}
cases=json.dumps({'cases':[c for c in data['cases'] if c['id'] in ids]},ensure_ascii=False).replace('<','\\u003c')
trace=json.dumps({cid:traces[cid] for cid in sorted(ids)},ensure_ascii=False).replace('<','\\u003c')
out=template.replace('@@CASES@@',cases).replace('@@TRACES@@',trace).replace('@@INDEX@@','').replace('@@OPTIONS@@','')
out=out.replace('<body>','<body class="preview-mode">').replace('<title>AISA — Cases on their module flows</title>','<title>AISA — Operations preview</title>')
css='''<style>
.preview-mode{background:#fff}.preview-mode>header,.preview-mode>footer,
.preview-mode #case-title,.preview-mode #scope-note,.preview-mode #flow,
.preview-mode .stage-caption,.preview-mode #state-control,.preview-mode .preview-nav,
.preview-mode #inspector,.preview-mode #source,.preview-mode #route-exception{display:none}
.preview-mode>main{padding:0;max-width:none}.operations-nav{padding:12px 0 16px}
.operations-nav p{font-size:14px;margin:0 0 10px;color:#66778c}
.operations-views{display:flex;flex-wrap:wrap;gap:6px}
.operations-views button{font-size:14px}.operations-views button[aria-pressed=true]{background:#edf3fc;border-color:#245caf;color:#245caf}
.operations-foot{padding:14px 0;font-size:13px;color:#66778c;display:flex;gap:12px;flex-wrap:wrap}
</style>'''
out=out.replace('</head>',css+'</head>')
buttons=''.join('<button type="button" data-view="'+key+'" aria-pressed="false">'+html.escape(value[0])+'</button>' for key,value in PREVIEW_VIEWS.items())
toolbar='<div class="operations-nav" id="operations-nav"><p>Working conversations: Ablera operators, agent tasks, sub-plans and decisions. All messages and role assignments are illustrative.</p><div class="operations-views" id="operations-views">'+buttons+'</div></div>'
out=out.replace('<main>',toolbar+'<main>')
footer='<div class="operations-foot"><span>Illustrative records · no live system actions</span><a id="preview-open" href="case_journeys.html#DC-02" target="_top">Open this view in the full walkthrough</a></div>'
script='''<script>
const previewViews=PREVIEW_CONFIG;
let previewSelection='workspace';
function afterRender(s){
document.querySelectorAll('[data-view]').forEach(b=>b.setAttribute('aria-pressed',String(b.dataset.view===previewSelection)));
el('preview-open').href='case_journeys.html?'+new URLSearchParams({stage:activeStage().uid,state:s.uid,surface,scenario,thread:selectedConversation(s).key})+'#'+selected.id;
}
function choosePreviewView(name){
const item=previewViews[name]||previewViews.workspace;
previewSelection=name;selected=cases.find(c=>c.id===item[1]);resetStage();activeUid=item[2];surface=item[3];stateUid=item[4];scenario='first';chatThreads[threadKey(active())]=item[5];render();
}
el('operations-views').addEventListener('click',e=>{const b=e.target.closest('[data-view]');if(b)choosePreviewView(b.dataset.view);});
choosePreviewView(urlOptions.get('view')||'workspace');
if(urlOptions.get('compact')==='1')el('operations-nav').hidden=true;
</script>'''.replace('PREVIEW_CONFIG',json.dumps(PREVIEW_VIEWS))
out=out.replace('</body>',footer+script+'</body>')
(HERE/'operations_preview.html').write_text(out,encoding='utf-8')
LINKS={
'support':{'S1':'40-support/stage-classification','route':'40-support/support-module','closure':'40-support/support-module'},
'data':{'S3':'40-support/stage-solution-take','S2':'40-support/stage-investigation','S4':'40-support/stage-solution-take','S5':'40-support/stage-application-and-verification','S6':'40-support/stage-application-and-verification','S7':'40-support/stage-application-and-verification','S8':'40-support/stage-precipitation'},
'configuration':{'S1':'20-configuration/stage-normalization','S2':'20-configuration/stage-abacus','S3':'20-configuration/stage-ipal','S4':'20-configuration/stage-offer','S5':'20-configuration/stage-serdica','joint':'20-configuration/configuration-module','release':'20-configuration/configuration-module'},
'commercial':{s:'45-commercial/offer-workflow' for s in ['O1','O2','O3','O4']},
'source':{'S1':'30-source/stage-planning','S2':'30-source/stage-planning','S3':'30-source/stage-implementation','S4':'30-source/stage-test-and-corrections','S5':'30-source/stage-deployment-scripts','S6':'30-source/stage-deploy-and-reversal','S7':'30-source/stage-deploy-and-reversal','S8':'30-source/stage-deploy-and-reversal'},
}