BodhiJSSDKReact集成指南Skill bodhi-sdk-react-integration

本技能提供React+Vite应用程序与Bodhi JS SDK的完整集成方案,实现本地大语言模型聊天功能。包含OAuth身份验证、流式响应处理、GitHub Pages部署配置和故障排除指南。适用于前端开发者集成AI聊天功能、React应用添加LLM能力、Bodhi SDK连接配置等场景。关键词:React集成、Bodhi SDK、本地LLM、OAuth认证、流式聊天、GitHub Pages部署、前端AI应用、聊天机器人开发。

前端开发 0 次安装 0 次浏览 更新于 3/2/2026

name: bodhi-sdk-react-integration description: > 将React+Vite Web应用程序与bodhi-js-sdk集成,实现本地LLM集成。当用户要求时使用: “集成bodhi”、“添加bodhi sdk”、“连接到bodhi”、“设置bodhi提供程序”、 “bodhi react集成”、“将bodhi部署到GitHub Pages”,或解决bodhi-js-sdk连接/身份验证问题。 allowed-tools: Read, Grep, Glob, Edit, Write, Bash(npm:), Bash(npx:)

Bodhi JS SDK React集成

将React+Vite应用程序与bodhi-js-sdk集成的指南,通过Bodhi Browser生态系统启用本地LLM聊天功能。

何时使用此技能

  • 用户希望将React应用程序与bodhi-js-sdk集成
  • 用户需要向React+Vite应用程序添加聊天/LLM功能
  • 用户正在将bodhi集成应用程序部署到GitHub Pages
  • 用户正在解决SDK连接、身份验证或流式传输问题

快速集成清单

  1. 安装npm install @bodhiapp/bodhi-js-react
  2. 注册:在https://developer.getbodhi.app创建OAuth客户端
  3. 包装应用:在应用周围添加<BodhiProvider authClientId={...}>
  4. 使用Hook:访问useBodhi()获取客户端、身份验证状态和操作
  5. 构建UI:创建支持流式传输的聊天界面

核心概念

包架构

  • @bodhiapp/bodhi-js-react - Web应用程序的预设包(自动创建WebUIClient)
  • @bodhiapp/bodhi-js-react-ext - Chrome扩展程序的预设包(自动创建ExtUIClient)
  • 两者都包含React绑定+OpenAI兼容API

连接模式

  • 扩展模式:通过Bodhi Browser扩展(首选)
  • 直接模式:直接HTTP到本地服务器(备用)
  • SDK自动检测并切换模式

身份验证

  • OAuth 2.0 + PKCE流程
  • 两个身份验证服务器:
    • 开发https://main-id.getbodhi.app/realms/bodhi(允许localhost)
    • 生产https://id.getbodhi.app/realms/bodhi(需要真实域名)

基本集成步骤

步骤1:安装包

npm install @bodhiapp/bodhi-js-react

步骤2:使用BodhiProvider包装应用

// App.tsx
import { BodhiProvider } from '@bodhiapp/bodhi-js-react';
import Chat from './Chat';

const CLIENT_ID = 'your-client-id-from-developer.getbodhi.app';

function App() {
  return (
    <BodhiProvider authClientId={CLIENT_ID}>
      <div className="app">
        <h1>我的Bodhi聊天应用</h1>
        <Chat />
      </div>
    </BodhiProvider>
  );
}

export default App;

步骤3:创建聊天组件

// Chat.tsx
import { useState, useEffect } from 'react';
import { useBodhi } from '@bodhiapp/bodhi-js-react';

