mcpField
R
react-native

react-native

github.com/assistant-ui开发29983 次安装2 天前更新
代码仓库

关于 react-native

react-native 是一组连接 assistant-ui 运行时的原生原语与技能,用于通过 React Native 构建聊天界面。它结合原生界面组合和 AI SDK v7 运行时与传输,模型路由则运行在独立后端。

主要功能

  1. 01无样式 React Native 原语
  2. 02AI SDK v7 运行时与传输
  3. 03原生消息线程和撰写框组合
  4. 04转发前端工具架构
  5. 05本地持久化与会话适配器
  6. 06通过 Metro 支持生成式工具包

适用场景

  1. 01在 Expo 应用中构建聊天界面
  2. 02将原生应用连接到独立托管的模型路由
  3. 03组合原生消息列表与输入控件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/assistant-ui/skills --skill react-native

安装后在 Claude Code 中输入/react-native确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
adapters.md
custom-backend.md
hooks.md
migration.md
primitives.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 应用。

目录

参考资料

快速开始

从维护中的 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 渲染器。

相关技能

  • 配置 -- 创建、初始化和配置 assistant-ui Web 项目
  • 基础组件 -- 用于 Web 应用的 DOM 基础组件,不适用于 React Native UI
  • 运行时 -- 与原生端共享的运行时行为和后端传输概念
  • 工具 -- 生成式工具包、其后端路由和自定义工具 UI

评论

支持 Markdown