File indexing completed on 2026-08-12 09:36:18
0001 """SWF resolver mapping for Snapper event references.
0002
0003 The generic package returns event references naming stable resolver
0004 identifiers (snapper-ai DESIGN.md, Event-reference contract); this
0005 module is the SWF integration that maps those identifiers to concrete
0006 REST routes and MCP tools and refines availability. Registered
0007 identifiers stay stable; deployment URLs live only here.
0008 """
0009
0010 from django.urls import NoReverseMatch, reverse
0011
0012
0013
0014 RESOLVER_MAP = {
0015 'swf-testbed-system-state-events': {
0016 'rest': 'monitor_app:systemstateevent-list',
0017 'rest_params': 'run_number, event_type, state',
0018 'mcp_tools': ['swf_get_system_state', 'swf_list_runs'],
0019 'notes': ('Exact E0-E1 datataking transitions; filter by the '
0020 'run_number carried in the datataking lane hover.'),
0021
0022 'page': 'monitor_app:runs_list',
0023 'page_label': 'Runs and their transitions',
0024 },
0025 'swf-system-status-history': {
0026 'rest': 'monitor_app:system-status-history',
0027 'rest_params': 'name, start, end (ISO 8601), limit',
0028 'mcp_tools': [],
0029 'notes': ('Append-only health observations behind the assessed '
0030 'health component.'),
0031 'page': 'monitor_app:system_status',
0032 'page_label': 'System health checks',
0033 },
0034 'swf-panda-activity-history': {
0035 'rest': 'monitor_app:panda-api-tasks-list',
0036 'rest_params': 'days, status, taskname (substring)',
0037 'mcp_tools': ['panda_list_jobs', 'panda_list_tasks',
0038 'panda_error_summary', 'panda_study_job'],
0039 'notes': ('Authoritative PanDA job and task records; event time '
0040 'is modificationtime.'),
0041 'page': 'monitor_app:panda_tasks_list',
0042 'page_label': 'PanDA tasks and jobs',
0043 },
0044 }
0045
0046
0047 def annotate_references(references):
0048 """Refine generic event references with concrete SWF transports.
0049
0050 A mapped resolver becomes available with its REST URL and MCP tool
0051 names; an unmapped one stays unknown — never claimed available.
0052 """
0053 annotated = []
0054 for reference in references:
0055 entry = dict(reference)
0056 mapping = RESOLVER_MAP.get(entry.get('resolver'))
0057 if mapping:
0058 try:
0059 rest_url = reverse(mapping['rest'])
0060 except NoReverseMatch:
0061 rest_url = ''
0062 entry['availability'] = 'available' if rest_url else 'unknown'
0063 entry['transport'] = {
0064 'rest_url': rest_url,
0065 'rest_params': mapping['rest_params'],
0066 'mcp_tools': mapping['mcp_tools'],
0067 'notes': mapping['notes'],
0068 }
0069 if mapping.get('page'):
0070 try:
0071 entry['page_url'] = reverse(mapping['page'])
0072 entry['page_label'] = mapping.get(
0073 'page_label') or entry.get('component', '')
0074 except NoReverseMatch:
0075 pass
0076 annotated.append(entry)
0077 return annotated