Przejdź do treści

Wizualny edytor scenariuszy — tutorial

Ten dokument prowadzi Cię przez wszystkie elementy edytora w panel.aiofactory.pl/support → zakładka Scenariusze. Zacznij od Obsługi Klienta — przeglądu, jeśli nie wiesz, czym jest scenariusz; tutaj zakładamy znajomość pojęć z Słowniczka.

Krótko

  • Edytor to dialog na całym ekranie, palette po lewej (lista typów węzłów), płótno na środku, panel testu po prawej.
  • Każdy scenariusz ma jeden korzeń (Source) i tworzy graf bez cykli (DAG). Zapisanie kompiluje graf do flow Windmill.
  • Aktywujesz dopiero po teście. Domyślnie nowy scenariusz startuje wyłączony.
  • Edycja istniejącego scenariusza tworzy wpis w Historii — możesz cofnąć każdą zmianę.

1. Otwarcie edytora

W panelu lewy pasek → Obsługa Klienta → trzecia zakładka u góry: Scenariusze.

Co widzisz w widoku listy:

  • Nagłówek strony: tytuł „Scenariusze automatyzacji" + dwa przyciski (Odśwież, Dodaj scenariusz).
  • Lista kart — każda karta to jeden scenariusz, z nazwą, statusem (zielony badge Aktywny lub szary Nieaktywny), priorytetem i ikonkami akcji po prawej (Aktywuj/Dezaktywuj — ikona przycisku zasilania, Edytuj — ołówek, Usuń — kosz).
  • Karty „Starter C10" mają złotawe tło i napis Starter C10 — są to gotowe szablony, które klonujesz i adaptujesz (patrz szablon kolorów, szablon imion psów).
  • Badge pending / review — gdy zespół ROOTACCESS opublikuje aktualizację seedowaną (np. lepszy prompt LLM), pojawi się żółty znacznik z liczbą oczekujących migracji. Klikasz Edytuj → pasek narzędzi → przycisk Aktualizacje i decydujesz, czy zastosować.

