@chai-ui/反应
Chai UI for React: 输入和输出表面的滴入组件 基因媒体应用. 这里的一切都被控制着——你拥有国家,这些组件 当它改变时告诉你.
用它来建还是用编码剂来指向它? 读取
DESIGN.md (包裹中)用于使用规则:
哪些部件要选取,哪些符号存在,内置的AI说明,以及
什么不能建设.
Chai的组件支持了WCAG 2.2 AA:用轴和自动测试
键盘和焦点检查,而不是手持屏幕读取器。 DESIGN.md 第6节
有细节。 焦点环默认可见,如WCAG所要求.
data-chai-focus-ring="hidden" 在祖先身上隐藏它们,用于预览或
仅显示表面. Composer是因为 promptLabel 命名提示字段
(违约:占位符),以及 ResultCard是因为 altText 设置图像备选案文
文本(默认:提示).
快速开始 : Composer
Composer 这是 bar-layout 输入表面:一个提示字段,一个附件
菜单,一个使用大小写芯片,模型/外观-鼠标拾取器,并提交-全部驱动
用来提供道具,而不是四个不同的组件.
import { useState } from "react";
import "@chai-ui/tokens/css";
import "@chai-ui/react/style.css";
import { Composer, type ComposerAttachment, type ComposerSubmitPayload } from "@chai-ui/react";
function App() {
const [value, setValue] = useState("");
const [attachments, setAttachments] = useState<ComposerAttachment[]>([]);
function handleSubmit(payload: ComposerSubmitPayload) {
// payload = { value, attachments, useCase, modelId, aspectRatio } —
// everything Composer tracks, assembled for you. Send it to whichever
// model/provider you've set up; Composer never calls one itself.
console.log(payload);
}
return (
<Composer
value={value}
onChange={setValue}
attachments={attachments}
onAttachmentsChange={setAttachments}
onSubmit={handleSubmit}
/>
);
}
这是最小的例——没有取模器,没有相比,没有附着 超过默认文件拾取器的能力。 所有其他控制都是添加剂:
<Composer
value={value}
onChange={setValue}
attachments={attachments}
onAttachmentsChange={setAttachments}
// A use-case chip + model/aspect-ratio pickers only appear once `useCase`
// is set — wire it from the attach menu's own picks, or set it yourself.
useCase={useCase}
onClearUseCase={() => setUseCase(null)}
onAttachMenuSelect={(action) => {
if (action === "create-image") setUseCase({ kind: "image", label: "Image" });
}}
// The Model menu lists Chai's suggested models for the use case, unless
// you pass your own `models` (see "Suggested models"). Nothing is picked
// for the person: submit waits until they pick a model or turn on
// auto-select. Without `onModelChange` there's no menu, and the list's
// first model runs.
modelId={modelId}
onModelChange={setModelId}
// An "Auto-select model" switch appears at the top of the model menu so
// the end user can flip it — omit `showAutoSelectToggle` to keep it a
// fixed, builder-only setting with no visible control instead.
autoSelectModel={autoSelectModel}
showAutoSelectToggle
onAutoSelectModelChange={setAutoSelectModel}
// The Aspect ratio menu offers what the selected models take. Suggested
// models carry their `aspectRatios`; give your own models theirs, e.g.
// ["1:1", "16:9", "9:16"]. A model without them (image-to-video follows
// the input image) shows no menu.
aspectRatio={aspectRatio}
onAspectRatioChange={setAspectRatio}
// Omit onEnhance entirely to hide the "optimize prompt" button — e.g.
// before you've wired an engine that can actually run the rewrite.
onEnhance={(currentValue) => runEnhance(currentValue).then(setValue)}
onSubmit={handleSubmit}
/>
完整的道具清单——包括: attachments'文件阅读行为,
onUnsupportedFile,以及 disabled编号 :submitDisabled - 记录为:
JSDoc直接打开 ComposerProps 内 src/Composer.tsx;每个道具和
事件随同发生 value编号 :onChange 其他形状
这个包裹.
见 Docs 站点上的作曲页面 一个有每个选入功能的活例.
无用大小写: 文本请求
无用选项的快捷键是文本请求
(单位:千美元)TEXT_USE_CASE:它得到文本回复,而不是什么都不做。 这是
如何使用作曲器作为 LLM 的简单聊天栏 :
- 型号:
useComposer寄给textEngine与textModel当你设置它们, 否则ChaiProvider'推理模式' (默认 Claude Opus 5 on OpenRouter). 没有ChaiProvider或一个textEngine,模拟文本引擎的答案,所以将您的应用程序包入<ChaiProvider>真实的答复. - 无模型菜单 : 建议的清单仅涵盖图像和视频,因此
文本请求没有显示模型菜单 。 提供文本模型的选择,通过
你们自己
models。 。 。 . - 回复流 输入
ResultCard正如它写,和cancel()停止它,保持已经到达的东西.
<ChaiProvider>
<Composer value={value} onChange={setValue} onSubmit={submit} submitting={busy} onAbort={cancel} />
{run && <ResultCard results={run.results} prompt={run.request.prompt} onAction={() => {}} />}
</ChaiProvider>
对于一个主要涉及图像的应用程序,设置默认值;它是 从来没有显示为芯片, 它带来了建议的图像模型和 光谱比菜单 :
<Composer defaultUseCase={{ kind: "image", label: "Image" }} … />
几种模式,几种使用案例(建设者选入,默认关闭)
// Several models: each produces its own result, paged inside one ResultCard.
<Composer multiSelectModels modelIds={modelIds} onModelIdsChange={setModelIds} models={models} … />
// Image and Video from one prompt (advanced): a Model menu per use case,
// one model each picked by hand (no auto-select), and submit waits for both. Only Image and Video combine;
// nextUseCases makes any other pick replace the rest.
<Composer
multiSelectUseCases
useCases={useCases}
onUseCasesChange={setUseCases}
onAttachMenuSelect={(action) => {
const picked = useCaseFor(action); // your mapping from menu item to use case
if (picked) setUseCases((prev) => nextUseCases(prev, picked));
}}
modelsByKind={{ image: imageModels, video: videoModels }}
modelIds={modelIds}
onModelIdsChange={setModelIds}
…
/>
不管怎样 onSubmit 接收 selections页:1 { useCase, modelIds, models }
输入每个使用例。 图像在几秒钟内到达 视频可以拍摄
分钟,所以显示每个用例 运行在自己的 ResultCard (单位:千美元)useComposer是因为
runs而不是把它们拼凑在一起.
与 autoSelectModel 打开( 不使用 multiSelectUseCases),触发器为"自动选择"并
useComposer 提交时选择模型: 推理模型读取
快速和介质 并选择从该用例 models当结束时
用户拥有开关( o)showAutoSelectToggle),自动选择属于
打开的大小写: 选择另一个大小写
onAutoSelectModelChange(false),所以新的一个的模型是用手挑选的。 过
onModelChange (或 onModelIdsChange) 也去钩上,所以触发器
显示选择 :
const { submit, routing } = useComposer({ engine, onModelChange: setModelId });
如果线路不能运行( 无) ChaiProvider,一个失败的推理电话,一个
在未列入清单的答复中,请求以第一个列入清单的模式进行
onRoutingFallback 说为什么.
附加图像和选中比例
附加图像不会改变模型菜单或隐藏外观比. 每个
建议的模型名称withImages页:1
Fal引擎在图像被附着时称它. 选择比例总是
胜利:图像模型直接取用,视频的起始图像被安装
在它被送到之前 默认地在它的中心或被加起来
黑条:
const { submit } = useComposer({ engine, startImageFit: "pad" }); // default "crop"
质量检查: evaluations
每个结果都可以携带通过或失败的标记,在结果卡的翻转上显示 边 他们来自两个地方, 你可以使用其中之一或两者:
- 您的后端 : 添加顶级
evaluations: [{ id, label, passed }]字段到 JSON 您的路由返回( 对于流, 发送为它自己的)data:块. Fal和OpenRouter引擎读取. - 选入法官: 您命名的模型检查每个文本或图像结果
根据你的标准,每个检查一个标记。 它运行在推理引擎上
(单位:千美元)
ChaiProvider) (中文(简体) ). 默认关闭,没有默认型号. 无judgeChecks它运行一个普通的"马奇斯快速"检查。 还算什么 好就看你的应用了.
const { submit } = useComposer({
engine,
judgeModel: "google/gemini-3.5-flash",
judgeChecks: [
// Your criteria, in your words. This one is an example for a marketing app's images.
{ id: "on-brand", label: "On brand", criterion: "Photographic and polished, never cartoonish.", kind: "image" },
...DEFAULT_EVALUATION_CHECKS,
],
});
法官的提示是 buildJudgePrompt (出口,所以你可以读取).
过 judgePrompt 替换它,呼叫 buildJudgePrompt 来增加它
而不是改写它.
分析: onEvent
每个组成部分都报告一个人所做的事和所看到的 ChaiEvent
每一个,无论你使用什么分析工具。 写出一个函数并传递
用于您使用的每个组件 :
import posthog from "posthog-js";
import type { ChaiEvent } from "@chai-ui/react";
const track = (e: ChaiEvent) => posthog.capture(e.name, e.properties);
<Composer onEvent={track} … />
<ResultCard onEvent={track} … />
<SidePanel onEvent={track} … />
<MediaAnalyzer onEvent={track} … />
<EditCard onEvent={track} … />
事件覆盖提交、停止、使用大小写、模型和选项选择、附件、, 增强、语音输入、显示结果(每次)、结果行动、呼喊、, 细节; 侧面板打开、关闭、 新建聊天、 提示 (按位置)及其页面芯片;媒体分析器的附着和去除, 模型、自动选择和及时取出长度、提交、停止和每项分析 完成( 处理或出错); 并添加、 确认和 删除,缩放,通过版本呼出,下载和分享. 移动和 重新调整区域大小没有报告。 仅是前端: 没有即时文本、文件名、 URL 或输出,只有长度,计数 和蔡自己的ID。 追踪模型呼叫, 你服务器的延迟和成本 准确无误.
酒吧坐的地方: menuPlacement
酒吧里的每张菜单 + 菜单,模型,相位比,语音,流派,
帧率)打开同样的方式. 告诉 Composer 酒吧停靠的地方:
<Composer menuPlacement="above" {...props} /> // docked to the bottom of the screen, like a chat app
<Composer menuPlacement="below" {...props} /> // docked to the top
别管了"auto"对于一个坐在页面上的栏:每个菜单是
当它打开和下行,如果它适合, 或者在上方,如果它适合,
所以它不会被边缘切断
屏幕.
您的字体
style.css 装入"机器人","材料设计"3的打字机. 如果你的应用有它
自定义字体, 导入 @chai-ui/react/style-without-fonts.css 改为:
相同的样式,没有Roboto),并将组件指向您的字体:
:root { --chai-type-family-material: "Your Font", system-ui, sans-serif; }
黑暗主题
组件有一个黑暗的主题。 选入: 设置 data-chai-theme="dark"
打开 <html>,或者在任何元素上,以及其中的每个组件开关.
<html data-chai-theme="dark">
柴不照系统设置,因为你的应用决定了
其主题。 随之而来,凌驾于单一的颜色和黑暗的价值观之上
他们自己在
@chai-ui/tokens 读取。 。 。 .
这个包裹还有什么
MediaAnalyzer- 投放图像、视频或音频剪辑并获得 生成准备后提示, 带有 kin- aware 模型菜单( 建议) OpenRouter模型,除非通过自己的模型)和快速取长器. 用电线useMediaAnalyzer(),它发送媒体 改为ChaiProvider逻辑模型并返回提示 :onSubmit={submit} submitting={analyzing} submitError={error}。 。 。 .ResultCard——让一个提示产生结果(图像,视频, 音频,或文本),带有类似/类似/重复/下载/共享,可配置 “更多”菜单、跨多个结果的页码,以及一个信息翻转显示 快速和模拟元数据。 现场实例 : chai-ui.com/docs/组件/结果卡。 。 。 .EditCard——通过在其上标出区域来编辑所附图像,每个区域 ,然后通过编辑作为版本。 见 下面"编辑一幅相".SidePanel在你的页面旁边有一个面板,有一个作曲家及其 答案,包含选择的页面上下文和提示。 见"侧面板" 见下文.- 初级 (单位:千美元)
src/primitives/(b) ——Toggle(MD3开关),SearchMenu(每个拾取者背后的模型/选项菜单——柴自来而非材料<md-menu>; DESIGN.md 第3节说原因),并Pagination(一个进步式的寻呼器,任何相接的表面都可以再利用). 这些部件是用这些部件建造的;如果 你正在整理自己的布局.
建议的模式
不用写模范名单. 柴船推荐名单,核对 对照每个提供者自己的目录,组件在您使用时 通过无 :
| 使用大小写 | 导出 | 提供者 |
|---|---|---|
| 创建图像 | SUGGESTED_IMAGE_MODELS | 法尔 |
| 从一个提示创建视频 | SUGGESTED_TEXT_TO_VIDEO_MODELS | 法尔 |
| 从图像创建视频 | SUGGESTED_IMAGE_TO_VIDEO_MODELS | 法尔 |
| 编辑图像 | SUGGESTED_EDIT_MODELS | 法尔 |
| 按媒体类型分列的媒体分析 | SUGGESTED_ANALYSIS_MODELS | 打开路透社 |
- 作曲家 为当前使用大小写提供列表
(单位:千美元)
suggestedModels(useCase)) (中文(简体) ). 它从不为人挑:用模型 菜单,提交等待选择或自动选择;没有菜单,列表的 第一型号运行. 媒体分析器 提供分析清单. - 你自己的名单赢了. 过
models(或modelsByKind改为: 列表,或[]没有模型菜单。 不需要任何东西. - 每个建议模式都了解其投入:其纵横比,Fal
其图像输入的字段(
falInput),所以法尔引擎发送准确的 那个模特儿期望的. - 它们只能通过包放出来改变. 供应商变化更快, 在安装引擎时检查一下 它不需要钥匙,运行不 模型和成本无:
import { checkSuggestedModels } from "@chai-ui/react";
const { ok, problems } = await checkSuggestedModels();
// problems: [{ provider: "fal", modelId, problem: "No longer takes these aspect_ratio values: 21:9." }]
它证实每个型号仍然存在 并且很活跃 仍然使用 大小比例和图像字段 Chai 发送( Fal), 并仍然接受其媒体 类型(开放路透)。 如果有什么变化,请另选一个模型或更新 一旦发行, 软件包就会追上.
useComposer 接线 Composer 到一个真正的引擎
import { ChaiProvider, useComposer, createFalEngine, Composer, ResultCard } from "@chai-ui/react";
// The reasoning models write text (Enhance, routing, text requests) and
// are separate from the media engine. With no props,
// Claude Opus 5 handles text and images, Gemini 3.8 Flash handles video
// and audio, both on `createOpenRouterEngine()`. Without a provider,
// Composer's Enhance button stays hidden.
function Root() {
return (
<ChaiProvider>
<App />
</ChaiProvider>
);
}
function App() {
const { run, runs, submit, cancel, enhance, enhancing } = useComposer({
engine: createFalEngine({ outputKind: "image" }),
});
// Every model's result from every use case, paged in one card.
const results = runs.flatMap((r) => r.results);
const busy = results.some((r) => r.status === "queued" || r.status === "running");
return (
<>
<Composer
value={value}
onChange={setValue}
onSubmit={submit}
submitting={busy}
onAbort={cancel}
onEnhance={enhance ? (v) => enhance(v).then(setValue) : undefined}
enhancing={enhancing}
// ...the rest of Composer's own props, as above
/>
{run && (
<ResultCard
results={results}
prompt={run.request.prompt}
onAction={(action, result) => {
// like / dislike / retry / download / share / your "more" actions
}}
/>
)}
</>
);
}
增强的指令是 buildEnhancePrompt (已导出,所以您可以读取)
) (中文(简体) ). 过 enhancePrompt 改为 useComposer 替换它,呼叫
buildEnhancePrompt 以增加而不是改写它:
useComposer({
engine,
enhancePrompt: (value, mode, field) => `${buildEnhancePrompt(value, mode, field)}\n\nKeep our brand's warm, natural style.`,
});
submit 带 Composer是因为 ComposerSubmitPayload 直接通过
直达 onSubmit。它把每个选择变成真实的
Request编号 :Run编号 :Result: 创建 "queued" Result 每个模型上升
前方,然后折叠每个 "running" → "done"编号 :"error" 作为
引擎解决它. run 是第一个 Run (或 null 第一次选举之前
提交; runs 每起使用案件一个 multiSelectUseCases 开始.
过 ResultCard 每次运行的结果,如上:
,每个页面都显示自己的类型(图像、视频、音频或文本).
仅通过 run.results 将隐藏每一个使用案例 在第一个之后.
服务器路线. createFalEngine(), (中文(简体) ), createVercelEngine() 编辑
OpenRouter 推理引擎调用 /api/chai/* 在您的服务器上, 添加
aPI 键。 加上一个文件, 然后设定 FAL_KEY, (中文(简体) ), OPENROUTER_API_KEY
或者说 AI_GATEWAY_API_KEY数字 :
// Next.js: app/api/chai/[...path]/route.ts
import { createChaiHandler } from "@chai-ui/core/server";
export const { GET, POST, PUT } = createChaiHandler();
其他框架和 authorize 编号 : allowedModels 要添加的设置
活着之前,在 @chai-ui/core 读取.
没有服务器路由. 在桌面应用程序( Tauri, Electron) 中写入一个
引擎,每个运行到你的应用程序的后端。 传过来
useComposer({ engine: desktopEngine }) 转至
<ChaiProvider reasoningEngine={desktopEngine}>编辑
@chai-ui/core 读取
有个Tauri的例子,语音输入,还有Stop在那里做什么.
每一次默认都是建议. 换掉其中任何一个:
<ChaiProvider
reasoningModel="your/text-and-image-model"
// Cheaper video and audio analysis; kinds you leave out keep their default.
reasoningModelByKind={{ video: "qwen/qwen3.8-omni-flash", audio: "qwen/qwen3.8-omni-flash" }}
reasoningEngine={yourEngine}
/>
默认导出为 DEFAULT_REASONING_MODEL 财务报告和审定财务报表
DEFAULT_REASONING_MODEL_BY_KIND。 。 。 .
useComposer属于自己的 reasoningEngine + 键 reasoningModel 覆盖
提供商的,但只有在两者都设定的时候。 文本请求到 textEngine
(默认:推理引擎,然后是模拟文本引擎),使用
textModel (默认: 推理模型) 当没有选择模型时. 其他种类去 engineByKind[kind],则 engine没有
模型被选中,引擎自身的默认模型运行.
别说了. cancel() 停止当前提交: 将其接入作曲家的
onAbort,与 submitting 在结果排队或运行时为真.
未完成成果转会 "cancelled" (证书显示“已停止”;a
流出文本结果保存到的文本),新提交将取消
前一个。 取消是提供者的最佳努力: Fal 删除 a
排队请求并信号运行中的请求,该请求可能仍然完成 ;
打开路透停止 a 流线 要求及其账单,仅用于
支持它的供应商( 不是 Google); 一个非流化请求保留
运行中。 自定义引擎收到 signal 内 generate(): 在
如果可以,则拒绝 AbortError (单位:千美元)abortError()) (中文(简体) ).
编辑图像 : EditCard
附加菜单中的“ 编辑图像 ” Composer 在编辑模式中。 设置使用大小写
改为 EDIT_IMAGE_USE_CASE,将所附图像传递给 useComposer 作为
editImage,然后将牌投出:
import { Composer, EditCard, EDIT_IMAGE_USE_CASE, SUGGESTED_EDIT_MODELS, useComposer } from "@chai-ui/react";
const editImage = useCase?.edit ? (attachments.find((a) => a.kind === "image") ?? null) : null;
const { run, submit, edit } = useComposer({ engine: createFalEngine({ outputKind: "image" }), editImage });
// The pick decides how many regions it takes (Flux 3 Image's until one is picked).
const model = SUGGESTED_EDIT_MODELS.find((m) => m.id === modelId) ?? SUGGESTED_EDIT_MODELS[0];
{edit && <EditCard {...edit} maxRegions={model?.maxRegions} />}
{!edit && run && <ResultCard results={run.results} prompt={run.request.prompt} onAction={…} />}
<Composer
// ...your other Composer props
useCase={useCase}
onAttachMenuSelect={(action) => {
if (action === "edit-image") setUseCase(EDIT_IMAGE_USE_CASE);
}}
regions={edit?.regions}
onRegionsChange={edit?.onRegionsChange}
onSubmit={submit}
/>
- 地区. "新区域"增加了一个带有指令字段的框. 检查
添加到快取( 作曲器中的彩色芯片); 垃圾会移除它 .
拖动、 拖动一角来调整大小; 通过键盘, 箭头移动和 Shift
- 箭头调整大小。 缩放将图像保存在卡片内; 拖到平板上 .
- 提交. 编辑需要图像加全图像提示, a 或两者兼有。 区域有他们自己的指示,所以迅速可以 保持空闲.
- 模特儿们. 在编辑模式下 作曲家要约
SUGGESTED_EDIT_MODELS: 通量 3 图片首先将每个区域读作"盒子",然后是"纳诺香蕉Pro"和"纳诺香蕉" GPT 图像 2. 提供您喜欢的任何编辑模式; 一个没有regionFormat用言语描述其区域,这不太准确。 改变方式 以useComposer是因为editPrompt。 。 。 . - 诸版本. 每次编辑的结果都是一个新版本,在卡片中显示 点来回呼. 下次编辑适用于显示的版本.
- 只有图像 现在.
侧面板: SidePanel
在您页面的一面贴有作曲者及其答案的面板,以快速 模式使用而不离开页面。 人们可以问起他们的页面 或关于其他的:
import { SidePanel } from "@chai-ui/react";
<div style={{ display: "flex" }}>
<main style={{ flex: 1 }}>{page}</main>
<SidePanel
title="Northwind Assistant"
description="Ask about this page, or anything else."
pageContext
promptTips={["Summarize this page", "What changed for free accounts?", "Draft a polite out-of-office reply"]}
/>
</div>
- 答复 从你的
ChaiProvider推理引擎, 或者通过textEngine(和textModel) (中文(简体) ). 没有模型菜单, 宽度比或 增强面板;语音输入在作曲机上有效(voiceInput) (中文(简体) ). - 页面上下文 默认关闭。 与
pageContext,面板读作 页面的标题、 URL、 所选文本和正文 (readPageContext数字 :<main>,则<article>,则<body>,上限为12,000个字符)和 每个问题都送来 "本页"芯片显示它已经打开 人可以把它取出 问别的东西, 并把它放回来+菜单。 传递一个函数而不是true以自己的方式阅读页面. 标出要留下的东西data-chai-page-context="skip"发送 一个页面的文本到一个模型 是你的决定 故意. - 提示提示: "开始"下2到4个短例
(单位:千美元)
promptTipsLabel一个水龙头发出一个。 包含至少一个不是 关于页面. - 版式数字 :
side="right"(违约)或"left"。 。 。 .mode="push"(默认) 以自己的宽度取出你的内容, 所以把它作为一个柔软的兄弟姐妹;mode="overlay"浮出一页.contained保存覆盖 处于其位置的父母。 宽于600px以下,均开放为a 全屏工作表.--chai-side-panel-width设置宽度( 400px) . - 开幕: 启动按钮打开; 关闭清除对话,
新的聊天开始而不关闭。 用它来控制它
open财务报告和审定财务报表onOpenChange设置launcher={false}用自己的按钮. 打开移动聚焦到提示, Esc 关闭面板( 打开后) ),然后关闭返回焦点到启动器. - 你的记号数字 :
logo替换发射器中的默认闪光 问候(44px)和头(28px),显示为给定(a)img或者说svg填入盒子),没有花花相间的绿瓦. - 后续行动 工作:最后6次交流与每个问题
(单位:千美元)
buildSidePanelPrompt) (中文(简体) ). - 答题样式数字 :
answers="simple"(默认)在面板上显示文本 像,不喜欢,重试和复制;"card"将每个答案放入 结果卡.footer在"作曲家"下增加一注,如"免责声明". - 分析数字 :
onEvent报告打开、关闭、新聊天、即时提示 (按位置)和页面芯片,加上作曲家和答案' 自己的活动.