Complete snapshot of /opt/microdao-daarion/ from NODE1 (144.76.224.179).
This represents the actual running production code that has diverged
significantly from the previous main branch.
Key changes from old main:
- Gateway (http_api.py): expanded from ~40KB to 164KB with full agent support
- Router: new /v1/agents/{id}/infer endpoint with vision + DeepSeek routing
- Behavior Policy: SOWA v2.2 (3-level: FULL/ACK/SILENT)
- Agent Registry: config/agent_registry.yml as single source of truth
- 13 agents configured (was 3)
- Memory service integration
- CrewAI teams and roles
Excluded from snapshot: venv/, .env, data/, backups, .tgz archives
Co-authored-by: Cursor <cursoragent@cursor.com>
246 lines
8.3 KiB
Python
246 lines
8.3 KiB
Python
import json
|
|
import os
|
|
import hashlib
|
|
from pathlib import Path
|
|
from datetime import datetime
|
|
|
|
import yaml
|
|
|
|
PENDING_PATH = Path(os.getenv('AGX_PENDING_PATH', '/opt/microdao-daarion/data/dictionaries/pending.jsonl'))
|
|
RESOLVED_PATH = Path(os.getenv('AGX_PENDING_RESOLVED_PATH', '/opt/microdao-daarion/data/dictionaries/pending_resolved.jsonl'))
|
|
DICT_PATH = Path(os.getenv('AGX_DICTIONARY_PATH', '/opt/microdao-daarion/data/dictionaries/dictionaries.yaml'))
|
|
LOCK_PATH = Path(os.getenv('AGX_DICTIONARY_LOCK', '/opt/microdao-daarion/data/dictionaries/locks/dictionaries.lock'))
|
|
|
|
REDACT_KEYS = set(k.strip().lower() for k in os.getenv('AGX_AUDIT_REDACT_KEYS', 'token,secret,password,authorization,cookie,api_key,signature').split(','))
|
|
|
|
|
|
def _now():
|
|
return datetime.utcnow().isoformat() + 'Z'
|
|
|
|
|
|
def _sanitize(obj):
|
|
if isinstance(obj, dict):
|
|
return {k: ('***REDACTED***' if k.lower() in REDACT_KEYS else _sanitize(v)) for k, v in obj.items()}
|
|
if isinstance(obj, list):
|
|
return [_sanitize(v) for v in obj]
|
|
return obj
|
|
|
|
|
|
def _load_pending():
|
|
if not PENDING_PATH.exists():
|
|
return []
|
|
items = []
|
|
for i, line in enumerate(RESOLVED_PATH.read_text(encoding='utf-8').split('\n'), start=1):
|
|
if not line.strip():
|
|
continue
|
|
obj = json.loads(line)
|
|
raw = line.strip()
|
|
pending_id = 'sha256:' + hashlib.sha256(raw.encode()).hexdigest()
|
|
items.append({
|
|
'pending_ref': f"pending.jsonl:{i}",
|
|
'pending_id': pending_id,
|
|
**obj
|
|
})
|
|
return items
|
|
|
|
|
|
def _load_resolved():
|
|
if not RESOLVED_PATH.exists():
|
|
return []
|
|
items = []
|
|
for i, line in enumerate(RESOLVED_PATH.read_text(encoding='utf-8').split('\n'), start=1):
|
|
if not line.strip():
|
|
continue
|
|
items.append(json.loads(line))
|
|
return items
|
|
|
|
|
|
def get_pending_detail(pending_ref_or_id: str):
|
|
pending = _load_pending()
|
|
resolved = _load_resolved()
|
|
target = next((p for p in pending if p.get('pending_ref') == pending_ref_or_id or p.get('pending_id') == pending_ref_or_id), None)
|
|
if not target:
|
|
return None
|
|
|
|
resolved_match = next((r for r in resolved if r.get('pending_id') == target.get('pending_id') or r.get('pending_ref') == target.get('pending_ref')), None)
|
|
status = 'open'
|
|
decision = ''
|
|
reason = ''
|
|
if resolved_match:
|
|
status = resolved_match.get('decision') or 'resolved'
|
|
decision = resolved_match.get('decision') or ''
|
|
reason = resolved_match.get('reason') or ''
|
|
|
|
suggestions = []
|
|
for s in (target.get('suggestions') or [])[:5]:
|
|
suggestions.append({
|
|
'id': s.get('id'),
|
|
'score': s.get('score')
|
|
})
|
|
|
|
return {
|
|
'ref': target.get('pending_ref'),
|
|
'category': target.get('category'),
|
|
'raw_term': target.get('raw_term'),
|
|
'ts': target.get('ts'),
|
|
'suggestions': suggestions,
|
|
'status': status,
|
|
'decision': decision,
|
|
'reason': reason
|
|
}
|
|
|
|
|
|
def list_pending(limit=50, category=None, status='open'):
|
|
pending = _load_pending()
|
|
resolved = _load_resolved()
|
|
resolved_ids = set(r.get('pending_id') for r in resolved)
|
|
if status == 'open':
|
|
pending = [p for p in pending if p['pending_id'] not in resolved_ids]
|
|
if category:
|
|
pending = [p for p in pending if p.get('category') == category]
|
|
return pending[:limit]
|
|
|
|
|
|
def _append_resolved(record: dict):
|
|
RESOLVED_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
with RESOLVED_PATH.open('a', encoding='utf-8') as f:
|
|
f.write(json.dumps(_sanitize(record), ensure_ascii=False) + "\n")
|
|
|
|
def approve_pending(pending_ref_or_id: str, action: dict, trace_id=None, reviewer='local'):
|
|
pending = _load_pending()
|
|
target = next((p for p in pending if p['pending_ref'] == pending_ref_or_id or p['pending_id'] == pending_ref_or_id), None)
|
|
if not target:
|
|
raise ValueError('pending_not_found')
|
|
|
|
record = {
|
|
'ts': _now(),
|
|
'pending_ref': target['pending_ref'],
|
|
'pending_id': target['pending_id'],
|
|
'decision': 'approved',
|
|
'category': target.get('category'),
|
|
'raw_term': target.get('raw_term'),
|
|
'action': action,
|
|
'reviewer': reviewer,
|
|
'reason': action.get('reason', '') or '',
|
|
'trace_id': trace_id or ''
|
|
}
|
|
_append_resolved(record)
|
|
return record
|
|
|
|
|
|
def reject_pending(pending_ref_or_id: str, reason: str, trace_id=None, reviewer='local'):
|
|
pending = _load_pending()
|
|
target = next((p for p in pending if p['pending_ref'] == pending_ref_or_id or p['pending_id'] == pending_ref_or_id), None)
|
|
if not target:
|
|
raise ValueError('pending_not_found')
|
|
|
|
record = {
|
|
'ts': _now(),
|
|
'pending_ref': target['pending_ref'],
|
|
'pending_id': target['pending_id'],
|
|
'decision': 'rejected',
|
|
'category': target.get('category'),
|
|
'raw_term': target.get('raw_term'),
|
|
'action': {'type': 'reject'},
|
|
'reviewer': reviewer,
|
|
'reason': reason,
|
|
'trace_id': trace_id or ''
|
|
}
|
|
_append_resolved(record)
|
|
return record
|
|
|
|
|
|
def _load_dict():
|
|
return yaml.safe_load(DICT_PATH.read_text(encoding='utf-8'))
|
|
|
|
|
|
def _write_dict(data):
|
|
LOCK_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
if LOCK_PATH.exists():
|
|
raise RuntimeError('lock_exists')
|
|
try:
|
|
LOCK_PATH.write_text('locked')
|
|
DICT_PATH.write_text(yaml.safe_dump(data, allow_unicode=True, sort_keys=False), encoding='utf-8')
|
|
finally:
|
|
try:
|
|
LOCK_PATH.unlink()
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def _add_synonym(data, category, canonical_id, raw_term):
|
|
items = data.get(category + 's', data.get(category, []))
|
|
# category names in dict are plural
|
|
if category in ['field','crop','operation','material','unit']:
|
|
items = data.get(category + 's', [])
|
|
for item in items:
|
|
if item.get('id') == canonical_id:
|
|
item.setdefault('synonyms', [])
|
|
if raw_term not in item['synonyms']:
|
|
item['synonyms'].append(raw_term)
|
|
return True
|
|
return False
|
|
|
|
|
|
def _create_entry(data, category, name, new_id, raw_term):
|
|
key = category + 's'
|
|
data.setdefault(key, [])
|
|
entry = {'id': new_id, 'name': name, 'synonyms': [raw_term]}
|
|
data[key].append(entry)
|
|
return entry
|
|
|
|
|
|
def apply_resolutions():
|
|
resolved = _load_resolved()
|
|
data = _load_dict()
|
|
applied = 0
|
|
for r in resolved:
|
|
if r.get('decision') != 'approved':
|
|
continue
|
|
action = r.get('action', {})
|
|
raw_term = r.get('raw_term')
|
|
category = r.get('category')
|
|
if action.get('type') in ['map_to_existing','add_synonym']:
|
|
if _add_synonym(data, category, action.get('canonical_id'), raw_term):
|
|
applied += 1
|
|
elif action.get('type') == 'create_new_entry':
|
|
_create_entry(data, category, action.get('canonical_name'), action.get('canonical_id'), raw_term)
|
|
applied += 1
|
|
_write_dict(data)
|
|
return applied
|
|
|
|
|
|
def stats():
|
|
pending = _load_pending()
|
|
resolved = _load_resolved()
|
|
resolved_ids = set(r.get('pending_id') for r in resolved)
|
|
open_items = [p for p in pending if p['pending_id'] not in resolved_ids]
|
|
return {
|
|
'open': len(open_items),
|
|
'approved': len([r for r in resolved if r.get('decision') == 'approved']),
|
|
'rejected': len([r for r in resolved if r.get('decision') == 'rejected'])
|
|
}
|
|
|
|
|
|
def auto_approve(min_score=0.97, category=None, dry_run=True, reviewer='local'):
|
|
# use suggestions from pending record; approve if top score >= min_score
|
|
items = list_pending(limit=1000, category=category, status='open')
|
|
results = []
|
|
for p in items:
|
|
suggestions = p.get('suggestions') or []
|
|
if not suggestions:
|
|
continue
|
|
top = suggestions[0]
|
|
if top.get('score', 0) >= min_score:
|
|
action = {
|
|
'type': 'map_to_existing',
|
|
'canonical_id': top.get('id'),
|
|
'canonical_name': top.get('name')
|
|
}
|
|
if dry_run:
|
|
results.append({'pending_ref': p['pending_ref'], 'action': action, 'dry_run': True})
|
|
else:
|
|
approve_pending(p['pending_ref'], action, reviewer=reviewer)
|
|
results.append({'pending_ref': p['pending_ref'], 'action': action, 'dry_run': False})
|
|
return results
|