Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 70 additions & 35 deletions demo/build_final.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#!/usr/bin/env python3
"""Build the final banner (ingest/banner.py) and demo GIF (demo/demo.gif).
"""Build the CLI banner (ingest/banner.py) and the README title-card GIF.

Layout: parrot (left) + ansi_shadow "Doppel"/"ganger" (right), amber wordmark,
tagline centered beneath. Renders the GIF with agg's dracula theme.
- ingest/banner.py: lean parrot + amber wordmark, printed at CLI startup.
- demo/demo.gif: a richer "title card" — tagline, parrot + gradient wordmark,
a keyword line, a version box, and a made-by line — rendered with agg.
"""
import json
import os
Expand All @@ -11,12 +12,19 @@
import pyfiglet

ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PY = os.path.join(ROOT, "venv", "bin", "python")
AGG = os.environ.get("AGG", "agg") # asciinema agg on PATH; override with $AGG
AGG = os.environ.get("AGG", "agg")
GAP = " "
TAG = "fine-tune an LLM to write like you"
CMD = "python -m ingest --source telegram --input demo/sample_export.json"
AMBER, RESET = "\x1b[1;38;2;242;176;76m", "\x1b[0m"

TAGLINE = "fine-tune an LLM on your chat history to write like you"
KEYWORDS = "ingest · scan · redact · audit · fine-tune"
VERSIONS = "Python 3.11–3.13 · LLaMA-Factory 0.9.4 · local LLM"
MADEBY = "made by @NotYuSheng"

AMBER = (242, 176, 76)
GRAD0, GRAD1 = (255, 196, 84), (233, 84, 64) # gold -> coral, vertical gradient
DIM = (140, 140, 150)

RESET = "\x1b[0m"

with open(os.path.join(ROOT, "demo/mascot.txt"), encoding="utf-8") as _f:
parrot = _f.read().rstrip("\n").split("\n")
Expand All @@ -32,27 +40,58 @@ def _fig(t):

word = _fig("Doppel") + _fig("ganger")
TOP = (len(parrot) - len(word)) // 2
TOTAL_W = PW + len(GAP) + max(len(l) for l in word)
WW = max(len(l) for l in word)
BLOCK_W = PW + len(GAP) + WW


def _solid(rgb, s):
return f"\x1b[1;38;2;{rgb[0]};{rgb[1]};{rgb[2]}m{s}{RESET}" if s.strip() else s


def _lerp(t):
"""Colour at fraction t along the top->bottom gradient."""
return tuple(round(GRAD0[k] + (GRAD1[k] - GRAD0[k]) * t) for k in range(3))


def rows(on, off):
def _center(plain, rgb=None, width=BLOCK_W):
pad = max(0, (width - len(plain)) // 2)
body = _solid(rgb, plain) if rgb else plain
return " " * pad + body


def lean_rows(on, off):
"""Parrot + wordmark only (for the CLI banner)."""
r = []
for i, pl in enumerate(parrot):
wl = word[i - TOP] if 0 <= i - TOP < len(word) else ""
wl = f"{on}{wl}{off}" if wl else ""
r.append((pl.ljust(PW) + GAP + wl).rstrip())
r.append("")
r.append(TAG.center(TOTAL_W).rstrip()) # tagline centred under the whole logo
return r


def card_rows():
"""The richer title card (coloured) for the GIF."""
rows = ["", _center(TAGLINE, DIM), ""]
n = max(1, len(word) - 1)
for i, pl in enumerate(parrot):
j = i - TOP
wl = _solid(_lerp(j / n), word[j]) if 0 <= j < len(word) else ""
rows.append(pl.ljust(PW) + GAP + wl)
rows += ["", _center(KEYWORDS, AMBER), ""]
box = len(VERSIONS) + 2
rows.append(_center("┌" + "─" * box + "┐", DIM))
rows.append(_center("│ " + VERSIONS + " │", DIM))
rows.append(_center("└" + "─" * box + "┘", DIM))
rows += ["", _center(MADEBY, DIM)]
return rows


def write_banner_module():
body = "\n".join(rows("<C>", "<R>")) # sentinels; colourised at runtime
body = "\n".join(lean_rows("<C>", "<R>"))
mod = (
'"""ASCII startup banner: a parrot in a mirror (it mimics your voice; the\n'
'mirror is the doppelganger) beside the wordmark. The wordmark is amber via\n'
'truecolor ANSI. Regenerate via demo/build_final.py.\n'
'Set DOPPELGANGER_NO_BANNER=1 to silence it."""\n\n'
'mirror is the doppelganger) beside the wordmark, in truecolor amber.\n'
'Regenerate via demo/build_final.py. DOPPELGANGER_NO_BANNER=1 silences it."""\n\n'
'import os\n\n'
'_AMBER = "\\x1b[1;38;2;242;176;76m" # truecolor amber\n'
'_RESET = "\\x1b[0m"\n\n'
Expand All @@ -62,40 +101,36 @@ def write_banner_module():
' return\n'
' print(_BANNER.replace("<C>", _AMBER).replace("<R>", _RESET) + "\\n")\n'
)
open(os.path.join(ROOT, "ingest/banner.py"), "w", encoding="utf-8").write(mod)
with open(os.path.join(ROOT, "ingest/banner.py"), "w", encoding="utf-8") as f:
f.write(mod)


