#!/usr/bin/env python3 import argparse import json from pathlib import Path ROOT = Path(__file__).resolve().parents[1] ROSTER_PATH = ROOT / 'references' / 'roster.json' def load_roster(): return json.loads(ROSTER_PATH.read_text(encoding='utf-8')) def resolve_plan(mode: str, tier: str): roster = load_roster() if mode not in roster: raise SystemExit(f'Unknown mode: {mode}') if tier not in roster['tierPolicy']: raise SystemExit(f'Unknown tier: {tier}') roles = roster[mode]['roles'] tier_policy = roster['tierPolicy'][tier] plan = { 'mode': mode, 'tier': tier, 'roles': {}, 'notes': tier_policy.get('notes', '') } for role, cfg in roles.items(): mission = cfg.get('mission', 'advisor') is_synthesis = mission == 'synthesis' override = tier_policy.get('synthesisModel') if is_synthesis else tier_policy.get('advisorModel') thinking = tier_policy.get('synthesisThinking') if is_synthesis else tier_policy.get('advisorThinking') plan['roles'][role] = { 'agentId': cfg['agentId'], 'mission': mission, 'defaultModel': cfg.get('defaultModel'), 'modelOverride': override, 'thinkingOverride': thinking, 'fallbacks': cfg.get('fallbacks', []) } return plan if __name__ == '__main__': p = argparse.ArgumentParser(description='Resolve council role/agent/model plan') p.add_argument('--mode', default='personality', choices=['personality', 'dp']) p.add_argument('--tier', default='light', choices=['light', 'medium', 'heavy']) p.add_argument('--pretty', action='store_true') args = p.parse_args() plan = resolve_plan(args.mode, args.tier) print(json.dumps(plan, indent=2 if args.pretty else None))