A 32 s trailer rendered in Blender from the Apex Universe scene. The pane in it is the real widget replaying answers Fusion AI gave on the live route, voiced by ElevenLabs Brian, with an original score. fusion/launch/ holds the 16:9 cut, its poster and English captions. The HAL 8 section gets a 'Meet Fusion AI' card (Talk to Fusion AI opens the widget through a fusion:open event), and the widget's welcome screen a 'Watch the launch film' chip that plays it in a lightbox. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
90 lines
4.6 KiB
Python
90 lines
4.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Put Fusion AI (powered by HAL 8) into the hub, replacing the old assistant pane.
|
|
|
|
python3 tools/fusion_inject.py
|
|
|
|
The widget itself is fusion/fusion.js (served as a file, loaded on demand) and fusion/fusion.css
|
|
(inlined into the bundle). The old block, from its "FUSION AI — assistant pane" banner to the end of
|
|
the FusionAI component, is replaced by a small component between /*F8-BEGIN*/ and /*F8-END*/;
|
|
re-running replaces that block and the style block again, so the script is idempotent.
|
|
The endpoint is HAL 8's public Fusion route; window.FUSION_AI_ENDPOINT still overrides it.
|
|
"""
|
|
|
|
import hashlib
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
SITE = Path(__file__).resolve().parents[1]
|
|
ENDPOINT = "https://hal8.odyssey-works.io/v1/public/fusion/chat"
|
|
tool = SITE / "tools" / "bundle.py"
|
|
tmp = SITE / "tools" / "_page.html"
|
|
subprocess.run([sys.executable, str(tool), "decode", str(SITE / "index.html"), str(tmp)], check=True, capture_output=True)
|
|
page = tmp.read_text("utf-8")
|
|
|
|
VER = hashlib.sha1((SITE / "fusion" / "fusion.js").read_bytes()).hexdigest()[:10]
|
|
FILM = SITE / "fusion" / "launch" / "fusion-ai-launch.mp4"
|
|
FILM_V = hashlib.sha1(FILM.read_bytes()).hexdigest()[:10] if FILM.exists() else "0"
|
|
COMPONENT = f"""/*F8-BEGIN*/
|
|
// ============================================================================
|
|
// FUSION AI — powered by HAL 8 (fusion/fusion.js; the key lives on HAL 8, never here)
|
|
// ============================================================================
|
|
function FusionAI() {{
|
|
const ref = useRef(null);
|
|
useEffect(() => {{
|
|
let api = null, dead = false;
|
|
import("./fusion/fusion.js?v={VER}")
|
|
.then(m => {{ if (!dead) api = m.mount(ref.current, {{ endpoint: window.FUSION_AI_ENDPOINT || "{ENDPOINT}" }}); }})
|
|
.catch(e => console.warn("[Fusion AI]", e));
|
|
return () => {{ dead = true; if (api) api.destroy(); }};
|
|
}}, []);
|
|
return MG("div", {{ ref }});
|
|
}}
|
|
// the launch film, on the HAL 8 page (fusion/launch/; "Talk to Fusion AI" opens the widget)
|
|
function FusionLaunchCard() {{
|
|
const film = "fusion/launch/fusion-ai-launch";
|
|
return MG("div", {{ className: "f8-launch" }},
|
|
MG("div", {{ className: "f8-launch-media" }},
|
|
MG("video", {{ src: film + ".mp4?v={FILM_V}", poster: "fusion/launch/poster.jpg?v={FILM_V}", controls: true, playsInline: true, preload: "none" }},
|
|
MG("track", {{ kind: "captions", src: film + ".vtt?v={FILM_V}", srcLang: "en", label: "English" }}))),
|
|
MG("div", {{ className: "f8-launch-copy" }},
|
|
MG("div", {{ className: "f8-launch-kicker" }}, "NEW · FUSION AI"),
|
|
MG("h3", null, "Meet Fusion AI. ", MG("span", {{ className: "serif-i" }}, "Powered by HAL 8.")),
|
|
MG("p", null, "The assistant on this site. Ask anything, write and run code, make images and short video, or just talk. Standard keeps your chat in this browser; Incognito keeps nothing."),
|
|
MG("div", {{ className: "h8-cta" }},
|
|
MG("button", {{ className: "mgx-btn pri", onClick: () => window.dispatchEvent(new CustomEvent("fusion:open")) }}, "Talk to Fusion AI"),
|
|
MG("a", {{ className: "mgx-btn", href: film + ".mp4", download: "fusion-ai-launch.mp4" }}, "Download the film"))));
|
|
}}
|
|
/*F8-END*/
|
|
"""
|
|
|
|
if "/*F8-BEGIN*/" in page:
|
|
i = page.index("/*F8-BEGIN*/")
|
|
j = page.index("/*F8-END*/\n", i) + len("/*F8-END*/\n")
|
|
else:
|
|
banner = page.index("// FUSION AI — assistant pane")
|
|
i = page.rfind("// ====", 0, banner)
|
|
f = page.index("function FusionAI()", banner)
|
|
j = re.compile(r"\n}\n").search(page, f).end()
|
|
old = page[i:j]
|
|
assert old.count("function ") == 1 and "SYSTEM_PROMPT" in old and "Powered by Claude" in old, "unexpected old block"
|
|
page = page[:i] + COMPONENT + page[j:]
|
|
assert "Powered by Claude" not in page and page.count("function FusionAI()") == 1
|
|
# the card sits in the HAL 8 section, right above "Inside the harness"
|
|
HOOK = 'MG("div", { className: "mg-subhead" }, "Inside the harness"),'
|
|
if "MG(FusionLaunchCard, null)" not in page:
|
|
assert page.count(HOOK) == 1, "HAL 8 section hook not found"
|
|
page = page.replace(HOOK, "MG(FusionLaunchCard, null),\n " + HOOK)
|
|
|
|
css = (SITE / "fusion" / "fusion.css").read_text("utf-8")
|
|
page = re.sub(r"<style>/\*f8-css-begin\*/.*?/\*f8-css-end\*/</style>\n", "", page, flags=re.S)
|
|
k = page.rfind("</head>")
|
|
page = page[:k] + "<style>/*f8-css-begin*/" + css + "/*f8-css-end*/</style>\n" + page[k:]
|
|
|
|
tmp.write_text(page, "utf-8")
|
|
r = subprocess.run([sys.executable, str(tool), "encode", str(SITE / "index.html"), str(tmp), str(SITE / "index.html")], capture_output=True, text=True)
|
|
tmp.unlink()
|
|
print(r.stdout.strip() or r.stderr.strip())
|
|
print(f"fusion.js v{VER}")
|