def render_gif():
env = dict(os.environ, LLM_VALIDATE="false", DOPPELGANGER_NO_BANNER="1")
out = subprocess.run([PY, *CMD.split()[1:]], cwd=ROOT, env=env,
capture_output=True, text=True, check=True)
report = ((out.stdout or "") + (out.stderr or "")).split("\n")

card = card_rows()
events, t = [], 0.0
def emit(d, dt):
nonlocal t
t += dt
events.append([round(t, 3), "o", d])
emit("\x1b[32m$\x1b[0m ", 0.3)
for ch in CMD:
emit(ch, 0.026)
emit("\r\n", 0.5)
for line in rows(AMBER, RESET) + report:
emit(line + "\r\n", 0.05)
emit("\x1b[32m$\x1b[0m ", 1.6)
emit("\x1b[?25l", 0.2) # hide cursor
for line in card:
emit(line + "\r\n", 0.08)
emit("", 2.4) # hold on the finished card
Comment thread
NotYuSheng marked this conversation as resolved.
emit("\x1b[?25h", 0.0) # restore cursor

cast = os.path.join(ROOT, "demo/demo.cast")
with open(cast, "w", encoding="utf-8") as f:
f.write(json.dumps({"version": 2, "width": 94, "height": 34}) + "\n")
f.write(json.dumps({"version": 2, "width": BLOCK_W + 6, "height": len(card) + 2}) + "\n")
for ev in events:
f.write(json.dumps(ev, ensure_ascii=False) + "\n")
subprocess.run([AGG, "--font-size", "18", "--theme", "dracula", cast,
os.path.join(ROOT, "demo/demo.gif")],
stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, text=True, check=True)
subprocess.run(
[AGG, "--font-size", "18", "--theme", "dracula", cast,
os.path.join(ROOT, "demo/demo.gif")],
stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, text=True, check=True,
)


if __name__ == "__main__":
write_banner_module()
render_gif()
print("=== layout preview ===")
print("\n".join(rows("", "")))
print("\n".join(r for r in card_rows()))
Binary file modified demo/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 2 additions & 5 deletions ingest/banner.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""ASCII startup banner: a parrot in a mirror (it mimics your voice; the
mirror is the doppelganger) beside the wordmark. The wordmark is amber via
truecolor ANSI. Regenerate via demo/build_final.py.
Set DOPPELGANGER_NO_BANNER=1 to silence it."""
mirror is the doppelganger) beside the wordmark, in truecolor amber.
Regenerate via demo/build_final.py. DOPPELGANGER_NO_BANNER=1 silences it."""

import os

Expand All @@ -26,8 +25,6 @@
⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇
⢸⣇⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇
⠈⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠁

fine-tune an LLM to write like you
"""


Expand Down
Loading