"""One-request stdlib SSH agent. No server, listening socket, or credentials.""" import base64, contextlib, datetime, hashlib, json, os, re, shlex, subprocess, sys, tempfile, urllib.request, uuid from pathlib import Path REPO = 'will-taggart/AFFECTOR-ARC' def atomic(path, obj): path = Path(path); path.parent.mkdir(parents=True, exist_ok=True) fd, name = tempfile.mkstemp(dir=path.parent) try: with os.fdopen(fd, 'w') as f: json.dump(obj, f, ensure_ascii=False, allow_nan=False); f.flush(); os.fsync(f.fileno()) os.replace(name, path) finally: if os.path.exists(name): os.unlink(name) def command(args, **kw): p = subprocess.run(args, capture_output=True, text=True, **kw) if p.returncode: raise RuntimeError((p.stderr or p.stdout or 'Command failed').strip()) return p.stdout.strip() def token(value, label): if not isinstance(value, str) or not re.fullmatch(r'[A-Za-z0-9_.,:+@/-]+', value) or value.startswith('-'): raise ValueError('Invalid '+label) return value def rootpath(value): if not isinstance(value, str) or not value.strip(): raise ValueError('Choose a remote workspace') p = Path(value).expanduser() if not p.is_absolute() or p == Path('/') or len(p.parts)<3: raise ValueError('Use an absolute path or ~/folder for the workspace') return p.resolve() def jobdir(root, identity): uuid.UUID(identity); p=root/'jobs'/identity if not p.is_dir(): raise ValueError('Job record not found') return p def fetch(url): with urllib.request.urlopen(urllib.request.Request(url,headers={'User-Agent':'AFFECTOR-ARC-Desktop/1.0'}), timeout=120) as r: return r.read() def current(root): p=root/'current' if not p.exists(): raise ValueError('Install/update AFFECTOR-ARC first') release=p.resolve() if release.parent != (root/'releases').resolve(): raise ValueError('Unexpected release path') return release def envpath(root,release): digest=hashlib.sha256((release/'setup.sh').read_bytes()).hexdigest()[:16] return root/'environments'/digest def scheduler(q, root, kind, payload=None): release=current(root); env=envpath(root,release) if kind!='setup' and not (env/'.affector-ready').exists(): raise ValueError('Run GPU setup successfully before submitting a transformation') identity=str(uuid.uuid4()); d=root/'jobs'/identity; d.mkdir(parents=True) account=token(q['account'],'allocation'); partition=token(q['partition'],'partition') wall=q.get('walltime','01:00:00') if not re.fullmatch(r'(?:\d+-)?\d{1,3}:\d{2}:\d{2}',wall): raise ValueError('Use HH:MM:SS or D-HH:MM:SS for wall time') cpus=int(q.get('cpus',8)); memory=int(q.get('memory',32)) if not 1<=cpus<=128 or not 1<=memory<=1024: raise ValueError('Invalid CPU or memory request') cache=rootpath(q.get('cache',str(root/'model-cache'))) lines=['#!/bin/bash','set -euo pipefail','umask 077','module load Miniconda3',f'export HF_HOME={shlex.quote(str(cache))}',f'cd {shlex.quote(str(release))}'] if kind=='setup': # Reuse a completed environment, but never treat a partial setup as ready. lines += [f'ENV={shlex.quote(str(env))}', 'mkdir -p "$(dirname "$ENV")"', 'exec 9>"$ENV.lock"', 'flock 9', 'if [ ! -f "$ENV/.affector-ready" ]; then', 'if [ ! -x "$ENV/bin/python" ]; then conda create -y --override-channels -c conda-forge -p "$ENV" python=3.12 pip; fi', '"$ENV/bin/python" -m pip install torch --index-url https://download.pytorch.org/whl/cu126', '"$ENV/bin/python" -m pip install "transformers==5.22.2" accelerate huggingface_hub safetensors', '"$ENV/bin/python" -m unittest discover -s tests', '"$ENV/bin/python" -m pip freeze > "$ENV/environment-resolved.txt"', '"$ENV/bin/python" -c \'import torch; assert torch.cuda.is_available(), "CUDA unavailable"; print(torch.__version__, torch.cuda.get_device_name(0))\'', 'touch "$ENV/.affector-ready"', 'fi', '"$ENV/bin/python" -m unittest discover -s tests', '"$ENV/bin/python" -c \'import torch; assert torch.cuda.is_available(), "CUDA unavailable"; print(torch.__version__, torch.cuda.get_device_name(0))\''] else: text=q.get('text','') if not isinstance(text,str) or not text.strip(): raise ValueError('Input text is empty') if len(text.encode())>20_000_000: raise ValueError('Input exceeds 20 MB') (d/'input.txt').write_text(text,encoding='utf-8') geometry=q.get('geometry') if not isinstance(geometry,dict): raise ValueError('Missing shape') # Validate without importing torch. The pinned source supplies the actual schema. import importlib.util spec=importlib.util.spec_from_file_location('arc_geometry',release/'engine/geometry.py'); m=importlib.util.module_from_spec(spec); spec.loader.exec_module(m) geometry=m.import_atlas(geometry,geometry.get('name','Imported shape')); m.validate(geometry) atomic(d/'shape.json',geometry) args=[str(env/'bin/python'),'-u','run_arc.py','--mode',kind,'--text-file',str(d/'input.txt'),'--geometry',str(d/'shape.json'),'--output',str(d/'report.json')] style=q.get('style','Restrained') if style not in ['Minimal','Restrained','Balanced','Creative']: raise ValueError('Invalid rewrite style') args += ['--style',style] if kind=='rewrite': for key,lo,hi in [('temperature',0,2),('top_p',0.00001,1),('top_k',0,100000),('max_tokens',32,2048),('time_limit',1,3600),('seed',0,2147483647)]: val=q.get(key,{'temperature':0,'top_p':.95,'top_k':40,'max_tokens':512,'time_limit':120,'seed':0}[key]) if type(val) not in (float,int) or not lo<=val<=hi: raise ValueError('Invalid '+key) if key in ['top_k','max_tokens','seed'] and int(val)!=val: raise ValueError(key+' must be an integer') args += ['--'+key.replace('_','-'),str(val)] lines += [shlex.join(args)] script='\n'.join(lines)+'\n'; (d/'job.sh').write_text(script) jid=command(['sbatch','--parsable','--account='+account,'--partition='+partition,'--nodes=1','--ntasks=1','--cpus-per-task='+str(cpus),'--gres=gpu:1','--mem='+str(memory)+'G','--time='+wall,'--job-name=affector-'+kind,'--output='+str(d/'job.log'),'--error='+str(d/'job.log'),str(d/'job.sh')]).split(';')[0] if not jid.isdigit(): raise RuntimeError('Unexpected Slurm job ID: '+jid) record={'id':identity,'job_id':jid,'kind':kind,'created_at':datetime.datetime.now(datetime.timezone.utc).isoformat(),'release':release.name,'directory':str(d),'account':account,'partition':partition} atomic(d/'job.json',record); return record def response_text(text): if not isinstance(text,str):return '' text=re.sub(r'[\s\S]*?\s*','',text,flags=re.I) if re.search(r'',text,re.I):return '' label=r'(?:transformed(?:\s+(?:text|passage|document))?|rewritten(?:\s+(?:text|passage|document))?|rewrite|revised(?:\s+(?:text|passage|document))?|final(?:\s+(?:answer|text))?|attempt|output)' pattern=r'(?im)^\s*(?:\#{1,6}\s*)?(?:here is (?:the |a )?)?(?:\*\*)?'+label+r'(?:\*\*)?\s*:\s*(?:\*\*)?[^\S\r\n]*' matches=list(re.finditer(pattern,text)) if matches: text=text[matches[-1].end():] suffix=re.search(r'(?im)^\s*(?:\#{1,6}\s*)?(?:\*\*)?(?:original(?:\s+(?:text|target|passage))?|source(?:\s+text)?|prompt|target|instructions?|explanation|notes?)(?:\*\*)?\s*:',text) if suffix:text=text[:suffix.start()] elif re.search(r'(?im)^\s*(?:\#{1,6}\s*)?(?:\*\*)?(?:original(?:\s+(?:text|target|passage))?|source\s+text|prompt|target)(?:\*\*)?\s*:',text):return '' text=text.strip() if text.startswith('```') and text.endswith('```'): lines=text.splitlines();text='\n'.join(lines[1:-1]).strip() if re.match(r"(?is)^(?:the prompt (?:asks|requests|requires|instructs)|this is (?:a |an )?prohibited attempt|i (?:cannot|can't|am unable to) (?:rewrite|comply with|fulfill this request))\b",text):return '' return text def transformed_text(report): records=report.get('records') if not isinstance(records,dict):return response_text(report.get('text','')) spans=report.get('spans',[]);source=report.get('input','');parts=[];previous=None for index in sorted(int(k) for k in records if str(k).isdigit()): record=records[str(index)];text=record.get('text','') if record.get('original_retained') or not isinstance(text,str) or not text.strip():continue if previous is not None: gap='\n\n' if index==previous+1 and index