后端前端CRM人工智能AI Agent【免费下载链接】crmComp AI CRM is an open source, CRM designed for AI agents. Agentic-first CRM.项目地址https://gitcode.com/gh_mirrors/crm48/crm点击查看免费下载本篇文章以 Comp AI CRM 仓库中锁定的 ai-elements 技能集见 skills-lock.json为背景深入讲解Confirmation组件——一个基于 alert 语义、专门用于管理 AI 工具执行审批工作流的 React 组件。你将掌握如何安装该组件、如何与 AI SDK 的useChat/streamText集成实现危险工具执行前需人工确认的完整闭环理解approval-requested、approval-responded、output-denied、output-available四类状态的渲染规则以及全部子组件的 Props 契约并学会基于仓库内的真实示例脚本confirmation.tsx 等快速落地生产级审批 UI。一、Confirmation 组件是什么Confirmation是 AI Elements 组件库中的一个 alert 型组件专门用于承载工具执行审批工作流的三种关键状态请求request、接受accept、拒绝reject。它解决的场景非常具体当 AI Agent 即将执行一个具有破坏性或高风险的工具调用例如删除文件、操作生产数据库、发送邮件时需要先向用户展示审批请求用户做出决定后组件再展示对应的执行结果。组件背景AI Elements 是基于 shadcn/ui 中有完整说明。该技能在本仓库中以ai-elements条目被锁定来源为vercel/ai-elements见 skills-lock.json意味着 Comp AI CRM 的 Agent 开发工作流可以直接参考这套组件规范来构建聊天与工具审批界面。该组件的核心设计目标在工具执行前展示审批请求及批准 / 拒绝操作按钮在用户响应后展示审批结果批准或拒绝与工具输出通过 props 驱动的状态管理而非组件内部维护状态便于与 AI SDK 的消息流ToolUIPart天然对齐。二、安装与前置条件安装Confirmation组件只需一条命令npx ai-elementslatest add confirmation如果你的项目使用 pnpm 或 bun 作为包管理器请替换为对应的 runner原文档与 SKILL.md 均强调这一点pnpm dlx ai-elementslatest add confirmation bunx --bun ai-elementslatest add confirmation命令执行后组件源码而非编译产物会被下载并放入你项目的 components 目录——默认是/components/ai-elements/或你在 shadcn/ui 的components.json中配置的目录。这正是 AI Elements 的代码即配置哲学安装完成后你可以直接打开组件文件阅读实现或按需修改。前置环境要求来自 SKILL.mdNode.js 18 或更高版本Next.js 项目且已安装 AI SDK组件示例依赖ai-sdk/react的useChat与ai的streamText、DefaultChatTransportshadcn/ui 已安装未安装时执行安装命令会自动帮你装好若组件样式不生效请确认globals.css已按 Tailwind 4 规范引入 shadcn/ui 基础样式。三、端到端集成示例让危险工具执行前必须获得用户确认原文档给出了一套完整的前后端集成示例删除文件场景这也是理解Confirmation组件如何嵌入真实 Agent 工作流的最佳入口。下面将完整呈现并逐段拆解。3.1 前端构建带审批的聊天 UI将以下组件加入你的前端页面原文档路径为app/page.tsxuse client; import { useChat } from ai-sdk/react; import { DefaultChatTransport, type ToolUIPart } from ai; import { useState } from react; import { CheckIcon, XIcon } from lucide-react; import { Button } from /components/ui/button; import { Confirmation, ConfirmationTitle, ConfirmationRequest, ConfirmationAccepted, ConfirmationRejected, ConfirmationActions, ConfirmationAction, } from /components/ai-elements/confirmation; import { MessageResponse } from /components/ai-elements/message; type DeleteFileInput { filePath: string; confirm: boolean; }; type DeleteFileToolUIPart ToolUIPart{ delete_file: { input: DeleteFileInput; output: { success: boolean; message: string }; }; }; const Example () { const { messages, sendMessage, status, addToolApprovalResponse } useChat({ transport: new DefaultChatTransport({ api: /api/chat, }), }); const handleDeleteFile () { sendMessage({ text: Delete the file at /tmp/example.txt }); }; const latestMessage messages[messages.length - 1]; const deleteTool latestMessage?.parts?.find( (part) part.type tool-delete_file ) as DeleteFileToolUIPart | undefined; return ( div classNamemax-w-4xl mx-auto p-6 relative size-full rounded-lg border h-[600px] div classNameflex flex-col h-full space-y-4 Button onClick{handleDeleteFile} disabled{status ! ready} Delete Example File /Button {deleteTool?.approval ( Confirmation approval{deleteTool.approval} state{deleteTool.state} ConfirmationRequest This tool wants to delete:{ } code{deleteTool.input?.filePath}/code br / Do you approve this action? /ConfirmationRequest ConfirmationAccepted CheckIcon classNamesize-4 / spanYou approved this tool execution/span /ConfirmationAccepted ConfirmationRejected XIcon classNamesize-4 / spanYou rejected this tool execution/span /ConfirmationRejected ConfirmationActions ConfirmationAction variantoutline onClick{() addToolApprovalResponse({ id: deleteTool.approval!.id, approved: false, }) } Reject /ConfirmationAction ConfirmationAction variantdefault onClick{() addToolApprovalResponse({ id: deleteTool.approval!.id, approved: true, }) } Approve /ConfirmationAction /ConfirmationActions /Confirmation )} {deleteTool?.output ( MessageResponse {deleteTool.output.success ? deleteTool.output.message : Error: ${deleteTool.output.message}} /MessageResponse )} /div /div ); }; export default Example;关键机制拆解消息流中定位工具片段latestMessage.parts.find((part) part.type tool-delete_file)从最新消息中取出delete_file工具对应的ToolUIPart。AI SDK 会以tool-toolName的形式为每个工具调用生成 UI 片段。条件渲染deleteTool?.approval 保证只有服务端真的发起了审批请求approval对象存在时才渲染ConfirmationdeleteTool?.output存在时才渲染执行结果。用户决策回传addToolApprovalResponse({ id, approved })将用户的批准/拒绝结果按审批 ID 回传给聊天流。参考仓库中的示例脚本 confirmation.tsx生产环境中对应的回调语义是respondToConfirmationRequest以approved: true/false作为参数——无论哪种命名核心都是把用户的决策绑定到具体的审批 ID 上。状态驱动 UIConfirmation接收approval审批对象与state工具当前状态两个 prop内部依据它们决定渲染ConfirmationRequest请求中、ConfirmationAccepted已批准还是ConfirmationRejected已拒绝的内容块以及是否显示ConfirmationActions操作按钮组。3.2 后端用 requireApproval 开启审批工作流将以下路由加入后端原文档路径为app/api/chat/route.tsximport { streamText, UIMessage, convertToModelMessages } from ai; import { z } from zod; // Allow streaming responses up to 30 seconds export const maxDuration 30; export async function POST(req: Request) { const { messages }: { messages: UIMessage[] } await req.json(); const result streamText({ model: openai/gpt-4o, messages: await convertToModelMessages(messages), tools: { delete_file: { description: Delete a file from the file system, parameters: z.object({ filePath: z.string().describe(The path to the file to delete), confirm: z .boolean() .default(false) .describe(Confirmation that the user wants to delete the file), }), requireApproval: true, // Enable approval workflow execute: async ({ filePath, confirm }) { if (!confirm) { return { success: false, message: Deletion not confirmed, }; } // Simulate file deletion await new Promise((resolve) setTimeout(resolve, 500)); return { success: true, message: Successfully deleted ${filePath}, }; }, }, }, }); return result.toUIMessageStreamResponse(); }后端要点requireApproval: true是审批工作流的总开关。开启后AI SDK 会在模型请求调用delete_file工具时暂停执行生成一个带有approval.id的审批请求并推送到前端只有前端通过addToolApprovalResponse回传approved: true工具的execute才会真正运行。双保险的confirm参数工具参数中的confirm: z.boolean().default(false)与审批流程形成纵深防御——即使审批环节被绕过或出现竞态execute内还会二次校验confirm是否为true否则直接返回success: false, message: Deletion not confirmed。这种UI 审批 参数校验的双层设计是生产级 Agent 应用中防止危险操作误执行的常见模式。convertToModelMessages将前端传来的UIMessage[]包含工具片段与审批结果转换为模型可读的消息格式保证审批决策能正确参与下一轮对话上下文。toUIMessageStreamResponse()将streamText结果以 UI 消息流的形式流式返回前端DefaultChatTransport借此实时消费工具状态与输出。四、状态机组件的渲染决策规则Confirmation组件通过stateprop 感知工具片段的当前状态。AI SDK 的ToolUIPart可能处于以下六种状态之一状态含义Confirmation 是否渲染input-streaming工具输入参数正在流式生成否input-available工具输入已就绪尚未请求执行否approval-requested已请求用户审批是渲染请求内容与操作按钮approval-responded用户已作出审批决定是渲染批准/拒绝结果output-denied审批被拒绝输出被拦截是渲染拒绝结果output-available审批通过工具输出可用是渲染批准结果从原文档的 Props 表与示例脚本可以确认如下渲染逻辑仓库示例见 confirmation.tsx、confirmation-accepted.tsx、confirmation-rejected.tsxConfirmationRequest仅在approval-requested状态渲染展示工具想要执行的操作说明ConfirmationAccepted仅在approval.approved true且状态为approval-responded或output-available时渲染展示已批准的确认信息通常搭配CheckIconConfirmationRejected仅在approval.approved false且状态为output-denied时渲染展示已拒绝的提示通常搭配XIcon示例中使用text-destructive语义色ConfirmationActions仅在approval-requested状态渲染承载 Approve / Reject 两个操作按钮。这种内容块全部声明、由状态决定显隐的组合式设计使得组件可以无缝复用在审批流程的各个阶段而无需在业务代码里手写大量if/else分支。五、三种典型状态的可运行示例原文档在 Examples 一节给出了三种典型状态仓库的 scripts 目录中提供了对应的可运行 TSX 示例均使用nanoid生成审批 ID方便直接对照5.1 审批请求状态approval-requested示例文件confirmation-request.tsxConfirmation approval{{ id: nanoid() }} stateapproval-requested {/* ...ConfirmationTitle / Request / Accepted / Rejected / Actions... */} /Confirmation当state approval-requested时组件展示审批请求与操作按钮。仓库示例还演示了一个贴近生产数据库场景的变体——请求中嵌入待执行的 SQL 语句块ConfirmationRequest This tool wants to execute a query on the production database: code classNamemt-2 block rounded bg-muted p-2 text-sm SELECT * FROM users WHERE role apos;adminapos; /code /ConfirmationRequest这说明ConfirmationRequest的children是任意 ReactNode可以自由放入code块、表格、描述列表等内容非常适合展示将要执行的危险操作详情。5.2 已批准状态approval-responded / output-available示例文件confirmation-accepted.tsxConfirmation approval{{ approved: true, id: nanoid() }} stateapproval-responded ConfirmationTitle {/* ...Request / Accepted / Rejected... */} /ConfirmationTitle /Confirmation用户点击 Approve 后approval.approved变为true组件不再渲染操作按钮仅展示ConfirmationAccepted中的已批准状态CheckIcon 文案。示例中图标使用了text-green-600 dark:text-green-400随主题明暗自适应。5.3 已拒绝状态output-denied示例文件confirmation-rejected.tsxConfirmation approval{{ approved: false, id: nanoid() }} stateoutput-denied {/* ...同样声明全部内容块由状态驱动显隐... */} /Confirmation用户点击 Reject 后进入output-deniedConfirmationRejected生效展示拒绝提示XIcontext-destructive语义色。此时服务端将跳过工具执行、拦截输出前端也不会出现deleteTool.output结果块对应 3.1 中deleteTool?.output 的条件分支不成立。六、Props 完整参考以下为原文档给出的全部 Props 契约完整继承并附上补充说明。Confirmation /根组件基于 shadcn/ui AlertProp类型默认值说明approvalToolUIPart[approval]-审批对象包含审批 ID 与审批状态approved。未提供或为undefined时组件不渲染。stateToolUIPart[state]-工具当前状态input-streaming、input-available、approval-requested、approval-responded、output-denied、output-available。input-streaming与input-available状态下不渲染。classNamestring-应用到 Alert 容器的额外 CSS 类。...propsReact.ComponentPropstypeof Alert-其余 props 全部透传给 Alert 组件Alert 本身继承HTMLAttributesHTMLDivElement因此id、aria-*、data-*等原生属性均可使用。ConfirmationTitle /基于 AlertDescription用于在审批 alert 内展示标题或标签的样式化描述元素。Prop类型默认值说明...propsReact.ComponentPropstypeof AlertDescription-其余 props 全部透传给 AlertDescription 组件。ConfirmationRequest /请求内容块Prop类型默认值说明childrenReact.ReactNode-审批请求阶段展示的内容。仅在状态为approval-requested时渲染。ConfirmationAccepted /已批准内容块Prop类型默认值说明childrenReact.ReactNode-审批通过后展示的内容。仅在approval.approved true且状态为approval-responded或output-available时渲染。ConfirmationRejected /已拒绝内容块Prop类型默认值说明childrenReact.ReactNode-审批被拒后展示的内容。仅在approval.approved false且状态为output-denied时渲染。ConfirmationActions /操作按钮容器Prop类型默认值说明classNamestring-应用到操作容器 div 的额外 CSS 类。...propsReact.ComponentPropsdiv-其余 props 透传给 div 元素。仅在状态为approval-requested时渲染。ConfirmationAction /单个操作按钮基于 shadcn/ui ButtonProp类型默认值说明...propsReact.ComponentPropstypeof Button-其余 props 全部透传给 Button 组件。默认带有h-8 px-3 text-sm尺寸样式示例中通过variantoutlineReject与variantdefaultApprove区分主次。七、特性总览与无障碍原文档列出的特性清单对应到实际能力基于 Context 的状态管理审批工作流的状态由approval/stateprops 驱动组件内部通过上下文协调各内容块的显隐按审批状态条件渲染请求、批准、拒绝三种内容块可同时声明由状态自动决定渲染哪个覆盖四种关键状态approval-requested、approval-responded、output-denied、output-available基于 shadcn/ui 的 Alert 与 Button 构建视觉与交互语义与 shadcn/ui 生态一致TypeScript 全面类型支持ToolUIPart泛型约束可精确描述工具输入输出类型如示例中的DeleteFileToolUIPartTailwind CSS 可定制样式组件代码就在项目内可直接调整类名键盘导航与无障碍支持继承自 shadcn/ui Alert / Button 的可访问性实现主题感知、自动暗色模式示例中text-green-600 dark:text-green-400、text-destructive等语义色会自动适配明暗主题。八、在本仓库中的定位与扩展建议技能来源锁定本仓库通过 skills-lock.json 锁定了ai-elements技能来源vercel/ai-elements因此.agents/skills/ai-elements/目录下的 SKILL.md、references/confirmation.md与scripts/示例共同构成了 Comp AI CRM 中构建 Agent 聊天与工具审批界面的标准参考。代码即配置的扩展方式安装后组件源码位于/components/ai-elements/confirmation.tsx对应项目内路径。由于代码直接落入你的项目而非封装在库里你可以像 SKILL.md 中演示的那样直接编辑组件源码——例如移除圆角、替换图标、调整按钮尺寸等所有修改即时生效。与 CRM Agent 场景的结合作为 Agentic-first 的 CRMComp AI CRM 的 Agent如删除记录、批量修改字段、发送消息等工具调用完全可以在前端复用这套审批模式把delete_file换成delete_contact/archive_deal把filePath换成 CRM 记录 ID即可为危险操作加上人工确认的安全闸门。审批请求内容块中甚至可以渲染记录的摘要信息让用户在做决定前看到完整上下文。实用排查提示源自 SKILL.md若组件样式缺失检查globals.css是否正确引入 Tailwind 4 shadcn/ui 基础样式若 CLI 未添加文件确认当前目录是项目根目录、components.json配置正确若/导入报 module not found检查tsconfig.json是否配置了/*: [./*]路径别名若主题切换不生效确保应用使用data-theme属性切换机制。九、小结Confirmation组件把AI 工具执行前的人工审批这个高频需求抽象为声明式、状态驱动的 UI 原语前端通过useChat的addToolApprovalResponse回传用户决策后端通过streamText的requireApproval: true挂起危险工具的执行两者配合即可在几分钟内为任何 Agent 应用补齐安全审批闭环。结合仓库内的 SKILL.md、references/confirmation.md 与 scripts 下的四个示例文件你可以直接对照实现并根据项目需要自由定制组件样式与内容块。赞分享后端前端CRM人工智能AI Agent【免费下载链接】crmComp AI CRM is an open source, CRM designed for AI agents. Agentic-first CRM.项目地址https://gitcode.com/gh_mirrors/crm48/crm点击查看免费下载相关推荐Comp AI CRM 中的 AI 推理展示ai-elements Reasoning 组件集成实战指南Comp AI CRM 中的 AI 推理展示ai elements Reasoning 组件集成实战指南 本文是一份以 ai elements 技能文档 ht后端前端CRM人工智能AI AgentComp AI CRM 集成指南用 ai-elements Queue 组件构建 AI 工作流队列与待办列表界面Comp AI CRM 集成指南用 ai elements Queue 组件构建 AI 工作流队列与待办列表界面 Queue 是 AI Elements 组件后端前端CRM人工智能AI AgentAgentOps-AI 实战基于 Google ADK 实现人工审批工作流AgentOps AI 实战基于 Google ADK 实现人工审批工作流 概述 在现代企业自动化流程中人工审批环节往往是不可或缺的关键节点。本文将介绍如何人工智能大模型LLMOps可观测性AI 评测Agent Traces上一篇OpenCLI 测试指南四层测试体系、本地最小充分验证策略与 E2E 实战手册下一篇Terminal.Gui项目中的Scheme机制深度解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