function Chat() {
  const { client, isOverallReady, isAuthenticated, login, showSetup } = useBodhi();
  const [prompt, setPrompt] = useState('');
  const [response, setResponse] = useState('');
  const [loading, setLoading] = useState(false);
  const [models, setModels] = useState<string[]>([]);
  const [selectedModel, setSelectedModel] = useState('');

  // 挂载时加载模型
  useEffect(() => {
    if (isOverallReady && isAuthenticated) {
      loadModels();
    }
  }, [isOverallReady, isAuthenticated]);

  const loadModels = async () => {
    const modelList: string[] = [];
    for await (const model of client.models.list()) {
      modelList.push(model.id);
    }
    setModels(modelList);
    if (modelList.length > 0) setSelectedModel(modelList[0]);
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!prompt.trim() || !selectedModel) return;

    setLoading(true);
    setResponse('');

    try {
      const stream = client.chat.completions.create({
        model: selectedModel,
        messages: [{ role: 'user', content: prompt }],
        stream: true,
      });

      for await (const chunk of stream) {
        const content = chunk.choices?.[0]?.delta?.content || '';
        setResponse(prev => prev + content);
      }
    } catch (err) {
      setResponse(`错误:${err instanceof Error ? err.message : String(err)}`);
    } finally {
      setLoading(false);
    }
  };

  if (!isOverallReady) {
    return <button onClick={showSetup}>打开设置</button>;
  }

  if (!isAuthenticated) {
    return <button onClick={login}>登录</button>;
  }

  return (
    <div>
      <select value={selectedModel} onChange={e => setSelectedModel(e.target.value)}>
        {models.map(model => (
          <option key={model} value={model}>
            {model}
          </option>
        ))}
      </select>
      <form onSubmit={handleSubmit}>
        <input value={prompt} onChange={e => setPrompt(e.target.value)} />
        <button type="submit" disabled={loading}>
          {loading ? '生成中...' : '发送'}
        </button>
      </form>
      {response && <div>{response}</div>}
    </div>
  );
}

export default Chat;

关键API和Hooks

useBodhi() Hook

const {
  client, // SDK客户端实例(OpenAI兼容API)
  isOverallReady, // 客户端和服务器都准备就绪(最常用检查)
  isAuthenticated, // 用户具有有效的OAuth令牌
  login, // 启动OAuth登录流程
  logout, // 注销并清除令牌
  showSetup, // 打开设置向导模态框

  // 附加属性
  isReady, // 客户端已初始化(扩展或直接URL)
  isServerReady, // 服务器状态为'ready'
  isInitializing, // client.init()进行中
  isExtension, // 使用扩展模式
  isDirect, // 使用直接HTTP模式
  canLogin, // isReady && !isAuthLoading
  isAuthLoading, // 身份验证操作进行中
} = useBodhi();

客户端方法(OpenAI兼容)

// 列出模型(AsyncGenerator)
for await (const model of client.models.list()) {
  console.log(model.id);
}

// 流式聊天
const stream = client.chat.completions.create({
  model: 'gemma-3n-e4b-it',
  messages: [{ role: 'user', content: '你好!' }],
  stream: true,
});

for await (const chunk of stream) {
  const content = chunk.choices?.[0]?.delta?.content || '';
  // 附加到响应
}

// 非流式聊天
const response = await client.chat.completions.create({
  model: 'gemma-3n-e4b-it',
  messages: [{ role: 'user', content: '你好!' }],
  stream: false,
});

高级配置

自定义客户端配置

<BodhiProvider
  authClientId={CLIENT_ID}
  clientConfig={{
    redirectUri: 'https://myapp.com/callback',
    basePath: '/app',
    logLevel: 'debug',
  }}
>
  <App />
</BodhiProvider>

子路径或GitHub Pages的basePath

当您的应用程序在子路径上运行时(例如,GitHub Pages在/repo-name/):

// Vite配置
export default defineConfig({
  base: '/repo-name/',
});

// BodhiProvider
<BodhiProvider authClientId={CLIENT_ID} basePath="/repo-name" callbackPath="/repo-name/callback">
  <App />
</BodhiProvider>;

常见模式

条件渲染

function App() {
  const { isOverallReady, isAuthenticated, showSetup, login } = useBodhi();

  if (!isOverallReady) {
    return <button onClick={showSetup}>需要设置</button>;
  }

  if (!isAuthenticated) {
    return <button onClick={login}>需要登录</button>;
  }

  return <ChatInterface />;
}

带缓存的模型加载

