#!/usr/bin/env python3 # 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. # # **Args**: `[]` (prints template) or `[json_config]` # # ``` # call_tool: calls=[{tool: "subagent_generate", args: []}] # call_tool: calls=[{tool: "subagent_generate", args: ["{...}"]}] # ``` # ollie:end import json import os import secrets import sys 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"subagent_generate: {msg}", file=sys.stderr) sys.exit(1) def main(): # No input: print template. if len(sys.argv) < 2 and sys.stdin.isatty(): json.dump(TEMPLATE, sys.stdout, indent=2) print() return # Read config from arg or stdin. if len(sys.argv) > 1: text = sys.argv[1] else: text = sys.stdin.read() if not text.strip(): die("empty input") try: raw = json.loads(text) except json.JSONDecodeError as e: die(f"invalid JSON: {e}") name = raw.get("name", "") or f"jit-{secrets.token_hex(8)}" role = raw.get("role", "") roster = raw.get("roster", "") shared_task = raw.get("shared_task", "") protocol = raw.get("protocol", "") constraints = raw.get("constraints", []) if not isinstance(constraints, list): die("constraints must be an array of strings") legacy = raw.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"] = ["cat ~/.config/ollie/prompts/SYSTEM_PROMPT.md", 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()