Artifact
O painel ao lado de um chat de IA que mostra o que o modelo criou. Páginas web, SVGs, documentos e código chegam em streaming ao vivo e depois passam para uma prévia isolada em sandbox, com versões que você pode comparar e restaurar, uma divisão redimensionável e um bottom sheet no celular.
Quando um modelo cria algo que vale guardar, como uma página web, um documento ou um arquivo, isso pertence ao lado do chat, e não dentro dele. O Artifact Workspace coloca seu chat e um painel lado a lado. O painel abre por conta própria quando um artifact começa a chegar em streaming, desliza para dentro enquanto o chat abre espaço e pode ser redimensionado, expandido para ocupar toda a largura ou arrastado para fechar. No celular, ele vira um bottom sheet que só abre quando você toca em um card, então a leitura do chat nunca é interrompida.
Enquanto o modelo escreve, o painel mostra código com realce que acompanha as novas linhas, com um botão Jump to latest se você rolar para cima. Páginas web e SVGs passam para a prévia quando a escrita termina, nunca no meio do streaming, e a prévia continua mostrando a última versão concluída até lá. Os documentos são renderizados como Markdown enquanto chegam. As prévias rodam em um iframe em sandbox, sem acesso ao seu site, só trocam depois que a nova versão carregou, sem flash branco, e relatam erros de runtime com uma ação Fix it que você pode enviar de volta ao modelo.
Pequenas mudanças não reescrevem o arquivo. Uma atualização pode enviar edits, cada uma um localizar e substituir aplicado em ordem à última versão concluída, como nos artifacts do Claude. O código permanece na tela e rola até cada edição, as linhas removidas são riscadas e se dobram, o texto novo é digitado com um tom verde e o resto do arquivo fica parado. O card diz Editing com o número de alterações. Uma edição cujo texto não é encontrado, ou é encontrado mais de uma vez, faz aquela versão falhar com uma mensagem dizendo qual edição e por quê, e a última versão boa continua sendo a atual. Use edits para mudanças locais e o content inteiro quando a maior parte do arquivo ou sua estrutura mudar.
Toda atualização é uma nova versão. O cabeçalho as lista com o que mudou, Show changes compara uma versão com a anterior linha a linha com a mesma visão de diff do Diff Review, e versões mais antigas podem ser restauradas sem excluir nada. As contagens de adicionadas e removidas ao lado do alternador e no card são as linhas que o diff mostra. Uma nova versão sempre vem para a frente. Os cards no chat mostram a versão que a mensagem criou, então clicar em um card antigo abre aquela versão. getArtifactsFromMessages monta tudo isso a partir de chamadas de ferramenta do AI SDK, e o painel, a visão de código e a prévia também funcionam isoladamente.
Adicione o registro Pro ao components.json
components.json Adicione seu token
Crie um token na sua página de conta e coloque-o em
.env.localcomoHEXTAUI_PRO_TOKEN.Adicione o bloco
pnpm dlx shadcn@latest add @hextaui-pro/artifact
Com o AI SDK
getArtifactsFromMessages transforma as chamadas de ferramenta create_artifact e update_artifact do useChat em artifacts com versões. Coloque um ArtifactCard onde cada chamada aparece e restaure adicionando uma chamada de atualização concluída com setMessages. update_artifact roda no navegador, então applyEdits pode avisar o modelo quando uma edição não correspondeu e ele pode tentar de novo.
As ferramentas no seu servidor
Duas ferramentas bastam: uma cria um artifact com um id estável, a outra o altera. Uma alteração é feita com edits, pares de localizar e substituir para mudanças pequenas, ou com o content inteiro para uma reescrita. Ambas chegam em streaming como entrada da ferramenta, então o painel se preenche, ou a edição é digitada no lugar, enquanto o modelo escreve.
Um painel isolado
Mostre um artifact salvo sem um chat, por exemplo em uma página de compartilhamento. O painel mantém sua própria versão, aba e estado de comparação.
Anatomia
As partes que você compõe, de fora para dentro.
| Parte | Descrição |
|---|---|
ArtifactWorkspace | O layout: seu chat como children, o painel ao lado em telas largas e em um bottom sheet em telas estreitas. Ele decide o que está aberto, abre novos artifacts e anuncia o progresso. |
ArtifactCard | O card em uma mensagem que abre um artifact, ou uma versão dele, e mostra quando ele está sendo escrito, falhou ou está aberto. |
ArtifactPanel | O cabeçalho com título, versões, abas e ações, e o código, as mudanças, a prévia ou o documento abaixo dele. |
ArtifactCode, ArtifactPreview | A visão de código e diff em streaming, e a prévia em sandbox com seu card de erro. |
getArtifactsFromMessages, applyEdits | Lê chamadas de ferramenta de criação e atualização de mensagens do AI SDK e retorna artifacts com suas versões. applyEdits aplica edições de localizar e substituir da mesma forma, para que você possa conferir uma edição antes de dizer ao modelo que funcionou. |
useArtifactWorkspace | Abre e fecha artifacts a partir dos seus próprios controles, por exemplo uma lista de arquivos em uma barra lateral. |
| Prop | Tipo | Padrão |
|---|---|---|
artifactsTodos os artifacts da conversa, em ordem. Geralmente getArtifactsFromMessages(messages). | Artifact[] | – |
childrenO chat, geralmente um ChatThread. | ReactNode | – |
openIdO artifact aberto, quando você o controla. Um id que não está em artifacts conta como fechado. | string | null | – |
defaultOpenIdO artifact aberto inicialmente, quando não controlado. | string | null | null |
onOpenChangeChamado quando um artifact é aberto ou o painel é fechado. | (id: string | null) => void | – |
autoOpenAbre um artifact em telas largas quando uma versão começa a chegar em streaming. Abre uma vez por versão, nunca depois que você o fecha durante aquele streaming, e nunca move o foco. | boolean | true |
defaultPanelSizeA parcela da largura que o painel ocupa ao abrir, em porcentagem. O chat mantém pelo menos 320px e o painel pelo menos 360px. Arrastar o divisor prevalece pelo resto da sessão. | number | 70 |
onRestoreMostra Restore nas versões mais antigas. Adiciona o conteúdo antigo como uma nova versão; nada é excluído. | (artifact, version) => void | – |
onFixMostra Fix it quando a prévia lança um erro. error tem message e line. | (artifact, version, error) => void | – |
actionsControles extras no cabeçalho, como Publish ou Share. | (artifact) => ReactNode | – |
| Prop | Tipo | Padrão |
|---|---|---|
artifactIdO artifact a abrir. Não renderiza nada se ele não existir. | string | – |
versionIdA versão que este card representa, geralmente o id da chamada de ferramenta. Clicar abre essa versão, e o card diz qual versão ela é. | string | – |
ArtifactPanel
Renderizado para você dentro do ArtifactWorkspace. Use-o diretamente para mostrar um artifact sem um chat.
| Prop | Tipo | Padrão |
|---|---|---|
artifactO que mostrar. | Artifact | – |
versionIdA versão exibida, quando você a controla. null acompanha a versão mais recente. | string | null | – |
onVersionChangeChamado quando alguém escolhe uma versão, com null para a mais recente. | (versionId: string | null) => void | – |
onCloseMostra o botão de fechar e fecha com Escape. | () => void | – |
fullscreen, onFullscreenChangeMostra Expand e Show chat, e sai do modo expandido com Escape. | boolean, (fullscreen: boolean) => void | – |
onRestore, onFix, actionsO mesmo que no workspace. | see ArtifactWorkspace | – |
Artifact
Os dados que os componentes leem.
| Prop | Tipo | Padrão |
|---|---|---|
id, titleUm id estável e o título exibido no cabeçalho e no card. | string | – |
kindhtml e svg ganham uma prévia em sandbox, markdown é renderizado como documento, code mostra apenas código. | "html" | "svg" | "markdown" | "code" | – |
language, filenameRealce e o nome do download para código. | string | – |
versionsDo mais antigo ao mais recente. status é streaming, complete, stopped ou error; note diz o que mudou. edits lista os pares de localizar e substituir que uma atualização direcionada aplicou; content é sempre o resultado completo. | { id, content, status?, error?, note?, edits?, createdAt?, messageId? }[] | – |
| Prop | Tipo | Padrão |
|---|---|---|
messagesMensagens do useChat. Chamadas de ferramenta chamadas create_artifact e update_artifact, ou suas formas em camelCase, viram versões. | UIMessage[] | – |
options.streamingSe a última mensagem ainda está chegando. Sem isso, chamadas inacabadas contam como interrompidas. | boolean | false |
options.toolsOs nomes das suas próprias ferramentas. Create lê id, title, kind, language, filename, description e content. Update lê id, description e content ou edits. | { create: string[]; update: string[] } | – |
update inputcontent reescreve o artifact. edits são aplicadas em ordem à última versão concluída; cada find deve corresponder exatamente uma vez, ou a versão falha com error dizendo qual edição e por quê. Se ambos forem enviados, content prevalece. | { content: string } | { edits: { find: string; replace: string }[] } | – |
| Tecla | Ação |
|---|---|
| Enter | Em um card, abre o artifact e move o foco para o título do painel. Em um card aberto, fecha-o. |
| Esc | Sai do modo expandido, depois fecha o painel e devolve o foco ao card. |
| ←→ | Redimensiona a divisão enquanto o divisor tem o foco. Abaixo do menor tamanho, o painel fecha ou o chat se oculta. |
| ←→ | Alterna entre Code e Preview enquanto uma aba tem o foco. |
| Tab | Percorre o cabeçalho, a área de código ou documento, que rola com as setas do teclado, e a prévia. |
- O painel é uma região rotulada com um título de verdade. Abri-lo a partir de um card move o foco para esse título, e fechá-lo devolve o foco ao card. Abrir por conta própria enquanto o modelo escreve nunca move o foco, então a digitação no composer nunca é interrompida.
- Os cards são botões com aria-pressed e aria-controls, e informam se o artifact está sendo escrito, falhou ou foi interrompido. Um status polite anuncia quando a escrita começa e quando uma versão está pronta, em vez de ler cada linha.
- O iframe de prévia tem como título o nome do artifact. Erros de runtime aparecem como um alerta com a mensagem e a linha, e o mesmo vale para uma edição que não pôde ser aplicada. As mudanças são anunciadas como adicionadas e removidas, e não apenas mostradas em cor.
- Todo botão de ícone tem um rótulo e um tooltip. Abrir, fechar e expandir deslizam com o chat se reorganizando suavemente, e com movimento reduzido o layout muda de uma vez com um fade curto. As edições aparecem com fade por inteiro em vez de serem digitadas.
Construído com
Os componentes gratuitos do HextaUI de que Artifact é feito. Cada um é instalado separadamente.
Código
12 arquivos, adicionados a components/blocks/artifact.