Powrót do bloga
VibeFrame

11 min czytania

Zostałem zwolniony. To jest to, co zamiast tego zbudowałem.

Silnik widżetów zbudowany w wolnym czasie po pracy - SSR+CSR, poniżej 15 KB, szybszy i bardziej funkcjonalny niż wersja z codziennej pracy. Leżał na moim dysku przez sześć miesięcy. Potem next-vibe go potrzebował.

Miałem właśnie pokazać to mojemu zespołowi. Potem zostałem zwolniony.

Historia powstania

Moja codzienna praca miała problem z widżetami. Inne strony importowały nasz JavaScript, żeby wyświetlić widżet - formularz, bąbelek czatu, panel pulpitu nawigacyjnego. Skrypt był nieefektywny, napuchły, wolno się ładował. Strony trzecie, które go importowały, wyraźnie płaciły za to cenę. W wolnym czasie po pracy zacząłem budować zamiennik.

Prototyp wyszedł lepiej niż się spodziewałem. Obsługa SSR i CSR - SSR dla szybkości, CSR dla interaktywności. Poniżej 15 KB łącznie. Szybszy niż wersja z codziennej pracy. Więcej funkcji. W pełni reaktywny, w pełni bezpieczny typowo. Właściwy protokół postMessage między iframe a stroną hosta. Brak wspólnego stanu. System wyzwalaczy, tryby wyświetlania, kontrolki częstotliwości wyświetlania. Miałem właśnie pokazać to mojemu zespołowi. Potem zostałem zwolniony.

Baza kodu leżała na moim dysku przez około sześć miesięcy. Potem zdałem sobie sprawę, do czego next-vibe tego naprawdę potrzebował: nie tylko formularzy - ale renderowania pełnego interaktywnego UI narzędzia działającego na zdalnym serwerze, w piaskownicy, na dowolnej stronie. To zdalne wykonywanie narzędzi z żywym UI.

Problem z tagami script

Gdy osadzasz treści zewnętrzne za pomocą nagiego tagu script, płacisz na dwa sposoby. Wydajność: skrypt musi się załadować, przetworzyć i wykonać zanim cokolwiek się wyrenderuje. Jeśli serwer zewnętrzny jest wolny, twoja strona czeka. I bezpieczeństwo: ten skrypt ma pełny dostęp do strony - DOM, ciasteczka, localStorage, nasłuchiwacze zdarzeń. Jeśli jest wadliwy, twoja strona się psuje. Jeśli jest złośliwy, twoi użytkownicy są narażeni.

Standardową bezpieczną alternatywą jest iframe. Ale iframe domyślnie nie komunikuje się ze stroną nadrzędną. Zdarzenia zmiany rozmiaru nie bąbelkują. Przesyłanie formularzy nie propaguje. Kończysz z głupim izolowanym pudełkiem, które nie może nic powiedzieć swojemu rodzicowi.

To, czego naprawdę potrzebujesz, to most.

API postMessage pozwala iframe i stronie hosta komunikować się bezpiecznie, między różnymi źródłami. Definiujesz protokół. Waliduje się źródła. Każda wiadomość ma typ. To jest VibeFrame.

Most postMessage

Strona nadrzędna
Rodzic → iframe
init, token uwierzytelniania, motyw, wstępne wypełnienie danych, nawigacja wstecz
Protokół postMessage
Sandboxowany iframe
iframe → Rodzic
gotowy, zmiana rozmiaru, zamknij, sukces, błąd, nawiguj, wymagane uwierzytelnianie

Każda wiadomość ma prefiks vf:. Most nadrzędny waliduje źródło przed przetworzeniem czegokolwiek. Iframe nigdy nie wykonuje się w kontekście strony hosta.

Tryby wyświetlania i wyzwalacze

Cztery tryby wyświetlania

Inline

Osadza bezpośrednio w elemencie DOM. Automatycznie dostosowuje rozmiar.

Modal

Wyśrodkowana nakładka z tłem. Pojawia się nad stroną.

Wsuwanie

Wsuwa się z prawej strony. Dobry dla formularzy lub treści pomocniczych.

Dolna kartka

Wysuwa się od dołu. Standardowy wzorzec mobilny.

Siedem typów wyzwalaczy

Natychmiastowy - montuje się, gdy tylko strona się ładuje

Przewijanie - uruchamia się gdy użytkownik przewinął procent strony

Czas - uruchamia się po N milisekundach

