"""Production graph-to-answer context adapter; no benchmark or oracle dependencies.""" from .context_policy import joined_candidates def graph_context(result: dict) -> dict: """Remove storage/profile metadata that cannot answer the actual question. Uses only actual retrieval output and query intent, never gold annotations. Values/subjects/source paths are copied without inventing or rewriting facts. """ facts = []; intent = result['constraints'] shared_year_query = intent.get('mentions_shared') and intent.get('mentions_academic_year') work_listing = (intent.get('mentions_work_listing', False) or shared_year_query or (intent.get('mentions_title') and any( row.get('fact_type') in {'person_thesis','person_work'} and not row.get('title') for row in result['facts']))) academic_records = [] for row in result['facts']: kind = row.get('fact_type', '') if kind.startswith('shared_'): field = {'shared_keyword': 'keyword', 'shared_category': 'category', 'shared_document_author': 'document_author'}.get(kind) if field: for side in ['left', 'right']: facts.append({'person': row[f'{side}_person'], field: row[field], 'document_path': row.get(f'{side}_document_path'), 'source_url': row.get(f'{side}_source_url')}) continue if not row.get('person'): continue allowed = {'person', 'document_path', 'source_url', 'keyword', 'category', 'document_author'} if intent['mentions_title'] or work_listing: allowed.add('title') if intent['mentions_title'] or intent['mentions_academic_year'] or intent['years'] or work_listing: allowed.add('year') if intent['mentions_start_year']: allowed.add('start_year') fact = {k: v for k, v in row.items() if k in allowed and v is not None} if (intent.get('thesis_types') or intent.get('work_types')) and kind in {'person_thesis','person_work'}: work_type=row.get('thesis_type') or row.get('work_type') if work_type: fact['work_type']=work_type if work_listing and kind in {'person_thesis', 'person_work'}: # Stable source record identity distinguishes two untitled projects # by the same person in the same year. Never use Neo4j element IDs. fact.update(record_id=row.get('thesis_id') or row.get('work_id'), work_type=row.get('thesis_type') or row.get('work_type'), work_label=row.get('heading'), title=row.get('title')) fact = {k: v for k, v in fact.items() if v is not None or k == 'title'} if fact not in academic_records: academic_records.append(fact) if fact not in facts: facts.append(fact) sources=result.get('sources') if sources is None: sources=[{k:d[k] for k in ['document_path','source_url'] if d.get(k)} for d in result.get('documents',[])] context={'status':result['status'],'reason':result['reason'],'facts':facts,'sources':sources, 'aggregation':result['aggregation'],'complete':result.get('complete'), 'truncated':result.get('truncated',False), 'truncation_reasons':result.get('truncation_reasons',[]), 'index_version':result.get('index_version')} context['answer_candidates']=joined_candidates(facts,intent) context['question'] = result.get('query', '') context['clarification'] = result.get('clarification') context['requested_people'] = list(dict.fromkeys(row['name'] for row in result.get('resolved_entities', []) if row.get('kind') == 'Person' and row.get('name'))) shared_values={} for fact in facts: for field in ['keyword','category','document_author']: if intent.get('mentions_shared') and fact.get(field) is not None: shared_values.setdefault((field,fact[field]),set()).add(fact['person']) people=context['requested_people'] context['shared_properties']=[{'field':field,'value':value,'people':people} for (field,value),witnesses in shared_values.items() if len(people)>=2 and set(people)<=witnesses] comparison = result.get('academic_year_comparison') or next((row for row in result['facts'] if row.get('fact_type') == 'academic_year_comparison'), None) if comparison is not None: context['academic_year_comparison'] = comparison if work_listing: context['required_academic_records'] = academic_records return context