Artifact
モデルが作成したものを表示する、AIチャットの横のパネルです。Webページ、SVG、ドキュメント、コードがリアルタイムでストリーミングされ、その後サンドボックス化されたプレビューに切り替わります。比較して復元できるバージョン、サイズを変更できる分割、スマートフォンでのボトムシートを備えています。
Webページ、ドキュメント、ファイルなど、モデルが残す価値のあるものを作ったとき、それはチャットの中ではなく、その横にあるべきです。Artifact Workspaceはチャットとパネルを並べて配置します。アーティファクトのストリーミングが始まるとパネルが自動で開き、チャットが場所を空けながらスライドインし、サイズ変更、全幅への展開、ドラッグで閉じることもできます。スマートフォンではボトムシートになり、カードをタップしたときだけ開くので、チャットを読む操作が中断されることはありません。
モデルが書いている間、パネルには新しい行に追従するハイライト付きのコードが表示され、上にスクロールするとJump to latestボタンが出ます。WebページとSVGは、書き込みが終わったときにプレビューへ切り替わり、ストリーミングの途中では切り替わらず、それまでは最後に完了したバージョンのプレビューを表示し続けます。ドキュメントはストリーミング中もMarkdownとして描画されます。プレビューはサイトにアクセスできないサンドボックス化されたiframeで動作し、新しいバージョンが読み込まれてから入れ替わるため白いちらつきがなく、実行時エラーはモデルに送り返せるFix itアクションとともに報告されます。
小さな変更でファイル全体は書き換えません。更新ではeditsを送信でき、それぞれがClaudeのアーティファクトのように、最後に完了したバージョンに順番に適用される検索と置換です。コードは画面に残ったまま各編集へスクロールし、削除された行は取り消し線が引かれて折りたたまれ、新しいテキストは緑の色合いでタイプされ、ファイルの残りは動きません。カードには変更数とともにEditingと表示されます。テキストが見つからない、または複数見つかった編集は、そのバージョンを失敗させ、どの編集がなぜ失敗したかを示すメッセージが表示され、最後に成功したバージョンが現在のまま残ります。局所的な変更にはedits、ファイルの大部分や構造が変わる場合は全体のcontentを使ってください。
すべての更新は新しいバージョンになります。ヘッダーには変更内容とともにバージョンが並び、Show changesはDiff Reviewと同じ差分ビューで、バージョンを1つ前のものと行ごとに比較します。古いバージョンは何も削除せずに復元できます。トグルの横とカードに表示される追加数と削除数は、差分に表示される行です。新しいバージョンは常に前面に来ます。チャット内のカードはそのメッセージが作成したバージョンを示すので、古いカードをクリックするとそのバージョンが開きます。getArtifactsFromMessagesは、これらすべてをAI SDKのツール呼び出しから構築し、パネル、コードビュー、プレビューは単独でも使えます。
Proレジストリをcomponents.jsonに追加する
components.json トークンを追加する
アカウントページでトークンを作成し、
.env.localにHEXTAUI_PRO_TOKENとして設定してください。ブロックを追加する
pnpm dlx shadcn@latest add @hextaui-pro/artifact
AI SDKと使う
getArtifactsFromMessagesは、useChatのcreate_artifactとupdate_artifactのツール呼び出しを、バージョン付きのアーティファクトに変換します。各呼び出しが現れる場所にArtifactCardを置き、完了したupdate呼び出しをsetMessagesで追加して復元します。update_artifactはブラウザーで実行されるため、applyEditsは編集が一致しなかったときにモデルへ伝え、モデルが再試行できます。
サーバー上のツール
ツールは2つで十分です。1つは安定したidを持つアーティファクトを作成し、もう1つはそれを変更します。変更は、小さな変更向けの検索と置換のペアであるedits、または書き換え向けの全体のcontentのいずれかです。どちらもツール入力としてストリーミングされるため、モデルが書いている間にパネルが埋まり、または編集がその場でタイプされます。
単独のパネル
共有ページなどで、チャットなしで保存済みのアーティファクトを表示します。パネルは独自にバージョン、タブ、比較の状態を保持します。
構造
外側から内側へ組み合わせるパーツ。
| パーツ | 説明 |
|---|---|
ArtifactWorkspace | レイアウト。チャットを子要素として配置し、広い画面ではその横に、狭い画面ではボトムシートにパネルを置きます。何を開くかを決め、新しいアーティファクトを開き、進捗を通知します。 |
ArtifactCard | アーティファクト、またはそのバージョンの1つを開くメッセージ内のカードで、書き込み中、失敗、開いている状態を表示します。 |
ArtifactPanel | タイトル、バージョン、タブ、アクションを備えたヘッダーと、その下のコード、変更、プレビュー、ドキュメント。 |
ArtifactCode, ArtifactPreview | ストリーミングされるコードと差分のビュー、およびエラーカードを備えたサンドボックス化されたプレビュー。 |
getArtifactsFromMessages, applyEdits | AI SDKのメッセージから作成と更新のツール呼び出しを読み取り、バージョン付きのアーティファクトを返します。applyEditsは同じ方法で検索と置換の編集を適用するため、モデルに成功したと伝える前に編集を確認できます。 |
useArtifactWorkspace | サイドバーのファイル一覧など、独自のコントロールからアーティファクトを開閉します。 |
| プロパティ | 型 | デフォルト |
|---|---|---|
artifacts会話内のすべてのアーティファクトを、順番に。通常は getArtifactsFromMessages(messages) です。 | Artifact[] | – |
childrenチャット。通常はChatThreadです。 | ReactNode | – |
openId制御する場合に開いているアーティファクト。artifactsにないidは閉じているものとして扱われます。 | string | null | – |
defaultOpenId非制御の場合に、最初に開いているアーティファクト。 | string | null | null |
onOpenChangeアーティファクトが開いたとき、またはパネルが閉じたときに呼ばれます。 | (id: string | null) => void | – |
autoOpenバージョンのストリーミングが始まったとき、広い画面でアーティファクトを開きます。バージョンごとに一度だけ開き、そのストリーム中に閉じた場合は再び開かず、フォーカスも動かしません。 | boolean | true |
defaultPanelSize開いたときにパネルが占める幅の割合(パーセント)。チャットは最低320px、パネルは最低360pxを保ちます。区切り線をドラッグした場合は、そのセッションの間ドラッグした幅が優先されます。 | number | 70 |
onRestore古いバージョンにRestoreを表示します。古い内容を新しいバージョンとして追加し、何も削除しません。 | (artifact, version) => void | – |
onFixプレビューがエラーを投げたときに、Fix itを表示します。errorはmessageとlineを持ちます。 | (artifact, version, error) => void | – |
actionsPublishやShareなどの、追加のヘッダーコントロール。 | (artifact) => ReactNode | – |
| プロパティ | 型 | デフォルト |
|---|---|---|
artifactId開くアーティファクト。存在しない場合は何も描画しません。 | string | – |
versionIdこのカードが表すバージョン。通常はツール呼び出しのidです。クリックするとそのバージョンが開き、カードにはどのバージョンかが表示されます。 | string | – |
ArtifactPanel
ArtifactWorkspaceの内部で描画されます。チャットなしでアーティファクトを表示するには、直接使用してください。
| プロパティ | 型 | デフォルト |
|---|---|---|
artifact表示する内容。 | Artifact | – |
versionId制御する場合に表示するバージョン。nullは最新バージョンに追従します。 | string | null | – |
onVersionChangeバージョンが選ばれたときに呼ばれます。最新の場合はnullが渡されます。 | (versionId: string | null) => void | – |
onClose閉じるボタンを表示し、Escapeで閉じます。 | () => void | – |
fullscreen, onFullscreenChangeExpandとShow chatを表示し、Escapeで展開モードを終了します。 | boolean, (fullscreen: boolean) => void | – |
onRestore, onFix, actionsワークスペースと同じです。 | see ArtifactWorkspace | – |
Artifact
コンポーネントが読み取るデータ。
| プロパティ | 型 | デフォルト |
|---|---|---|
id, title安定したidと、ヘッダーとカードに表示されるタイトル。 | string | – |
kindhtmlとsvgにはサンドボックス化されたプレビュー、markdownにはドキュメントとしての描画、codeにはコードのみの表示が使われます。 | "html" | "svg" | "markdown" | "code" | – |
language, filenameコードのハイライトとダウンロード名。 | string | – |
versions古いものが先頭です。statusはstreaming、complete、stopped、errorのいずれかで、noteは変更内容を示します。editsは、ターゲットを絞った更新で適用された検索と置換のペアを列挙し、contentは常に完全な結果です。 | { id, content, status?, error?, note?, edits?, createdAt?, messageId? }[] | – |
| プロパティ | 型 | デフォルト |
|---|---|---|
messagesuseChatのメッセージ。create_artifactとupdate_artifact、またはそのキャメルケース形式の名前のツール呼び出しが、バージョンになります。 | UIMessage[] | – |
options.streaming最後のメッセージがまだ届いている途中かどうか。指定しない場合、未完了の呼び出しは停止したものとして扱われます。 | boolean | false |
options.tools独自のツール名。Createはid、title、kind、language、filename、description、contentを読み取ります。Updateはid、description、およびcontentまたはeditsのいずれかを読み取ります。 | { create: string[]; update: string[] } | – |
update inputcontentはアーティファクトを書き換えます。editsは最後に完了したバージョンに順番に適用され、各findは必ず1回だけ一致する必要があり、そうでなければそのバージョンはどの編集がなぜ失敗したかを示すerrorとともに失敗します。両方が送られた場合は、contentが優先されます。 | { content: string } | { edits: { find: string; replace: string }[] } | – |
| キー | アクション |
|---|---|
| Enter | カードでは、そのアーティファクトを開き、フォーカスをパネルのタイトルに移します。開いているカードでは、閉じます。 |
| Esc | 展開モードを終了し、パネルを閉じて、フォーカスをカードに戻します。 |
| ←→ | 区切り線にフォーカスがある間、分割のサイズを変更します。最小サイズを超えると、パネルが閉じるか、チャットが非表示になります。 |
| ←→ | タブにフォーカスがある間、CodeとPreviewを切り替えます。 |
| Tab | ヘッダー、矢印キーでスクロールするコードまたはドキュメント領域、プレビューの順に移動します。 |
- パネルは、実際の見出しを持つラベル付きのリージョンです。カードから開くとフォーカスがその見出しに移り、閉じるとフォーカスがカードに戻ります。モデルの書き込み中に自動で開く場合はフォーカスを動かさないため、コンポーザーへの入力が中断されることはありません。
- カードはaria-pressedとaria-controlsを持つボタンで、アーティファクトが書き込み中か、失敗したか、停止したかを伝えます。1行ずつ読み上げる代わりに、書き込みの開始時とバージョンの準備完了時に、politeなステータスで通知します。
- プレビューのiframeには、アーティファクトにちなんだタイトルが付きます。実行時エラーは、メッセージと行番号つきのalertとして表示され、適用できなかった編集も同様です。変更は色で示されるだけでなく、追加と削除として読み上げられます。
- すべてのアイコンボタンにはラベルとツールチップがあります。開く、閉じる、展開する動作はスライドし、チャットは滑らかにリフローします。モーション軽減時は、レイアウトが短いフェードとともに即座に切り替わります。編集は、タイプされずにまとめてフェードインします。
使用技術
Artifact を構成する無料のHextaUIコンポーネントです。それぞれ単独でインストールできます。
コード
12 個のファイルを components/blocks/artifact に追加しました。