Zamiar wyjścia - uruchamia się gdy mysz opuszcza viewport przez górę

Kliknięcie - uruchamia się gdy kliknięto określony element

Najechanie - uruchamia się przy wejściu myszy na selektor

Viewport - uruchamia się na podstawie rozmiaru ekranu

Częstotliwość wyświetlania

zawsze, raz-na-sesję, raz-na-dzień, raz-na-tydzień, raz-na-użytkownika. Egzekwowane po stronie klienta z localStorage. Bez podróży do serwera.

Dwa tagi script. Gotowe.

Każdy endpoint staje się osadzalny. Narzędzie działa na własnym serwerze. Widżet renderuje się w piaskownicy na twojej stronie. Pełne funkcje, zero wspólnego stanu.

Kompletny kod osadzania dla formularza kontaktowego z unbottled.ai

typescript
1import { VibeFrame } from "next-vibe/vibe-frame";
2
3VibeFrame.mount({
4  serverUrl: "https://unbottled.ai",
5  endpoint: "contact_POST",
6  target: "#contact-form",
7  trigger: { type: "immediate", display: "inline" },
8});

Lub jako zwykły tag script dla dowolnej strony:

html
1<script>
2  window.vibeFrameConfig = {
3    serverUrl: "https://unbottled.ai",
4    integrations: [{
5      endpoint: "contact_POST",
6      target: "#contact-form",
7      trigger: { type: "immediate", display: "inline" },
8    }],
9  };
10</script>
11<script src="https://unbottled.ai/vibe-frame/vibe-frame.js"></script>
Show the contact form from unbottled.ai on this page.
Claude Opus 4.6
I'll call the contact form endpoint on unbottled.ai. The response includes full widget data - the same UI renders here via the platform's widget system.
Contact form is live. The widget renders directly - same definition, same UI, zero extra work. Expand the tool call to see the widget data.
0.30 Kredyty 362 Tokeny

Panel administracyjny generuje to dla ciebie. Wybierz endpoint, wybierz tryb wyświetlania, wybierz wyzwalacz. Kopiuj. Wklej wszędzie.

Nie efekt uboczny. Sedno sprawy.

Gdy przeniosłem VibeFrame do next-vibe, pierwsze prawdziwe zastosowanie nie polegało na osadzeniu formularza kontaktowego na jakiejś zewnętrznej stronie. Było to zdalne wykonywanie narzędzi wewnątrz samej platformy - renderowanie pełnego interaktywnego UI widżetu dowolnego endpointu w piaskownicy, żeby rozproszone narzędzia działały jak jeden system.

Prawdziwe dane. Żywe wskaźniki. Wykres Vibe Sense reaguje na to, co dzieje się na serwerze. To nie jest zrzut ekranu ani eksport statyczny. Narzędzie działa. VibeFrame renderuje jego UI widżetu w piaskownicy wszędzie tam, gdzie tego potrzebujesz - wewnątrz platformy, na dashboardzie lub na dowolnej innej stronie.

Wtedy architektura zaskoczyła. VibeFrame nie był tylko sposobem na osadzanie formularzy na stronach trzecich. Był połową renderowania zdalnego wykonywania narzędzi - brakującym elementem, który sprawia, że rozproszony system narzędzi wydaje się jedną spójną platformą.

Sfederowane osadzanie

Każda integracja w VibeFrame może wskazywać na inny serverUrl. Oznacza to, że możesz osadzać widżety z wielu instancji next-vibe na tej samej stronie. Żaden wspólny backend. Żadna wspólna baza danych.

Wiele instancji, jedna strona hosta, zero wspólnej infrastruktury

typescript
1import { VibeFrame } from "next-vibe/vibe-frame";
2
3// Chat widget from unbottled.ai
4VibeFrame.mount({
5  serverUrl: "https://unbottled.ai",
6  endpoint: "agent_chat_threads_GET",
7  target: "#chat",
8});
9
10// Product catalog from a shop instance
11VibeFrame.mount({
12  serverUrl: "https://shop.example.com",
13  endpoint: "products_GET",
14  target: "#products",
15  trigger: { type: "scroll", scrollPercent: 30, display: "modal" },
16});
17
18// Analytics dashboard from yet another instance
19VibeFrame.mount({
20  serverUrl: "https://analytics.example.com",
21  endpoint: "vibe_sense_dashboard_GET",
22  target: "#dashboard",
23  trigger: { type: "click", clickSelector: "#show-stats", display: "slideIn" },
24});

