@ chai- ui/ 核心
Chai UI组件背后的无头核心: 数据类型 :
请求 + 运行 + 结果模式 提交即时流经和
可插接的生成引擎,实际调用模型,组件'
行为为小型框架免费商店. 没有框架, 没有渲染 :
@chai-ui/react 用钩子把商店包起来,然后 @chai-ui/vue 财务报告和审定财务报表
@chai-ui/svelte 包装同样的商店.
版式
types.ts共享类型:MediaKind, (中文(简体) ),DroppedMedia, (中文(简体) ),ModelOption, (中文(简体) ),Usage, (中文(简体) ),GenerationUseCase。 。 。 .run.ts—— 说Request编号 :Run编号 :Result再加上纯洁的过渡createRun, (中文(简体) ),startResult, (中文(简体) ),resolveResult, (中文(简体) ),failResult, (中文(简体) ),deriveGenerationUseCase) (中文(简体) ).engine.ts- 那个GenerationEngine接口每个提供者工具,GenerationError,以及mockEngine编号 :createMockEngine(占位符输出,没有网络呼叫,没有API密钥).engines/fal.ts—— 说createFalEngine,通过 Fal.ai (默认) 生成媒体.engines/openrouter.ts—— 说createOpenRouterEngine,文本/通过OpenRouter进行解释(即时增强,媒体分析).engines/vercel.ts—— 说createVercelEngine,通过Vercel AI Gateway的文本和图像模型.media-analysis-prompts.ts—— 指令文本MediaAnalyzer发送, 每个媒体类型 × 快速长度 .suggested-models.ts建议的模型列出每个使用案例(Fal for generation,OpenRouter for analysis),每个模型都有经核实的侧面比和Fal输入格式;suggestedModels(useCase)。 。 。 .check-suggested-models.ts—— 说checkSuggestedModels():检查这些列表与Fal's和OpenRouter今天的目录。 没有钥匙,没有模型运行.model-routing.ts自动选择:buildModelRoutingPrompt, (中文(简体) ),parseModelRoutingReply,以及routeModel,这回落到第一个上市模型,而不是扔.reasoning.ts推理引擎和模型 aChaiProvider共享 :createReasoning, (中文(简体) ),pickReasoning, (中文(简体) ),reasoningModelFor和所建议的缺省.composer.ts—— 说createComposerStore,怎样useComposer包:提交有效载荷 + 运行、自动选择路由、增强(buildEnhancePrompt,其默认指令),取消,图像编辑版本和评价法官. 加作曲家的共享类型( E)ComposerSubmitPayload, (中文(简体) ),EditVersion(中文(简体) ).composer-view.ts- 什么情况Composer显示和提交,从其道具中制定,用于每个绑定:模型菜单、方格比、用例规则(nextUseCases) (中文(简体) ).analytics-events.ts前端分析:ChaiEvent类型和composerEvents, (中文(简体) ),resultCardEvents, (中文(简体) ),sidePanelEvents, (中文(简体) ),mediaAnalyzerEvents财务报告和审定财务报表editCardEvents报告各组成部分onEvent。 。 。 .evaluation-judge.ts选入法官:EvaluationCheck, (中文(简体) ),DEFAULT_EVALUATION_CHECKS, (中文(简体) ),buildJudgePrompt, (中文(简体) ),parseJudgeReply。 。 。 .image-fit.ts—— 说fitImageToRatio: 收成或贴上视频的起始图像与所选比例(startImageFit) (中文(简体) ).region-edit.ts区域编辑:区域形状、将区域读作方框的模型,以及buildRegionEditPrompt。 。 。 .edit-card.ts—— 说EditCard'几何:区域框,缩放和平板,以及指示字段去的地方.side-panel.ts—— 说SidePanel'行为 :readPageContext(该页面的标题、URL、选择和正文),buildSidePanelPrompt(有页面和最近转弯的提问),和线性帮助.voice-input.ts——作曲家的语音输入:收录,发送到语音对文本模型,还原笔录.result-format.ts- 怎么样ResultCard显示结果的细节.media-actions.ts——下载并共享生成的媒体.menu-placement.ts——如何打开组件的菜单从触发器中打开.media-analyzer.ts—— 说createMediaAnalyzerStore,怎样useMediaAnalyzer包装.server/—— 说createChaiHandler(单位:千美元)chai-handler.ts和toNodeHandler(单位:千美元)node.ts从@chai-ui/core/server(仅服务器).
建议的模式,并检查它们
组件在下列时间从建议的清单中填入其示范菜单:
建设者没有通过(见 @chai-ui/react读取。 里面每个法尔模型
携带 falInput,从它的Fal schema中读取:图像的去向
(单位:千美元)image_url, (中文(简体) ), image_urls 或者说 start_image_url)和纵宽比如何
发送( e)aspect_ratio,或名称 image_size) (中文(简体) ). buildFalRequestBody
使用它; 对于列表以外的模型, 它回到猜测中
编号.
列表仅通过软件包发布来更改. checkSuggestedModels()
从浏览器或节点将它们与供应商进行比较
无密钥 :
const { ok, checked, problems } = await checkSuggestedModels();
它报告一个模型已经消失 或不再活动, 一个Fal模型,没有
更长的长度需要宽比或图像字段 Chai发送或现在需要
chai不发送, 和一个OpenRouter模型 不再接受它
媒体。 Fal的目录每页读取10个模型(api.fal.ai/v1/models, (中文(简体) ),
OpenRouter的从 openrouter.ai/api/v1/models。 。 。 .
服务器路径 : @chai-ui/core/server
内置引擎从未持有过API密钥. 他们给你的一条路线打电话
服务器, /api/chai/*,以及 createChaiHandler 为它服务:它添加了钥匙
并向Fal.ai、OpenRouter或Vercel AI Gateway转发请求,
流经反馈.
// Next.js: app/api/chai/[...path]/route.ts
import { createChaiHandler } from "@chai-ui/core/server";
export const { GET, POST, PUT } = createChaiHandler();
设定 FAL_KEY, (中文(简体) ), OPENROUTER_API_KEY 或者说 AI_GATEWAY_API_KEY 在服务器中
环境(从不包含 VITE_ 或者说 NEXT_PUBLIC_ 前缀). 在韦尔塞尔,
VERCEL_OIDC_TOKEN 是为你们而设的,是代替门户钥匙的。 缺了一把钥匙就回来了
清晰出错,例如"FAL KEY没有设置在服务器上"
所行之处. 路由生活在您的应用框架( React, Vue 或 Svelte) 中
或者在背后的API服务器上 装入
/api/chai,其中组件发送请求. handle(request)
使用标准网络 Request 返回 a Response· ; GET, (中文(简体) ), POST 财务报告和审定财务报表
PUT (Fal取消调用)功能相同. 当浏览器
断开, 提供者的电话也被中止 .
| 你的设置 | 添加这个 |
|---|---|
| Next.js (App路由器) (英语) | export const { GET, POST, PUT } = createChaiHandler(); 内 app/api/chai/[...path]/route.ts |
| 重混/ 反应路由器 | export const loader = ({ request }) => chai.handle(request); export const action = loader; 内 app/routes/api.chai.$.ts |
| 坚果 | export default defineEventHandler((event) => chai.handle(toWebRequest(event))); 内 server/api/chai/[...path].ts |
| 斯维尔特基特 | export const fallback = ({ request }) => chai.handle(request); 内 src/routes/api/chai/[...path]/+server.ts键入时(见 @chai-ui/svelte 读取) |
| 浩诺 | app.all("/api/chai/*", (c) => chai.handle(c.req.raw)) |
| 邦,德诺 | 路径 /api/chai/* 改为 chai.handle 内 Bun.serve 编号 : Deno.serve |
| 云花岗工人 | createChaiHandler({ falKey: env.FAL_KEY, openRouterKey: env.OPENROUTER_API_KEY, aiGatewayKey: env.AI_GATEWAY_API_KEY }).handle(request) |
| 纯节点快车 | app.use("/api/chai", toNodeHandler(createChaiHandler())) |
上场前,限制谁可以使用路线及其运行. 没有这些,任何到达你网站的人都可以花你的API信用:
createChaiHandler({
authorize: async (request) => Boolean(await getSession(request)), // false → 403
allowedModels: ["fal-ai/flux/schnell", "anthropic/claude-opus-5"], // anything else → 403
});
永远不要导入 @chai-ui/core/server 从浏览器代码.
写入引擎
一种方法是: 迅速加上任何附着的介质, 一个输出回.
import type { GenerationEngine } from "@chai-ui/core";
const myEngine: GenerationEngine = {
async generate({ modelId, prompt, attachments }) {
// call your provider…
return { src: "https://…/output.png", kind: "image" };
},
};
扔一个 GenerationError(message, reasons?) 无法拨打
用户界面内容而不是赤裸的网络错误。 API 密钥永远不会
属于引擎: 调用添加密钥的服务器路由, 如
createChaiHandler 见上文.
没有服务器路由
桌面应用程序( Tauri, Electron) 没有内置服务器路由 引擎呼叫,他们的 CSP 通常限制连接-src 到应用 自己来 柴不运出桌面引擎:写你自己的手 运行到您的应用程序的后端( Tauri 命令, 或本地守护进程), 即 拿着钥匙,叫模特儿 在陶里语:
// src/lib/desktop-engine.ts: one run per call, through your app's backend.
import { invoke } from "@tauri-apps/api/core";
import type { GenerationEngine, MediaKind } from "@chai-ui/core";
export const desktopEngine: GenerationEngine = {
// signal and onText can't cross to the backend; every other field goes.
async generate({ signal, onText, ...run }) {
const result = await invoke<{ src: string; kind: MediaKind }>("chai_generate", run);
signal?.throwIfAborted();
return result;
},
};
通过它作为 useComposer是因为 engine,并给予同一引擎
ChaiProvider 作为 reasoningEngine: 增强、 自动选择、 文本请求、,
媒体分析 和法官 否则仍然调用服务器路线.
附件作为数据 URL 到达,所以后端得到整个文件. 这个
密钥从不到达网页视图, 不需要连接- 弧到
应用。 对于本地守护进程, 请求获取本地主机地址
并添加地址至连接-src.
语音输入同样有效: voiceInput={{ model }} 调用服务器
路径,所以通过自己的 Transcribe 转而将录音记录为
一个数据 URL并返回文本 :
import type { Transcribe } from "@chai-ui/core";
const transcribe: Transcribe = (clip) => invoke<string>("chai_transcribe", { clip });
// voiceInput={{ transcribe }}
别说了. 结果立即被取消,以及 throwIfAborted() 保持一个
但后端运行会持续进行
计费 要结束它,就给后端一个取消命令,然后叫它
从信号的中止事件.