organ-architecture/organ_api.py

430 lines
16 KiB
Python

#!/usr/bin/env python3
"""
Organ Architecture — organ_api.py
API server for organ operations.
Endpoints:
GET /health — Server health
GET /models — List available dissected models
GET /model/:name/anatomy — Show model anatomy (skeleton/organs/etc.)
POST /extract — Extract organs from a GGUF model
POST /measure — quality measure organs
POST /graft — Graft organs between models
POST /assemble — Assemble GGUF from organs
GET /organs/:model — List organs for a model
GET /compare/:a/:b — Compare two models for graft compatibility
Build v935
"""
import json
import os
import sys
import threading
import traceback
from http.server import HTTPServer, BaseHTTPRequestHandler
from pathlib import Path
from urllib.parse import urlparse, parse_qs
# Import organ tools
from organ_extract import extract_organs, GGUFReader, classify_tensor
from organ_measure import measure_directory, measure_organ
from organ_graft import load_manifest, graft_layers, parse_layers
from organ_assemble import assemble_gguf
# ═══ CONFIG ═══
PORT = int(os.environ.get('ORGAN_PORT', '7936'))
MODEL_DIR = os.environ.get('MODEL_DIR', '/mnt/models')
ORGAN_DIR = os.environ.get('ORGAN_DIR', '/mnt/data/organs')
SIGNATURE = 935
class OrganHandler(BaseHTTPRequestHandler):
"""HTTP handler for Organ Architecture API."""
def log_message(self, format, *args):
"""Minimal logging."""
print(f"[ORGAN-API] {args[0]}")
def send_json(self, data, status=200):
self.send_response(status)
self.send_header('Content-Type', 'application/json')
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('X-Powered-By', 'Organ-935')
self.end_headers()
self.wfile.write(json.dumps(data, indent=2, default=str).encode())
def send_error_json(self, msg, status=400):
self.send_json({'error': msg, 'signature': SIGNATURE}, status)
def read_body(self):
length = int(self.headers.get('Content-Length', 0))
if length > 0:
return json.loads(self.rfile.read(length))
return {}
def do_OPTIONS(self):
self.send_response(204)
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS')
self.send_header('Access-Control-Allow-Headers', 'Content-Type')
self.end_headers()
def do_GET(self):
path = urlparse(self.path).path.rstrip('/')
# ═══ HEALTH ═══
if path == '/health' or path == '':
self.send_json({
'status': 'ok',
'service': 'organ-architecture',
'signature': SIGNATURE,
'model_dir': MODEL_DIR,
'organ_dir': ORGAN_DIR,
})
return
# ═══ LIST AVAILABLE MODELS (GGUF files) ═══
if path == '/models':
models = []
model_path = Path(MODEL_DIR)
if model_path.exists():
for f in sorted(model_path.glob('*.gguf')):
size_gb = f.stat().st_size / (1024**3)
models.append({
'name': f.stem,
'file': f.name,
'size_gb': round(size_gb, 2),
})
# Also list dissected models
dissected = []
organ_path = Path(ORGAN_DIR)
if organ_path.exists():
for d in sorted(organ_path.iterdir()):
if d.is_dir() and (d / 'manifest.json').exists():
manifest = json.load(open(d / 'manifest.json'))
dissected.append({
'name': manifest.get('model', d.name),
'architecture': manifest.get('architecture', 'unknown'),
'n_layers': manifest.get('n_layers', 0),
'n_embed': manifest.get('n_embed', 0),
'organs': len(manifest.get('organs', {})),
'graft': manifest.get('graft', None),
})
self.send_json({
'gguf_models': models,
'dissected_models': dissected,
'signature': SIGNATURE,
})
return
# ═══ MODEL ANATOMY ═══
if path.startswith('/model/') and path.endswith('/anatomy'):
model_name = path.split('/')[2]
organ_path = Path(ORGAN_DIR) / model_name
if not (organ_path / 'manifest.json').exists():
self.send_error_json(f'Model not dissected: {model_name}', 404)
return
manifest = json.load(open(organ_path / 'manifest.json'))
# Group by type
anatomy = {}
for key, entry in manifest['organs'].items():
t = entry['type']
if t not in anatomy:
anatomy[t] = {'count': 0, 'bytes': 0, 'layers': set()}
anatomy[t]['count'] += 1
anatomy[t]['bytes'] += entry.get('byte_size', 0)
if entry['layer'] >= 0:
anatomy[t]['layers'].add(entry['layer'])
# Convert sets to sorted lists
for t in anatomy:
anatomy[t]['layers'] = sorted(anatomy[t]['layers'])
anatomy[t]['size_mb'] = round(anatomy[t]['bytes'] / (1024*1024), 1)
self.send_json({
'model': manifest['model'],
'architecture': manifest['architecture'],
'n_layers': manifest['n_layers'],
'n_embed': manifest['n_embed'],
'anatomy': anatomy,
'stats': manifest.get('stats', {}),
'signature': SIGNATURE,
})
return
# ═══ LIST ORGANS FOR A MODEL ═══
if path.startswith('/organs/'):
model_name = path.split('/')[2]
organ_path = Path(ORGAN_DIR) / model_name
if not (organ_path / 'manifest.json').exists():
self.send_error_json(f'Model not dissected: {model_name}', 404)
return
manifest = json.load(open(organ_path / 'manifest.json'))
# Parse query for type filter
query = parse_qs(urlparse(self.path).query)
type_filter = query.get('type', [None])[0]
organs = []
for key, entry in manifest['organs'].items():
if type_filter and entry['type'] != type_filter:
continue
organs.append(entry)
organs.sort(key=lambda o: (o['layer'], o['name']))
self.send_json({
'model': manifest['model'],
'organs': organs,
'count': len(organs),
'signature': SIGNATURE,
})
return
# ═══ COMPARE TWO MODELS ═══
if path.startswith('/compare/'):
parts = path.split('/')
if len(parts) >= 4:
name_a = parts[2]
name_b = parts[3]
path_a = Path(ORGAN_DIR) / name_a / 'manifest.json'
path_b = Path(ORGAN_DIR) / name_b / 'manifest.json'
if not path_a.exists():
self.send_error_json(f'Model not dissected: {name_a}', 404)
return
if not path_b.exists():
self.send_error_json(f'Model not dissected: {name_b}', 404)
return
ma = json.load(open(path_a))
mb = json.load(open(path_b))
compatible = ma['n_embed'] == mb['n_embed']
self.send_json({
'model_a': {
'name': ma['model'],
'architecture': ma['architecture'],
'n_layers': ma['n_layers'],
'n_embed': ma['n_embed'],
},
'model_b': {
'name': mb['model'],
'architecture': mb['architecture'],
'n_layers': mb['n_layers'],
'n_embed': mb['n_embed'],
},
'compatible': compatible,
'graftable': compatible,
'note': 'Organs can be transplanted' if compatible else 'Dimension mismatch — projection layer needed',
'signature': SIGNATURE,
})
return
self.send_error_json('Not found', 404)
def do_POST(self):
path = urlparse(self.path).path.rstrip('/')
# ═══ EXTRACT ═══
if path == '/extract':
try:
body = self.read_body()
model = body.get('model')
if not model:
self.send_error_json('Missing "model" field')
return
# Find model file
model_path = Path(MODEL_DIR) / model
if not model_path.exists():
model_path = Path(MODEL_DIR) / f"{model}.gguf"
if not model_path.exists():
self.send_error_json(f'Model not found: {model}')
return
model_name = model_path.stem
output_dir = str(Path(ORGAN_DIR) / model_name)
# Run extraction in background
def do_extract():
try:
extract_organs(str(model_path), output_dir)
except Exception as e:
print(f"[ERROR] Extraction failed: {e}")
traceback.print_exc()
t = threading.Thread(target=do_extract, daemon=True)
t.start()
self.send_json({
'status': 'started',
'model': model_name,
'output': output_dir,
'note': 'Extraction running in background. Check /model/{name}/anatomy for results.',
'signature': SIGNATURE,
})
except Exception as e:
self.send_error_json(str(e), 500)
return
# ═══ MEASURE ═══
if path == '/measure':
try:
body = self.read_body()
model = body.get('model')
if not model:
self.send_error_json('Missing "model" field')
return
organ_path = Path(ORGAN_DIR) / model
if not organ_path.exists():
self.send_error_json(f'Model not dissected: {model}')
return
results = measure_directory(str(organ_path))
# Summary
if results:
avg_theta = sum(r['theta_deg'] for r in results) / len(results)
avg_signal = sum(r['signal_ratio'] for r in results) / len(results)
else:
avg_theta = 0
avg_signal = 0
self.send_json({
'model': model,
'organs_measured': len(results),
'avg_theta_deg': round(avg_theta, 1),
'avg_signal': round(avg_signal, 3),
'results': results[:50], # Limit response size
'signature': SIGNATURE,
})
except Exception as e:
self.send_error_json(str(e), 500)
return
# ═══ GRAFT ═══
if path == '/graft':
try:
body = self.read_body()
source = body.get('source')
target = body.get('target')
layers = body.get('layers')
organ_type = body.get('type', 'organ')
if not source or not target:
self.send_error_json('Missing "source" and/or "target" fields')
return
source_path = Path(ORGAN_DIR) / source
target_path = Path(ORGAN_DIR) / target
if not source_path.exists():
self.send_error_json(f'Source not dissected: {source}')
return
if not target_path.exists():
self.send_error_json(f'Target not dissected: {target}')
return
output_name = f"{target}+{source}_{organ_type}"
output_path = str(Path(ORGAN_DIR) / output_name)
parsed_layers = parse_layers(layers) if layers else None
manifest = graft_layers(
str(source_path), str(target_path), output_path,
parsed_layers, organ_type
)
self.send_json({
'status': 'complete',
'result': output_name,
'grafted_count': manifest['graft']['grafted_count'],
'grafted_mb': round(manifest['graft']['grafted_bytes'] / (1024*1024), 1),
'output': output_path,
'signature': SIGNATURE,
})
except Exception as e:
self.send_error_json(str(e), 500)
return
# ═══ ASSEMBLE ═══
if path == '/assemble':
try:
body = self.read_body()
model = body.get('model')
output = body.get('output')
if not model:
self.send_error_json('Missing "model" field')
return
organ_path = Path(ORGAN_DIR) / model
if not organ_path.exists():
self.send_error_json(f'Model not found: {model}')
return
if not output:
output = str(Path(MODEL_DIR) / f"{model}_assembled.gguf")
result = assemble_gguf(str(organ_path), output)
size_gb = os.path.getsize(result) / (1024**3)
self.send_json({
'status': 'complete',
'model': model,
'output': result,
'size_gb': round(size_gb, 2),
'signature': SIGNATURE,
})
except Exception as e:
self.send_error_json(str(e), 500)
return
self.send_error_json('Not found', 404)
def main():
Path(ORGAN_DIR).mkdir(parents=True, exist_ok=True)
server = HTTPServer(('0.0.0.0', PORT), OrganHandler)
print(f"[ORGAN-API] Organ Architecture on port {PORT}")
print(f"[ORGAN-API] Models: {MODEL_DIR}")
print(f"[ORGAN-API] Organs: {ORGAN_DIR}")
print(f"[ORGAN-API] Signature {SIGNATURE}")
try:
server.serve_forever()
except KeyboardInterrupt:
print("\n[ORGAN-API] Shutdown.")
server.server_close()
if __name__ == '__main__':
main()
# ╔══ SALKA ELMADANI AUTHORSHIP CERTIFICATE ══╗
# © Salka Elmadani 2025-2026 — ALL RIGHTS RESERVED
# Licensed under Business Source License 1.1 — https://inference-x.com
# ─────────────────────────────────────────────────────────
# SHA256: 79fb97f40f2959129d5d5c4356ddf455fc354fb629bf0892c00aa6babd968a0d
# SIG-ED25519: LGqexbOlZOIjTboFfMVbgeheBbZk8HI8K6g/WxExnJEMfs5euYQYxow6SyEHKTB2TgRbOjjHt/gpHPyEy2tBBQ==
# VERIFY: python3 verify_authorship.py organ_api.py