Definicja podróżuje z widżetem. Serwer, który jest właścicielem endpointu, jest właścicielem renderowania.

Połowa wywołań

VibeFrame obsługuje renderowanie. Rejestr narzędzi obsługuje wywołania. Podłączasz zdalne instancje next-vibe – każda z nazwą jak hermes, thea lub własnym aliasem. Ich endpointy stają się dostępne obok twoich lokalnych narzędzi. Jeden zunifikowany zestaw.

AI używa tool-help, żeby odkryć każdy dostępny endpoint – lokalny i zdalny. Widzi cały rejestr: nazwy, opisy, typowane wejścia, typowane wyjścia. Gdy wywołuje execute-tool, platforma kieruje do właściwej instancji. AI nie obchodzi, gdzie narzędzie mieszka.

Ty masz kontrolę. Przypnij narzędzia, które chcesz widzieć, wyłącz te, których nie potrzebujesz. Ta sama obsługa dla lokalnych i zdalnych endpointów – żadnej różnicy w konfiguracji.

Połącz instancje. AI odkrywa narzędzia. Ty decydujesz, których używasz.

Skille: warstwa persony

Na wierzchu skille dodają personę. Skill to preset – nazwa, system prompt, głos, osobowość i opcjonalnie ograniczony zestaw narzędzi. Użytkownik wybiera korepetytora, programistę, gawędziarza. Pod spodem to ten sam rejestr, te same endpointy, te same wywołania execute-tool.

Perspektywa użytkownika

Skill to persona. Korepetytor, programista, gawędziarz. Każdy ma nazwę, głos, osobowość. Wybierasz jednego i zaczynasz rozmawiać.

Perspektywa AI

Skill to preset konfiguracji. Może ograniczyć widoczne narzędzia, przypiąć konkretne endpointy lub zostawić pełny rejestr otwarty. Ten sam interfejs execute-tool, tylko zawężony.

Zdalne wykonywanie narzędzi

Oto co łączy VibeFrame i rejestr narzędzi. Gdy AI wywołuje execute-tool ze zdalnym endpointem, next-vibe kieruje wywołanie do docelowej instancji. Ta instancja wykonuje narzędzie i zwraca wynik. Dość standardowo.

Ale każdy endpoint w next-vibe ma też widżet – typowaną, w pełni wyposażoną komponentę UI, która wie, jak renderować wejścia i wyjścia tego narzędzia. Jeśli zdalna instancja jest publicznie dostępna, VibeFrame renderuje prawdziwy widżet w sandboxowanym iframe, komunikując się z serwerem narzędzia przez postMessage. Pełna interaktywność, żywe dane, prawdziwe UI.

Jeśli instancja nie jest publiczna – za firewallem, w prywatnej sieci – platforma przechodzi na UI sterowane definicją. Definicja endpointu zawiera wystarczająco metadanych (typy pól, etykiety, reguły walidacji), żeby wyrenderować funkcjonalny interfejs lokalnie, bez sięgania po frontend zdalnego serwera. Tak czy inaczej narzędzie działa. UI się dostosowuje.

Agent AI
execute-tool

wywołuje narzędzie

Zdalna instancja

wykonuje, zwraca wynik

renderuje pełne UI w piaskownicy

VibeFrame
Widżet UI w piaskownicy

Serwer, który posiada narzędzie, posiada UI. VibeFrame renderuje ją wszędzie, gdzie jej potrzebujesz. Tak wygląda zdalne wykonywanie narzędzi z pełnym frontendem.

Co mają wspólnego

VibeFrame i rejestr narzędzi rozwiązują ten sam problem z przeciwnych stron. Rejestr narzędzi obsługuje wywołania - każdy endpoint na dowolnej instancji, wywoływalny z dowolnej AI. VibeFrame obsługuje renderowanie - każdy widżet z dowolnej instancji, osadzalny na dowolnej stronie. Zdalne wykonywanie narzędzi to most między nimi: wywołaj narzędzie, renderuj jego UI.

Rozproszony system narzędzi z rozproszonym systemem renderowania. To jest next-vibe.

Zobacz na GitHubie

bash
1git clone https://github.com/techfreaque/next-vibe
2cd next-vibe
3cp .env.example .env
4bun install
5vibe dev

Nigdy nie mogłem tego pokazać tym kolegom. Ale pokazuję to tobie.