#!/usr/bin/env python3 """One-shot feasibility probe: render one product's catalog shard as Go literals. Answers whether the shortcut storage model (compiled-in struct literals, zero runtime parse) is viable for the 845-tool Schema catalog, by measuring compile time, binary size and access cost on a single product first. Deliberately drops field_provenance: it is 50% of the bytes and no runtime consumer reads it, so a codegen design would keep it in JSON for audit only. Keeping it here would make the size numbers pessimistic and the design wrong. """ import json import sys def q(s: str) -> str: return json.dumps(s if s is not None else "", ensure_ascii=False) def strs(v) -> str: if not v: return "nil" return "[]string{" + ", ".join(q(x) for x in v) + "}" def render_param(name, p) -> str: fields = [ f"Name: {q(p.get('name') or name)}", f"Type: {q(p.get('type'))}", f"Description: {q(p.get('description'))}", f"Property: {q(p.get('property'))}", f"Required: {str(bool(p.get('required'))).lower()}", f"CLIRequired: {str(bool(p.get('cli_required'))).lower()}", f"RequiredWhen: {q(p.get('required_when'))}", f"Format: {q(p.get('format'))}", f"Enum: {strs(p.get('enum'))}", ] return "{" + ", ".join(fields) + "}" def render_tool(canonical, t) -> str: params = t.get("parameters") or {} lines = [ f"\t{q(canonical)}: {{", f"\t\tName: {q(t.get('name'))},", f"\t\tCanonicalPath: {q(t.get('canonical_path'))},", f"\t\tCLIPath: {q(t.get('cli_path'))},", f"\t\tPrimaryCLIPath: {q(t.get('primary_cli_path'))},", f"\t\tProductID: {q(t.get('product_id'))},", f"\t\tGroup: {q(t.get('group'))},", f"\t\tTitle: {q(t.get('title'))},", f"\t\tDescription: {q(t.get('description'))},", f"\t\tAliases: {strs(t.get('aliases'))},", f"\t\tIsAlias: {str(bool(t.get('is_alias'))).lower()},", f"\t\tEffect: {q(t.get('effect'))},", f"\t\tRisk: {q(t.get('risk'))},", f"\t\tConfirmation: {q(t.get('confirmation'))},", f"\t\tIdempotency: {q(t.get('idempotency'))},", f"\t\tInterfaceMode: {q(t.get('interface_mode'))},", f"\t\tAvailability: {q(t.get('availability'))},", f"\t\tAgentSummary: {q(t.get('agent_summary'))},", f"\t\tUseWhen: {strs(t.get('use_when'))},", f"\t\tAvoidWhen: {strs(t.get('avoid_when'))},", f"\t\tExamples: {strs(t.get('examples'))},", f"\t\tHasParameters: {str(bool(t.get('has_parameters'))).lower()},", f"\t\tParameterCount: {int(t.get('parameter_count') or 0)},", ] if params: lines.append("\t\tParameters: map[string]Param{") for pname in sorted(params): lines.append(f"\t\t\t{q(pname)}: {render_param(pname, params[pname])},") lines.append("\t\t},") lines.append("\t},") return "\n".join(lines) def main() -> int: src, product, out = sys.argv[1], sys.argv[2], sys.argv[3] tools = json.load(open(src, encoding="utf-8"))["tools"] body = "\n".join(render_tool(c, tools[c]) for c in sorted(tools)) with open(out, "w", encoding="utf-8") as f: f.write(f"""// Copyright 2026 Alibaba Group // Code generated by scripts/dev/catalog_codegen_probe.py; DO NOT EDIT. // // Feasibility probe for storing the Schema catalog as compiled-in Go literals // instead of embedded JSON, mirroring how internal/shortcut stores its 376 // definitions. field_provenance is omitted: no runtime consumer reads it. package catalogcodegen // Tools holds the {product} product's leaf ToolSpecs as static data, so there is // no decode step on the first lookup. var Tools = map[string]Tool{{ {body} }} """) print(f"generated {out}: {len(tools)} tools") return 0 if __name__ == "__main__": raise SystemExit(main())