88 lines
2.7 KiB
Python
88 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
import os, sys
|
|
|
|
def load_manifest(path):
|
|
# Minimal YAML parser for our simple manifests:
|
|
# keys: name (ignored), include: [..], modules: [..]
|
|
data = {"include": [], "modules": []}
|
|
key = None
|
|
with open(path, 'r', encoding='utf-8') as f:
|
|
for raw in f:
|
|
line = raw.rstrip('\n')
|
|
s = line.strip()
|
|
if not s or s.startswith('#'):
|
|
continue
|
|
if s.startswith('include:'):
|
|
key = 'include'
|
|
continue
|
|
if s.startswith('modules:'):
|
|
key = 'modules'
|
|
continue
|
|
if s.startswith('name:'):
|
|
key = None
|
|
continue
|
|
# list item under current key
|
|
if key in ('include', 'modules') and s.startswith('- '):
|
|
item = s[2:].strip()
|
|
data[key].append(item)
|
|
return data
|
|
|
|
def resolve(path, seen):
|
|
m = load_manifest(path)
|
|
includes = m.get('include', []) or []
|
|
modules = m.get('modules', []) or []
|
|
for inc in includes:
|
|
resolve(inc, seen)
|
|
for mod in modules:
|
|
if mod not in seen:
|
|
seen.append(mod)
|
|
return seen
|
|
|
|
def words(s: str) -> int:
|
|
return len(s.split())
|
|
|
|
def main():
|
|
if len(sys.argv) != 3:
|
|
print("Usage: prompt_build.py <manifest> <out>", file=sys.stderr)
|
|
sys.exit(2)
|
|
manifest, out_path = sys.argv[1], sys.argv[2]
|
|
mods = resolve(manifest, [])
|
|
if not mods:
|
|
print(f"No modules resolved from {manifest}", file=sys.stderr)
|
|
sys.exit(1)
|
|
if out_path != '-':
|
|
os.makedirs(os.path.dirname(out_path), exist_ok=True)
|
|
def read(p):
|
|
with open(p, 'r', encoding='utf-8') as f:
|
|
return f.read().strip() + "\n\n"
|
|
parts = ["Generated Prompt Pack\n\n"]
|
|
for m in mods:
|
|
parts.append(f"--- {m} ---\n")
|
|
parts.append(read(m))
|
|
content = "".join(parts)
|
|
# budgets
|
|
total_words = words(content)
|
|
BASE_BUDGET = 1200
|
|
if total_words > BASE_BUDGET:
|
|
print(f"ERROR: Pack exceeds budget: {total_words} > {BASE_BUDGET}", file=sys.stderr)
|
|
sys.exit(3)
|
|
ERRORS = 0
|
|
MOD_BUDGET = 400
|
|
for m in mods:
|
|
with open(m, 'r', encoding='utf-8') as f:
|
|
wc = words(f.read())
|
|
if wc > MOD_BUDGET:
|
|
print(f"ERROR: Module {m} exceeds budget: {wc} > {MOD_BUDGET}", file=sys.stderr)
|
|
ERRORS += 1
|
|
if ERRORS:
|
|
sys.exit(4)
|
|
if out_path == '-':
|
|
sys.stdout.write(content)
|
|
else:
|
|
with open(out_path, 'w', encoding='utf-8') as out:
|
|
out.write(content)
|
|
print(f"Built {out_path} with {total_words} words across {len(mods)} modules.", file=sys.stderr)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|