Skip to content

React 适配器 ​

@plingjs/react 把 React 的 ref、effect 与 context 接到 Vue 适配器共用的页面运行时上。它不另带执行器,也不另写一套 agent 循环。

对等版本:React 18 及以上。它是客户端适配器;Next.js 等 SSR 宿主必须在 DOM 就绪后再创建实例。

安装与 Provider ​

tsx
import { createRoot } from "react-dom/client";
import { createPling, PlingProvider } from "@plingjs/react";
import App from "./App";

const pling = createPling({
  agent: {
    config: {
      baseUrl: import.meta.env.VITE_AGENT_BASE_URL,
      model: import.meta.env.VITE_AGENT_MODEL,
      apiKey: import.meta.env.VITE_AGENT_API_KEY,
    },
  },
});

createRoot(document.getElementById("root")!).render(
  <PlingProvider pling={pling}>
    <App />
  </PlingProvider>,
);

createPling(options) 支持 ui、registry、shared、namespace、onWarn、agent、revealSensitive、scopes、presence 与 derive。返回的 PlingElement 包含 registry、scopes、ui、presence、derived()、setActiveScopes() 与 destroy()。

Hooks ​

Hook返回用途
usePling()PlingElement取 Provider 中的实例
usePlingTool<T>(options)RefCallback<T>声明元素动作
useAgentTool(options)void声明函数级动作
usePlingRecord<T>(value)RefCallback<T>声明一行记录
usePlingScope<T>(options)RefCallback<T>声明区域
usePlingState(key, source, options?)() => void注册组件级只读视图
exposePlingState(pling, key, source, options?)() => void在组件树外注册视图

usePlingTool 接受与 Vue v-tool 相同的字段:id、desc、kind、params、run、available、expect、confirm、handoff、action、target、autoTarget 与 fidelity。选项从 ref 读取,因此重渲染后处理函数不会停留在旧闭包。

完整的一行 ​

tsx
function TaskRow({ task, onToggle }: { task: Task; onToggle: (id: string) => void }) {
  const row = usePlingRecord({ data: task, label: task.title });
  const toggle = usePlingTool<HTMLButtonElement>({
    id: `toggle@${task.id}`,
    desc: `${task.done ? "取消完成" : "标记完成"}:${task.title}`,
  });

  return (
    <li ref={row}>
      <button ref={toggle} onClick={() => onToggle(task.id)}>
        {task.done ? "取消完成" : "完成"}
      </button>
      {task.title}
    </li>
  );
}

ref 回调在挂载时注册,卸载时注销。记录读取最新的 task prop,所以字段更新不需要重新声明。

区域与状态 ​

tsx
function TaskList({ tasks }: { tasks: Task[] }) {
  const scope = usePlingScope<HTMLUListElement>({
    id: "task_list",
    label: "待办列表",
    role: "list",
  });

  usePlingState("task_view", () => ({
    total: tasks.length,
    open: tasks.filter((task) => !task.done).length,
  }), { description: "当前列表的待办总数与未完成数" });

  return <ul ref={scope}>{tasks.map((task) => <TaskRow key={task.id} task={task} onToggle={() => {}} />)}</ul>;
}

usePlingState 没有 setter。要改变列表,必须声明执行改变的动作。

助手界面 ​

tsx
<AgentDock
  title="待办助手"
  quick={["新增一条待办", "把第一条待办标记完成"]}
  config={{ limits: { maxTurns: 100 } }}
/>

<AgentDock> 负责 runtime、确认面板、人工接力面板与最近操作;<AgentChat> 只负责展示,适合宿主自己管理 runtime 和事件流的场景。

给 <AgentDock> 传 debug 可在运行页开启只读检查器:

tsx
<AgentDock debug={{ maxCalls: 8 }} />

检查器展示打开时的页面投影,以及每次保留的模型调用所收到的消息、工具、响应与请求时页面快照。它读取当前对话正在使用的 runtime,不执行动作,也不创建第二套会话。debug 默认关闭;传对象可限制保留的调用数,传 true 使用默认上限。检查器会显示发往模型的消息与页面数据,应把它视为开发工具,不要在生产公开构建里无条件开启。

模型设置界面仍只在 Vue 3 适配器中提供。React 项目应把模型凭据留在自己的模型网关之后。

能力边界 ​

React 支持动作、函数级工具、记录、区域、状态、确认、人工接力、存在感、自动派生、命名空间、共享页面运行时与只读运行检查器。

当前不支持:

  • store 字段白名单(useAgentStoreState);
  • 复合动作 steps;
  • 页面反馈、分步指引与任务入口;
  • 模型设置界面;
  • 覆盖率扫描;
  • Router 页面身份。

不要通过引入 Vue 组件来补这些缺口。应新增 React 实现,或把能力下沉到共享层。

常见失败 ​

症状原因处理
Hook 抛错,提示没有 Provider组件渲染在 <PlingProvider> 之外在根节点包一层
重渲染后动作消失ref 换到了别的元素,或元素被卸载把 ref 固定在稳定的可交互节点上
行内动作作用到错误的行id 没有绑定到该行使用 toggle@${task.id}
状态不更新捕获了旧值,而不是读取当前值传读取当前 props/state 的函数
Dock 没有模型createPling({ agent }) 与 <AgentDock> 都没有配置在其中一个提供 config,或使用环境变量
卸载后 useAgentTool 仍然有效Hook 在组件外调用移入组件,或显式注销

证据 ​

版本与兼容性 ​

项目取值
适用版本@plingjs/react 0.1.0-alpha.2
引入版本0.1.0-alpha.2(首个发布的 alpha)
运行环境支持 ES2022 模块的浏览器中的 React 18 或更高版本;SSR 与构建需 Node.js 20 或更高版本
Peer 依赖react >=18
稳定性1.0 之前的 alpha;次版本可能改变 API

本适配器不依赖 Vue,也不绑定特定路由。本页列出的 Provider、Hook、组件名与 props 就是当前版本的公开接口。