const loadModels = async () => {
  const cached = localStorage.getItem('bodhi_models');
  if (cached) {
    const { models: cachedModels, expiry } = JSON.parse(cached);
    if (Date.now() < expiry) {
      setModels(cachedModels);
      return;
    }
  }

  const modelList: string[] = [];
  for await (const model of client.models.list()) {
    modelList.push(model.id);
  }
  setModels(modelList);

  localStorage.setItem(
    'bodhi_models',
    JSON.stringify({
      models: modelList,
      expiry: Date.now() + 3600000, // 1小时
    })
  );
};

错误处理

try {
  const stream = client.chat.completions.create({ ... });
  for await (const chunk of stream) {
    // 处理块
  }
} catch (err) {
  if (err instanceof Error) {
    console.error('聊天错误:', err.message);
    setError(err.message);
  }
}

详细指南

有关特定主题的全面信息,请参阅支持文档:

SDK文档参考

bodhi-js-sdk存储库包含全面的文档:

  • bodhi-js-sdk/docs/quick-start.md - 官方快速入门
  • bodhi-js-sdk/docs/react-integration.md - React集成深入探讨
  • bodhi-js-sdk/docs/authentication.md - OAuth流程详情
  • bodhi-js-sdk/docs/streaming.md - 流式传输模式
  • bodhi-js-sdk/docs/api-reference.md - 完整的API文档

实施方法

当用户要求集成bodhi-js-sdk时:

  1. 检查现有设置:查找package.json、现有React组件
  2. 安装包:运行npm install @bodhiapp/bodhi-js-react
  3. 添加BodhiProvider:使用提供程序包装根组件
  4. 创建/更新组件:向组件添加useBodhi() hook
  5. 测试连接:验证扩展检测或直接模式
  6. 添加OAuth:指导用户在developer.getbodhi.app注册
  7. 实现聊天:创建流式聊天界面
  8. 处理错误:添加适当的错误边界和用户反馈

故障排除时:

  1. 检查连接状态:使用isOverallReadyisReadyisServerReady
  2. 验证身份验证状态:检查isAuthenticatedauth对象
  3. 检查日志:在控制台中查找以[Bodhi/Web]为前缀的日志
  4. 审查配置:验证authClientId、redirectUri、basePath
  5. 测试后端:确保本地服务器在http://localhost:1135
  6. 检查扩展:验证Bodhi Browser扩展已安装

测试集成

集成后,验证:

  1. 扩展检测:检查控制台中的[Bodhi/Web] Extension detected
  2. 服务器连接:验证[Bodhi/Web] Server ready
  3. 设置流程:点击“打开设置”测试模态框
  4. 身份验证:点击“登录”测试OAuth流程
  5. 模型加载:验证模型是否填充在下拉列表中
  6. 流式传输:发送消息并验证实时响应流式传输
  7. 错误处理:测试服务器离线以验证错误状态

常见集成任务

当用户请求时:

  • “将bodhi添加到我的React应用程序” → 遵循基本集成步骤
  • “为bodhi设置OAuth”指导到oauth-setup.md、developer.getbodhi.app
  • “部署到GitHub Pages” → 参考github-pages.md获取basePath和404 hack
  • “聊天不工作” → 检查troubleshooting.md获取连接/身份验证问题
  • “模型未加载” → 验证服务器、检查模型端点、审查异步迭代
  • “流式传输损坏” → 验证stream:true、检查AsyncGenerator模式

要引用的关键文件

实施集成时:

  • bodhi-js-sdk/docs/quick-start.md - 主要集成指南
  • bodhi-js-sdk/docs/react-integration.md - React特定模式
  • bodhi-js-sdk/docs/ - 全面的文档和示例

注意事项

  • 仅关注React+Vite项目
  • 始终使用@bodhiapp/bodhi-js-react预设包(最简单)
  • 自动回调处理默认启用(handleCallback={true}
  • OAuth回调自动发生,无需自定义路由
  • 默认后端:http://localhost:1135
  • 扩展模式优于直接模式
  • 流式传输的AsyncGenerator模式(OpenAI兼容)