도구
도구는 AI가 호출할 수 있는 명명된 작업으로, 타입이 지정된 입력을 가집니다(예:send_email(to, subject, body)). 도구는 스킬의 tools.ts에서 선언되며, 앱이 제공하는 도구의 경우 컴포넌트 중 하나의 HTTP 경로로 지원됩니다. 이 페이지는 도구 계약의 정보 소스입니다. 스킬에서 tools.ts가 어디에 있는지 다룹니다.
도구 선언
tools.ts의 각 항목에는 공급자 안전 name, 친화적인 displayName, description, Zod input 스키마, 그리고 Kazzle이 호출하는 대상을 나타내는 target이 있습니다.
대상
target은 도구 또는 필수 작업 버튼의 재사용 가능한 주소입니다. 직접 AI 도구 호출과 버튼 클릭이 동일한 대상 객체를 사용할 수 있으므로 둘 다 동일한 코드를 실행합니다.
HTTP 대상은 동일한 요청 필드를 사용합니다:
body: '${input}'을 작성하세요.
참조
Kazzle은 디스패치 전에 HTTP 대상query, headers, body, url 필드의 참조를 확인합니다:
${input}— 전체 도구 입력 또는 전체 버튼 입력입니다.${input.path}— 입력의 중첩된 값입니다.${env.NAME}— 소유 앱 컴포넌트의 선언된env.collection+env.environment의 명명된 환경 변수입니다.
${input.name} 텍스트가 필요할 때는 $${input.name}을 사용하세요.
핸들러 요청
app 대상의 경우 대상 컴포넌트에 일치하는 경로를 추가하세요. body: '${input}'을 사용하면 Kazzle은 타입이 지정된 입력을 JSON 본문으로 전송합니다:
app 대상은 또한 다음을 수신합니다:
앱 대상은
headers를 통해 Authorization을 설정할 수 없습니다. Kazzle이 해당 헤더를 소유합니다. 핸들러가 스레드 대 도구 API를 분기해야 할 때 @kazzle/app/tools의 toolContext(req)로 컨텍스트를 읽으세요.
일치하는 경로가 없는 도구는 유용한 작업을 수행하지 않습니다. 둘 다 함께 추가하세요. tools.json은 지원되지 않습니다. 앱 컴파일러가 하나를 찾으면 실패합니다.
핸들러 응답
일반 텍스트 또는 최대 3개 채널이 있는 JSON을 반환합니다:content— AI가 읽는 일반 결과(모델에 제공됨). 필수입니다.markdown— 선택적입니다. 도구 카드에 렌더링되는 짧은 리치 텍스트 요약(react-markdown; 원본 HTML은 이스케이프됨). 문장, 작은 목록, 인라인 링크에 좋습니다. 베어 상대 경로는 죽은 사전 형식 텍스트로 렌더링됩니다. 링크는 절대여야 합니다.embedUrl— 선택적입니다. 앱이 제공하는 절대 URL입니다. 카드는 이를 샌드박스 iframe에 렌더링합니다. 이것이 실제 전체 너비 UI(연결 화면, 대시보드, 차트)를 표시하는 방법입니다. 앱이 페이지를 호스팅하고 소유하므로 자신의 백엔드, 쿠키, OAuth에 대해 완전히 대화형일 수 있습니다. 드라이브에 아무것도 기록되지 않습니다.
embedUrl이 markdown을 이깁니다. 항상 의미 있는 content를 유지하세요. 그것이 AI가 읽는 것입니다.
필수 작업
앱 도구는 사용자(또는 장치) 작업이 필요할 때 스레드를 일시 중지할 수 있습니다. 카드 제목과 버튼이 있는type: 'action_required'를 반환합니다. toolContext(req).source === 'thread'일 때만 유효합니다. 도구 API(source: 'api')를 통해 일반 도메인 오류를 대신 반환하세요.
/chat/resume을 통해 재개합니다. 일치하는 클라이언트는 작성자 버튼을 봅니다. 일치하지 않는 클라이언트는 여전히 건너뛰기/취소 및 “에서 계속”을 봅니다. target 없는 버튼은 input을 도구 결과로 제출합니다. target이 있는 버튼은 먼저 해당 대상을 실행한 다음 대상 결과를 도구 결과로 사용합니다.
리치 UI — 앱 호스팅 페이지 포함
도구의 결과가 시각적이거나 대화형(연결 화면, 차트, 요약 대시보드)일 때 컴포넌트 중 하나에서 페이지를 제공하고 절대 URL을embedUrl로 반환하세요. 주입된 컴포넌트 URL에서 URL을 빌드하세요. 상대 경로는 절대 사용하지 마세요.
embedUrl을 선호하세요. 앱이 이미 페이지를 제공하고 있으므로 UI는 대화형으로 유지되고 코드와 함께 버전이 지정되며 호출당 아티팩트가 어디에도 기록되지 않습니다.