关于 react-native
react-native 是一组连接 assistant-ui 运行时的原生原语与技能,用于通过 React Native 构建聊天界面。它结合原生界面组合和 AI SDK v7 运行时与传输,模型路由则运行在独立后端。
主要功能
- 01无样式 React Native 原语
- 02AI SDK v7 运行时与传输
- 03原生消息线程和撰写框组合
- 04转发前端工具架构
- 05本地持久化与会话适配器
- 06通过 Metro 支持生成式工具包
适用场景
- 01在 Expo 应用中构建聊天界面
- 02将原生应用连接到独立托管的模型路由
- 03组合原生消息列表与输入控件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ assistant-ui/ skills --skill react-native安装后在 Claude Code 中输入/react-native确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/adapters.mdcustom-backend.mdhooks.mdmigration.mdprimitives.md详细介绍
assistant-ui React Native
请始终查阅 assistant-ui.com/llms.txt,以获取最新 API。
@assistant-ui/react-native 提供与运行时连接、无样式的 React Native 基元。使用它们搭配 View、Text、Pressable、TextInput、FlatList 和原生样式来构建聊天界面。@assistant-ui/ai-sdk 提供 AI SDK v7 运行时和传输层。模型路由运行在单独的后端项目中,不会打包进 Expo 应用。
目录
参考资料
- ./references/primitives.md -- 原生基元命名空间及其组成部分
- ./references/hooks.md -- 状态、运行时、工具和作用域提供程序钩子
- ./references/adapters.md -- 本地持久化、附件和远程会话列表
- ./references/custom-backend.md -- 流式模型适配器和由后端管理的会话列表
- ./references/migration.md -- 将 Web 运行时迁移到原生 UI 层
快速开始
从维护中的 Expo 示例开始:
npx assistant-ui@latest create --example with-expo my-app
cd my-app
设置应用可以访问的端点。它必须是绝对 URL。实体设备无法将自己的 localhost 解析到开发服务器。
EXPO_PUBLIC_CHAT_ENDPOINT_URL="https://api.example.com/api/chat"
启动 Expo:
npx expo start
手动设置
在现有 Expo 应用中安装原生运行时及其 AI SDK v7 对等依赖包:
npx expo install @assistant-ui/react-native @assistant-ui/ai-sdk ai@^7 @ai-sdk/react@^4
在单独的位置托管模型路由。原生应用通过 AssistantChatTransport 将 UI 消息发送到该路由;路由会异步将其转换为 AI SDK v7 格式,并返回 UI 消息流。
import { openai } from "@ai-sdk/openai";
import { convertToModelMessages, streamText } from "ai";
export async function POST(request: Request) {
const { messages } = await request.json();
const result = streamText({
model: openai("gpt-5.6-luna"),
messages: await convertToModelMessages(messages),
});
return result.toUIMessageStreamResponse();
}
在钩子中创建运行时。将端点放在 Expo 公共环境变量中,以便编译后的应用能够访问它。
import {
AssistantChatTransport,
useChatRuntime,
} from "@assistant-ui/ai-sdk";
const chatEndpoint = process.env.EXPO_PUBLIC_CHAT_ENDPOINT_URL;
export function useAppRuntime() {
if (!chatEndpoint) {
throw new Error("EXPO_PUBLIC_CHAT_ENDPOINT_URL is required");
}
return useChatRuntime({
transport: new AssistantChatTransport({ api: chatEndpoint }),
});
}
AssistantChatTransport 会转发前端工具架构和系统消息。当后端启用前端工具时,请使用 @assistant-ui/ai-sdk 中的 frontendTools 来处理请求工具;共享的后端契约请参阅 tools。
原生聊天组合
将运行时置于原生 AssistantRuntimeProvider 下方,然后使用基元组合会话和输入框。ThreadPrimitive.MessagesFlatList 是当前的列表基元,并会将每一行限定到对应的消息作用域。
import {
AssistantRuntimeProvider,
AuiIf,
ComposerPrimitive,
MessagePrimitive,
ThreadPrimitive,
useAuiState,
} from "@assistant-ui/react-native";
import { Text, View } from "react-native";
import { useAppRuntime } from "./use-app-runtime";
function MessageRow() {
const role = useAuiState((s) => s.message.role);
return (
<View
style={{
alignSelf: role === "user" ? "flex-end" : "flex-start",
backgroundColor: role === "user" ? "#007aff" : "#f0f0f0",
borderRadius: 16,
margin: 8,
padding: 12,
}}
>
<MessagePrimitive.Content />
</View>
);
}
function Composer() {
return (
<ComposerPrimitive.Root style={{ flexDirection: "row", gap: 8, padding: 12 }}>
<ComposerPrimitive.Input
multiline
placeholder="Message..."
style={{ borderWidth: 1, borderRadius: 20, flex: 1, padding: 10 }}
/>
<ComposerPrimitive.Send>
<Text>Send</Text>
</ComposerPrimitive.Send>
</ComposerPrimitive.Root>
);
}
function ChatScreen() {
return (
<ThreadPrimitive.Root style={{ flex: 1 }}>
<AuiIf condition={(s) => s.thread.isEmpty}>
<Text style={{ padding: 16 }}>Send a message to begin.</Text>
</AuiIf>
<ThreadPrimitive.MessagesFlatList autoScroll>
{() => <MessageRow />}
</ThreadPrimitive.MessagesFlatList>
<Composer />
</ThreadPrimitive.Root>
);
}
export default function App() {
const runtime = useAppRuntime();
return (
<AssistantRuntimeProvider runtime={runtime}>
<ChatScreen />
</AssistantRuntimeProvider>
);
}
MessagePrimitive.Content 默认使用原生 Text 来显示文本部分,而非 Markdown。模型返回 Markdown 时,请传入 renderText,或使用 MessagePrimitive.Parts 搭配 React Native Markdown 渲染器。处理原生键盘时,将会话放在 KeyboardAvoidingView 中,并根据平台进行调整。
在基元作用域内使用 useAuiState 获取响应式值。无参数调用 useAui() 可执行 aui.composer.send() 和 aui.thread.cancelRun() 等命令式操作。选择器应使用基元或稳定引用,不要在选择器中构造对象或数组。
生成式工具包
Metro 必须能够编译以 "use generative" 开头的文件。安装 @assistant-ui/metro 并用它包装默认配置。Expo 从 expo/metro-config 获取 getDefaultConfig;裸 React Native 应用则从 @react-native/metro-config 获取。
const { getDefaultConfig } = require("expo/metro-config");
const { withAui } = require("@assistant-ui/metro");
module.exports = withAui(getDefaultConfig(__dirname));
对于无后端工具包,请通过包装器传入 aui 选项,以确保前端和人工工具架构仍可上传:
module.exports = withAui({
...getDefaultConfig(__dirname),
aui: { backendless: true },
});
使用 @assistant-ui/react-native 编写工具包,并包含原生 View 和 Text 渲染器。"use generative" 指令会使编译器根据 execute 推断工具类型。tools 技能介绍后端、前端、人工、提供方、外部和存根工具的语义。
常见问题
移动应用向 /api/chat 发送请求,却始终无法连接到服务端
- 原生应用没有可用于相对请求的浏览器来源。请将
EXPO_PUBLIC_CHAT_ENDPOINT_URL设置为完整的路由 URL。 - 请使用模拟器或实体设备可访问的主机。设备上的 localhost 指的是设备本身。
已挂载 Provider,但基础组件报错或不显示状态
- 使用
useChatRuntime或其他受支持的运行时 Hook 创建运行时,然后通过runtime={runtime}将其传递给AssistantRuntimeProvider。 - 在该 Provider 下方渲染基础组件。消息、消息部分、附件、队列、建议和会话列表项基础组件也需要对应的父级渲染作用域。
Web 版 Thread 或 Elements 导入项无法在 Expo 应用中渲染
- shadcn Elements 目录基于 DOM 和 Tailwind 构建。请使用
@assistant-ui/react-native基础组件和 React Native 样式构建原生 UI。
消息列表无法保持在底部
- 新界面请使用带有
autoScroll的ThreadPrimitive.MessagesFlatList。ThreadPrimitive.Messages为兼容性保留,其自动滚动选项默认为 false。
工具包被编译为普通模块,或工具架构从未传递给模型
- 使用
"use generative"之前,请将withAui添加到Metro。 - 在服务端构建中导入相同的生成式模块。如果没有服务端构建,请设置
aui: { backendless: true }。
Markdown 显示为字面星号和代码围栏
MessagePrimitive.Content默认使用原生Text。请通过renderText提供原生 Markdown 渲染器。