Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0cffe-206f-7323-89d3-b20ca4cf4bf9
82 lines
4.6 KiB
Python
82 lines
4.6 KiB
Python
"""Conditional execution and explicit reuse of structurally screened stage results."""
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
|
|
from infospace_bench.workflow import AssistedGenerationResult, FixtureAssistedGenerationAdapter
|
|
from research_admission import json_block, screen
|
|
|
|
|
|
def fingerprint(value):
|
|
return hashlib.sha256(json.dumps(value, sort_keys=True).encode()).hexdigest()
|
|
|
|
|
|
def identity(adapter):
|
|
if isinstance(adapter, FixtureAssistedGenerationAdapter):
|
|
return {'fixture': sorted((list(k), v.markdown, v.provider, v.metadata)
|
|
for k, v in adapter.responses.items())}
|
|
if hasattr(adapter, 'config') and hasattr(adapter, 'endpoint'):
|
|
return {'class': type(adapter).__name__, 'endpoint': adapter.endpoint,
|
|
'config': adapter.config.to_dict(), 'diagnostics': adapter.diagnostics}
|
|
raise ValueError('Optimized execution requires llm-connect or a fixture adapter')
|
|
|
|
|
|
class ResearchExecution:
|
|
def __init__(self, limited, context, reuse_from=None):
|
|
self.limited = limited
|
|
self.context = {**context, 'adapter': identity(limited.adapter)}
|
|
self.candidates = None
|
|
self.relations = '```json\n[]\n```'
|
|
self.events, self.cache, self.previous = [], {}, {}
|
|
self.reuse_from = str(Path(reuse_from).resolve()) if reuse_from else None
|
|
if reuse_from:
|
|
root = Path(reuse_from)
|
|
receipt = json.loads((root / 'reports/research-run.json').read_text())
|
|
raw = (root / 'reports/stage-cache.json').read_bytes()
|
|
if (receipt['status'] != 'completed' or
|
|
hashlib.sha256(raw).hexdigest() != receipt.get('stage_cache_sha256')):
|
|
raise ValueError('Reuse requires a completed run and matching cache digest')
|
|
self.previous = json.loads(raw)
|
|
|
|
def generate(self, request):
|
|
stage = request.stage_id
|
|
if stage == 'relations' and len(json_block(self.candidates)['candidates']) < 2:
|
|
self.events.append({'stage': stage, 'execution': 'deterministic',
|
|
'reason': 'fewer than two candidates'})
|
|
return AssistedGenerationResult(self.relations, provider='deterministic',
|
|
metadata={'reason': 'fewer than two candidates'})
|
|
if stage == 'critique':
|
|
report = screen(self.candidates, self.relations)
|
|
self.events.append({'stage': stage, 'execution': 'deterministic', 'screen': report})
|
|
return AssistedGenerationResult(
|
|
'# Editorial review required\n\nThis is a structural screen, not model critique.\n\n'
|
|
+ '```json\n' + json.dumps(report, indent=2) + '\n```\n\n'
|
|
+ 'Check source fidelity, known-use independence, unsupported guarantees, '
|
|
'counterexamples and scenario relevance. Record corrections in the editorial review.\n',
|
|
provider='deterministic', metadata={'admission': 'not_granted'})
|
|
key = fingerprint({'context': self.context, 'stage': stage, 'prompt': request.prompt,
|
|
'workflow': request.workflow_id, 'input': request.input_artifact_id})
|
|
cached = self.previous.get(key)
|
|
event = {'stage': stage, 'execution': 'cache' if cached else 'provider'}
|
|
self.events.append(event)
|
|
if cached:
|
|
result = AssistedGenerationResult(cached['markdown'], cached['provider'],
|
|
{**cached['metadata'], 'reused_from': self.reuse_from, 'current_provider_call': False})
|
|
else:
|
|
result = self.limited.generate(request)
|
|
if stage in ('candidates', 'relations'):
|
|
report = screen(result.markdown if stage == 'candidates' else self.candidates,
|
|
'```json\n[]\n```' if stage == 'candidates' else result.markdown)
|
|
event['screen'] = report
|
|
if report['structural_status'] != 'passed':
|
|
event['rejected_assertions'] = len(report['findings'])
|
|
# Keep rejected research output for review, but do not propagate/cache it.
|
|
self.rejected = {'stage': stage, 'content': result.markdown, 'screen': report}
|
|
raise ValueError(f'{stage} structural screen blocked; inspect rejected-stage.json')
|
|
if stage == 'candidates':
|
|
self.candidates = result.markdown
|
|
if stage == 'relations':
|
|
self.relations = result.markdown
|
|
self.cache[key] = cached or {'markdown': result.markdown, 'provider': result.provider,
|
|
'metadata': result.metadata}
|
|
return result
|