#!/usr/bin/env python3 # args_json: {"type":"object","properties":{"role":{"type":"string","description":"Who this agent is and what it does"},"name":{"type":"string","description":"Config name (default: jit-)"},"roster":{"type":"string","description":"Name/task mapping of peers"},"shared_task":{"type":"string","description":"Tracking entry or issue ID"},"protocol":{"type":"string","description":"Coordination mechanics"},"constraints":{"type":"array","items":{"type":"string"},"description":"Array of constraint strings"},"prompt":{"type":"string","description":"Legacy: complete identity as single string"}}} # ollie:prompt # ## subagent_generate # # Generate a JIT subagent config. No args prints the JSON template. # With JSON input, creates the config and prints the agent name. # # ``` # subagent_generate(role="backend dev") # subagent_generate() # ``` # ollie:end import json import os import secrets import sys sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from _lib.args import parse_args AGENTS_DIR = os.path.expanduser("~/.config/ollie/agents") BASE_CONFIG = os.path.join(AGENTS_DIR, "default.json") TEMPLATE = { "name": "", "role": "", "roster": "", "shared_task": "", "protocol": "", "constraints": [], "prompt": "", } def die(msg): print(f"error: {msg}", file=sys.stderr) sys.exit(1) def main(): args = parse_args() data = args.raw() # No meaningful input: print template. if not any(v for v in data.values() if v): json.dump(TEMPLATE, sys.stdout, indent=2) print() return name = args.get("name") or f"jit-{secrets.token_hex(8)}" role = args.get("role", "") roster = args.get("roster", "") shared_task = args.get("shared_task", "") protocol = args.get("protocol", "") constraints = args.get_list("constraints") legacy = args.get("prompt", "") if not role and not legacy: die("role or prompt required") # Build identity text. if role: parts = ["## Role", role] if roster: parts += ["## Roster", roster] if shared_task: parts += ["## Shared Task", shared_task] if protocol: parts += ["## Coordination Protocol", protocol] if constraints: parts += ["## Constraints", "\n".join(f"- {c}" for c in constraints)] identity = "\n\n".join(parts) else: identity = legacy # Load base config. try: with open(BASE_CONFIG) as f: cfg = json.load(f) except (OSError, json.JSONDecodeError) as e: die(f"failed to read base config: {e}") cfg["prompt"] = [f"echo {json.dumps(identity)}"] # Write JIT config. out_path = os.path.join(AGENTS_DIR, f"{name}.json") try: with open(out_path, "w") as f: json.dump(cfg, f, indent=2) except OSError as e: die(f"failed to write config: {e}") print(name) if __name__ == "__main__": main()