Aby otworzyć edytor:

  • Nowy scenariusz — przycisk Dodaj scenariusz w nagłówku → otwiera pusty edytor (tytuł placeholder „Nazwa scenariusza").
  • Istniejący — ikona ołówka na karcie scenariusza.

Edytor otwiera się jako dialog na całej szerokości ekranu (~92% wysokości okna). Pasek tytułu sam dialogu jest niewidoczny — zamiast niego u góry masz kompaktowy pasek narzędzi.


2. Anatomia paska narzędzi (góra edytora)

Pasek dzieli się na trzy rzędy:

Rząd 1 — pasek tożsamości scenariusza (h-14)

Od lewej:

Element Co robi
Pole tekstowe „Nazwa scenariusza" Identyfikator pokazywany na liście scenariuszy. Np. Eskalacja sporów Allegro. Wymagane.
Priorytet (input liczbowy 1–999) Gdy do jednego zdarzenia pasuje więcej niż jeden scenariusz, dyspozytor uruchamia je w kolejności rosnącego priorytetu. Domyślnie 100.
Aktywny (checkbox) Włącza/wyłącza scenariusz dla dyspozytora. Patrz Głośna szyba bezpieczeństwa.
Dodaj opis / Edytuj opis Otwiera pole opisu pod paskiem (zobaczysz je w widoku listy jako podtytuł karty).
Auto-layout (prawa strona) Re-układa graf — przydatne, gdy „bałagan" po wielu zmianach.
Windmill (prawa strona) Otwiera w nowej karcie wygenerowany flow Windmill — tylko dla zaawansowanej diagnostyki.
Anuluj / Zapisz Anuluj zamyka bez zapisu. Zapisz waliduje graf i wysyła do Convex; przy błędach walidacji widzisz banner ze szczegółami.

Rząd 2 — pasek triggera (h-11, lekko wyciemnione tło)

Definiuje, kiedy ten scenariusz ma się włączyć:

Pole Co wybierasz
Źródło Skąd pochodzi zgłoszenie: Email (Gmail / Mailcow), Allegro, eBay, Erli, WooCommerce, Harmonogram (cron).
Konto (jeśli źródło ≠ Harmonogram) „Dowolne konto" lub konkretne konto z listy (np. konkretna skrzynka Gmail / konkretne OAuth Allegro).
Gdy nastąpi Typ zdarzenia: Nowe zgłoszenie (new_issue), Nowa wiadomość (new_message), Nowy spór / reklamacja (dispute_opened), Zgłoszenie zwrotu (return_requested). Dostępne typy zależą od źródła.
Typ (opcjonalny) Zawęża do konkretnego typu zgłoszenia po stronie platformy: dla eBay np. Wiadomość (CORE), Payment dispute, Zwrot, MBG case.
Cron (tylko Harmonogram) Wyrażenie cron 6-polowe, np. 0 */2 * * * = co 2 godziny.

Przyciski po prawej:

  • Dane wejściowe — rozwija notatkę z listą pól, jakie scenariusz dostanie do wykorzystania (np. issue.subject, issue.snippet, issue.messages[*].text). Świetne odniesienie podczas pisania promptu LLM.
  • Aktualizacje — pojawia się tylko dla scenariuszy zaseedowanych (z migrationsami) i ma żółty znacznik z liczbą oczekujących aktualizacji.
  • Historia — lista 50 ostatnich zapisów z przyciskiem Przywróć przy każdej.
  • N węzłów · M połączeń — licznik. Obok strzałka ręcznie odświeża walidację.

Trigger „Harmonogram (cron)" — to inny typ scenariusza

Wszystkie zwykłe scenariusze startują od zdarzenia (wiadomość, spór, …). „Harmonogram" startuje sam o wybranej godzinie — issue i event są wtedy puste, więc pierwszy węzeł musi sam pobrać dane (np. BaseLinker call → getOrders). Patrz Reference węzłów → BaseLinker call.

Rząd 3 — banner błędów (pojawia się tylko, jeśli są)

Pasek z czerwonym tłem zawierający komunikaty walidacji:

  • Błędy zapisu (np. „Nazwa scenariusza jest wymagana") — z ikoną alertu.
  • Błędy globalne grafu (np. „Scenario graph contains a cycle at node 'gate'") — z tekstem rozdzielonym kropkami.
  • Ostrzeżenia migracji (żółty kolor) — np. „Sub-drzewo zostało zmodyfikowane przez operatora".

Przycisk × po prawej zwija banner do następnej zmiany.


3. Anatomia płótna

Pod paskami narzędzi cała przestrzeń to płótno SvelteFlow:

  • Tło w kropki — siatka 20×20 px, do której węzły się przyciągają.
  • Mini-mapa w prawym dolnym rogu — szybkie nawigowanie po dużych grafach.
  • Sterowanie w lewym dolnym rogu — + / − / ⛶ (zoom in/out/fit-view) + 🔒 (locked / unlocked).
  • Palette po lewej — kolumna szerokości 256 px ze spinaniem (przycisk < zwija ją do paska 48 px). Patrz niżej.
  • Panel testu po prawej — kolumna szerokości 360 px, domyślnie zwinięta. Patrz niżej.

Palette (lewa kolumna)

Lista wszystkich węzłów, które możesz dodać. Pogrupowane:

  • TriggerSource (już dodany jako korzeń, ale jest dostępny do ponownego wstawienia w wyjątkowych przypadkach).
  • LogicFilter, Delay.
  • AILLM extract.
  • ActionsSend reply, Send template, Update status, Escalate, Create ticket, Mark email read, BaseLinker field, BaseLinker call, BaseLinker find by tag, eBay dispute action, eBay return decide, Amazon template message.

Kliknięcie kafelka dodaje węzeł na płótno (pojawia się w pozycji (40, 40 + N×120) — przesuń go ręcznie po dodaniu kilku).

Trzy węzły są ukryte z palety (Source, Append puppy name, Parse personalization cards) — pojawiają się tylko, gdy klonujesz szablon, który ich używa. Patrz Reference węzłów.

Panel testu (prawa kolumna)

Wyłączony domyślnie — kliknij < przy prawej krawędzi, żeby go rozwinąć. Działa tylko na bezpiecznych węzłach (Filter, LLM extract, BaseLinker find by tag, parse_personalization_cards) — czyli tych, które nie wykonują żadnej akcji na rzeczywistym systemie. Akcje typu send_reply mają napis „Ten węzeł wykonuje akcję na rzeczywistym systemie — preview niedostępny".

Dwa tryby:

  1. Z istniejącego zgłoszenia — wybierasz z listy ostatnich 20 zgłoszeń → panel pobiera pełny dokument zgłoszenia → wstawia go do pola mock_issue jako JSON.
  2. JSON — sam edytujesz pola mock_issue, mock_event, mock_results.

Po kliknięciu Uruchom test węzeł wykonuje się w izolacji (bez side-effectów), zwraca wynik (JSON) + czas wykonania. Możesz kliknąć „Do upstream" — wynik trafia do mock_results jako gdyby ten węzeł właśnie się wykonał. To pozwala testować łańcuchowo: wynik węzła A → input węzła B.


4. Anatomia węzła na płótnie

Każdy węzeł to karta z trzema sekcjami:

Nagłówek karty

  • Pole tytułu (edytowalne) — tytuł, który zobaczysz na płótnie. Domyślnie pochodzi z typu („LLM extract", „Send reply"), ale przepisz go tak, żeby był czytelny dla siebie za miesiąc (np. „Wyciągnij imię psa z tematu").
  • Identyfikator typu (np. llm_extract) — szary tekst pod tytułem, niezmienny.
  • Ikona kosza w prawym górnym rogu — usunięcie węzła (połączenia z/do niego znikną).

Lista pól

Każdy typ węzła ma własny zestaw pól:

Rodzaj pola Wygląd Jak edytujesz
text Pojedyncze pole tekstowe Wpisujesz wartość.
textarea Wieloliniowe pole tekstowe Wpisujesz tekst, np. prompt LLM.
select Lista rozwijana Klikasz, wybierasz opcję.
boolean Checkbox Klikasz.
number Pole liczbowe Wpisujesz liczbę (z walidacją min/max).
string-list Lista chip-ów Wpisujesz wartość, Enter → dodaje chip; klikasz × na chipie → usuwa.
key-value-list Lista par „klucz → wartość" Przyciskiem + Dodaj dodajesz wiersz, edytujesz oba pola.
schema-fields Edytor schematu JSON Definiujesz pola (nazwa + typ) — używane np. do ekstrakcji LLM.
account-id Lista kont Wybierasz konto z dropdown (lista zaciągana z cs_email_accounts / marketplace_accounts).

Pod każdym polem tekstowym, które wspiera placeholdery (prompt_template, body, value w BaseLinker, …), masz panel Upstream outputs — lista nazw węzłów wyżej w grafie i ich pól, np.:

extract_color (LLM extract)
   fields    (object)   — pola wyciągnięte przez LLM
   confidence (number)  — 0=no_name, 1=vague, 2=certain
   route     (string)   — "certain" | "vague" | "no_name"

Kliknięcie pola wstawia gotowy placeholder ({{results.extract_color.fields.color}}) do edytowanego pola.

Uchwyty (handles)

  • Uchwyt wejścia — lewa krawędź karty, mały kropka.
  • Uchwyt(y) wyjścia — prawa krawędź. Liczba zależy od typu:
    • Większość węzłów: 1 uchwyt (bez etykiety).
    • Filter: 2 uchwyty: continue (góra) i skip (dół).
    • LLM extract: 3 uchwyty: certain (2), vague (1), no_name (0) — odpowiadają polu route w wyniku.

5. Łączenie węzłów (krawędzie)

Drag & drop: kliknij i przeciągnij od uchwytu wyjścia jednego węzła do uchwytu wejścia drugiego. SvelteFlow rysuje krzywą Béziera; po puszczeniu krawędź jest gotowa.

Reguły, które edytor egzekwuje przy zapisie:

Reguła Komunikat błędu, gdy łamiesz
Dokładnie jeden korzeń (węzeł bez wejść) Scenario graph must have exactly one root node
Brak cykli (graf musi być DAG-iem) Scenario graph contains a cycle at node '<id>'
Brak złączeń — żaden węzeł nie może mieć więcej niż 1 wejście Scenario graph merges are not supported yet (node '<id>' has multiple inputs)
Każdy węzeł musi być osiągalny z korzenia Scenario graph contains disconnected nodes: <id>
Węzeł z 2+ wyjściami musi mieć etykiety na krawędziach Scenario graph node '<id>' needs labeled outputs to preserve branch routing

Brak złączeń = duplikuj węzły w gałęziach

Edytor nie pozwala na merge dwóch gałęzi w jeden wspólny węzeł. Jeśli obie gałęzie mają kończyć się tym samym Update status, dodaj dwa identyczne węzły Update status — po jednym w każdej gałęzi.

Etykiety krawędzi (dla węzłów z wieloma wyjściami)

Krawędź wychodząca z Filter automatycznie ma etykietę continue lub skip (bo Filter ma uchwyty z tymi nazwami). Krawędź z LLM extract ma certain, vague lub no_name. Etykiety widzisz na krawędzi jako mały owalny tekst.


6. Placeholdery — referencja do wyniku poprzedniego węzła

W polu tekstowym, które wspiera szablonowanie, możesz wstawić wartość z poprzedniego węzła. Składnia:

{{results.<id_węzła_źródłowego>.<klucz>}}

Przykład:

{{results.extract_color.fields.color}}

Działa to tylko, gdy całe pole jest jednym placeholderem. Tekst „Hi {{results.extract_color.fields.name}}, …" nie zostanie podstawiony — całe pole pojechałoby do węzła jako literał.

Per-node placeholdery ({{customer_name}}, {{subject}}, {{text}})

To inny mechanizm — działa wewnątrz niektórych węzłów (LLM extract, Send reply, Send template, Create ticket). Te placeholdery są podstawiane w runtime przez sam węzeł, nie przez edytor. Pełna lista: zobacz każdy węzeł w Reference węzłów, sekcja „Per-node template placeholders".


7. Zapis — co się dzieje pod spodem

Klikasz Zapisz:

  1. Walidacja po stronie panelu — graf ma korzeń, brak cykli, brak złączeń, etykietki na rozgałęzieniach, referencje upstream pasują do dataOutputs poprzednich węzłów.
  2. Wysłanie do Convex — POST do /api/cs/scenarios (akcja create lub update).
  3. Convex zapisuje rekord w cs_scenarios z polem graph (graf) + metadanymi (nazwa, priorytet, aktywny, źródło, …).
  4. Convex wstawia wpis do Historii (cs_scenario_history) z poprzednią i nową wersją grafu.
  5. Convex schedule-uje akcję flow_sync.syncScenarioFlowInternal — to ona kompiluje graf na flow Windmill pod ścieżką f/support/scenarios/<slug> i (dla scenariuszy scheduled) tworzy odpowiedni cron-schedule.
  6. Edytor zamyka się i widok listy się odświeża.

Jeśli walidacja po stronie Convex padnie (np. graf ma odwołanie do węzła wyżej w grafie), zobaczysz banner ze szczegółowym komunikatem — rekord nie został zapisany.

Zapis ≠ aktywacja

Sam zapis nie aktywuje scenariusza, jeśli wcześniej go nie aktywowałeś. Pamiętaj o checkboxie Aktywny w pasku narzędzi.


8. Test pojedynczego węzła

Przed pierwszą aktywacją:

  1. Wybierz węzeł na płótnie (kliknij na kartę — pojawia się obwódka).
  2. Otwórz Panel testu po prawej (< przy prawej krawędzi).
  3. Tryb „Z istniejącego zgłoszenia" — wybierz prawdziwe zgłoszenie z listy. Panel pobiera jego JSON i wstawia do mock_issue.
  4. (Opcjonalnie) Edytuj mock_event (np. zmień typ zdarzenia).
  5. (Opcjonalnie) Wstaw mock_results jeśli ten węzeł zależy od wyników innych węzłów. Możesz też uruchomić węzeł upstream, kliknąć „Do upstream" i wynik trafi do mock_results automatycznie.
  6. Kliknij Uruchom test. Wynik (JSON) pokaże się pod przyciskiem.

Co możesz przetestować:

Węzeł Co zwraca
Filter {action: "continue" \| "skip", actual: <wartość pola>, ...}
LLM extract {fields: {...}, confidence: 0/1/2, route: "no_name" \| "vague" \| "certain"}
BaseLinker find by tag {found: true/false, order_product_id, bl_order_id, sku, name, ...}
Parse personalization cards {structured: bool, expected_cards: int|null, candidate_names: [...], personalized_skus: [...]}

Akcji (send_reply, update_status, escalate, create_ticket, …) nie da się przetestować w izolacji z tej strony — uruchomiłyby się na prawdziwym systemie. Aby je przetestować, użyj zgłoszenia testowego (wyślij sobie email, otwórz issue ręcznie) i obserwuj Logi → Przebiegi.


9. Aktualizacje (migracje seedowane)

Jeśli używasz scenariusza zaseedowanego (np. „Color extraction → BaseLinker"), zespół ROOTACCESS może wypuścić aktualizację (np. lepszy prompt LLM). Wtedy:

  1. Na karcie scenariusza w widoku listy pojawi się żółty znacznik N pending.
  2. W edytorze otwórz pasek Aktualizacje (przycisk z ikoną ) — widzisz listę dostępnych migracji.
  3. Każda migracja ma trzy stany:
    • Do zastosowania (apply) — możesz nacisnąć Apply.
    • Zmodyfikowane lokalnie (skip-diverged) — operator zmienił sub-drzewo, którego dotyczy migracja. Apply nie zadziała automatycznie; możesz kliknąć Diff, żeby zobaczyć, co byś dostał.
    • Zastosowane (already-applied) — migracja jest już aktywna.
  4. Przed kliknięciem Apply możesz kliknąć Diff — pojawia się side-by-side: graf przed i po migracji.

Jeśli pominiesz migrację (Skip), Convex zapamięta, że ją odrzucasz — nie będzie się więcej pojawiać.


10. Historia i przywracanie

Każdy zapis tworzy nowy wpis w Historii. Otwórz scenariusz w edytorze → przycisk Historia w pasku narzędzi.

Każdy wpis pokazuje:

  • Datę i godzinę (np. 2 maj 2026, 14:32).
  • Autora (email operatora, który zapisał).
  • Powód (jeśli był podany — większość zapisów go nie ma).
  • Przycisk Przywróć — wraca do grafu z tej daty.

Przywrócenie też tworzy nowy wpis

Przywrócenie z historii nie nadpisuje aktualnego stanu — dodaje nową wersję identyczną z wybraną. Możesz potem spokojnie wrócić do tego, co było.


11. Najczęstsze błędy

Błąd Symptom Rozwiązanie
Nie ma uchwytów continue / skip na Filter Nie widzisz dwóch uchwytów wyjścia Edytor stworzył je automatycznie — przewiń kartę, są na prawej krawędzi nieco rozsunięte.
Save fails: graph has merges Zapisałeś dwie krawędzie zbiegające się w jeden węzeł Skopiuj końcowy węzeł — po jednym w każdej gałęzi.
references unknown step '<id>' Skopiowałeś placeholder z innego scenariusza, ale nie ma tu takiego węzła Wstaw placeholder z panelu Upstream outputs (lewa strona pola).
Filter nie działa, mimo że pole pasuje Zazwyczaj case_sensitive=false jest zostawione domyślnie, a wpisałeś WIELKIE LITERY w value Wyłącz case_sensitive lub dopasuj wielkość liter.
LLM extract zwraca puste pola Prompt nie zawiera {{text}} lub {{subject}} Wstaw placeholdery do promptu — bez nich LLM dostaje pusty kontekst.
Scenariusz nie startuje mimo aktywacji Zły trigger / źródło / konto / typ — dyspozytor nie znajduje dopasowania Otwórz /marketplace/history/runs filtrowane po nazwie scenariusza i sprawdź, czy są przebiegi. Jeśli nie — sprawdź pasek triggera, czy Źródło i Gdy nastąpi pasują do realnego zdarzenia.

Pełna lista błędów walidacji + interpretacja: Reference węzłów → Najczęstsze błędy.


Dane techniczne

  • Komponent edytora: dashboard/src/routes/support/ScenarioBuilderDialog.svelte (1834 linii) + ScenarioBuilderNode.svelte (per-node card) + FlowFitView.svelte (auto-fit).
  • Walidacja po stronie klienta: dashboard/src/lib/support/graph.ts:validateBuilderGraph.
  • Walidacja + kompilacja po stronie Convex: convex/convex/support/flow_sync.ts:analyzeGraph + validateResultsReferences.
  • Katalog typów węzłów (palette): convex/convex/support/nodeCatalog.ts (źródło prawdy dla pól, etykiet, dataOutputs).
  • Generowane flow Windmill: f/support/scenarios/<48-znaków-nazwy>-<8-ostatnich-id>/.