Skip to main content

Narzędzia

Narzędzie to nazwana akcja, którą może wywołać AI, z typizowanymi wejściami — np. send_email(to, subject, body). Narzędzia są deklarowane w pliku tools.ts umiejętności i, dla narzędzi, które serwuje Twoja aplikacja, wspierane przez trasę HTTP w jednym z Twoich komponentów. Ta strona jest źródłem prawdy dla kontraktu narzędzia; Umiejętności opisują, gdzie znajduje się tools.ts.

Deklarowanie narzędzia

Każdy wpis w tools.ts ma bezpieczną dla dostawcy name, przyjazną displayName, description, schemat Zod input i target, który określa, co Kazzle wywołuje.

Cele

target to wielokrotnie używany adres dla narzędzia lub przycisku wymaganej akcji. Bezpośrednie wywołanie narzędzia AI i kliknięcie przycisku mogą używać tego samego obiektu target, więc oba uruchamiają ten sam kod. Cele HTTP używają tych samych pól żądania:
Nie ma niejawnych domyślnych ustawień żądania. Jeśli Twój handler powinien otrzymać surowe wejście narzędzia jako JSON, napisz body: '${input}'.

Odwołania

Kazzle rozwiązuje odwołania w polach query, headers, body i url celu HTTP przed wysłaniem:
  • ${input} — całe wejście narzędzia lub całe wejście przycisku.
  • ${input.path} — zagnieżdżona wartość z wejścia.
  • ${env.NAME} — nazwana zmienna środowiskowa z deklarowanej env.collection + env.environment komponentu aplikacji będącego właścicielem.
Rozwiązanie jest jednorazowe. Jeśli odwołanie brakuje lub jest nieznane, narzędzie się nie powiedzie zamiast podstawiać pustą wartość. Użyj $${input.name}, gdy potrzebujesz dosłownego tekstu ${input.name}.

Żądanie handlera

Dla celu app dodaj pasującą trasę w komponencie docelowym. Z body: '${input}', Kazzle wysyła typizowane wejście jako treść JSON:
Cele app również otrzymują: Cele aplikacji nie mogą ustawiać Authorization przez headers; Kazzle jest właścicielem tego nagłówka. Przeczytaj kontekst za pomocą toolContext(req) z @kazzle/app/tools, gdy handler musi rozróżniać wątek vs Tools API. Narzędzie zadeklarowane bez pasującej trasy nic pożytecznego nie robi — dodaj oba razem. tools.json nie jest obsługiwany; kompilator aplikacji się nie powiedzie, jeśli go znajdzie.

Odpowiedź handlera

Zwróć zwykły tekst lub JSON z maksymalnie trzema kanałami:
  • content — zwykły wynik, który czyta AI (przekazywany do modelu). Wymagane.
  • markdown — opcjonalnie. Krótkie podsumowanie w formacie bogatego tekstu renderowane na karcie narzędzia (react-markdown; surowy HTML jest zmieniony). Dobre dla zdania, małej listy, linku wbudowanego. Sama ścieżka względna renderuje się jako martwy tekst preformatowany — linki muszą być bezwzględne.
  • embedUrl — opcjonalnie. Bezwzględny adres URL, który serwuje Twoja aplikacja; karta renderuje go w piaskownicy iframe. W ten sposób pokazujesz rzeczywisty, pełnoszerokoś UI — ekran połączenia, pulpit nawigacyjny, wykres. Twoja aplikacja hostuje i jest właścicielem strony, więc może być w pełni interaktywna względem Twojego własnego backendu, ciasteczek i OAuth. Nic nie jest zapisywane na dysku.
embedUrl wygrywa nad markdown, gdy oba są ustawione. Zawsze zachowaj znaczący content — to to, co czyta AI.

Wymagana akcja

Narzędzie aplikacji może wstrzymać wątek, gdy potrzebuje akcji użytkownika (lub urządzenia). Zwróć type: 'action_required' z tytułem karty i przyciskami. Ważne tylko wtedy, gdy toolContext(req).source === 'thread' — przez Tools API (source: 'api'), zwróć zamiast tego normalny błąd domeny.
Kazzle zapisuje kartę na wywołaniu narzędzia i wznawia przez /chat/resume po naciśnięciu przycisku. Pasujący klienci widzą przyciski autora; niepassujący klienci nadal widzą Pomiń/Anuluj plus „Kontynuuj na ”. Przycisk bez target przesyła swoje input jako wynik narzędzia. Przycisk z celem najpierw uruchamia ten cel, a następnie używa wyniku celu jako wyniku narzędzia.

Bogaty UI — osadź stronę hostowaną przez aplikację

Gdy wynik narzędzia jest wizualny lub interaktywny (ekran połączenia, wykres, pulpit nawigacyjny podsumowania), serwuj stronę z jednego z Twoich komponentów i zwróć jej bezwzględny adres URL jako embedUrl. Zbuduj adres URL z wstrzykniętego adresu URL komponentu — nigdy ścieżki względnej.
Strona uruchamia się w iframe o innym pochodzeniu (jej własne pochodzenie, ciasteczka i skrypty). Aby zmienić rozmiar karty, wyślij jej wysokość do rodzica — karta nasłuchuje tego i zmienia rozmiar (ograniczone do 70% okna przeglądarki):
Preferuj embedUrl zamiast emitowania ciągów HTML: Twoja aplikacja już serwuje strony, UI pozostaje interaktywny i wersjonowany z Twoim kodem, a żadne artefakty na wywołanie nie są zapisywane nigdzie.