@ frontera- sdk/ 聊天- ii
一个Frontera代理的对话,作为一个反应组件 在您自己的应用程序. 流化回复,工具活动,附件,代理生成的文件, 知识的引用、批准和个人账户联系.
这是一个 组件,不是 iframe它在你的DOM, 使用你的反应, 而您的 CSS 可以到达它(参见 危害) (中文(简体) ).
安装
npm i @frontera-sdk/chat-ui react react-dom
反应19,仅限无害环境管理。 安装需要节点.js 22 或 后. react 财务报告和审定财务报表
react-dom 是唯一的软件包 组件 需要你帮助的两个
在一页断钩中复制.
作为这个软件包的依赖,它用安装来制造的所有其他东西.
npm ls react # expect one version
如果你的标语端点 在同一项目 服务器 需要两个 更多,因为您自己的代码直接导入(参见 键:
npm i @frontera-sdk/chat @frontera-sdk/core
两者都已经带着这个软件包到达了,所以安装在实际操作中都是不开放的. 无论如何,申报一下: 您的源入件属于您的清单中的包件, 或该套件停止的那一天,取决于您的建筑间歇.
快开始
需要两样东西: 两个样式表,则a 装有 高度。 。 。 .
'use client'
import { FronteraChat } from '@frontera-sdk/chat-ui/chat'
import '@frontera-sdk/chat-ui/platform.css'
import '@frontera-sdk/chat-ui/styles.css'
export function Support() {
return (
<div className="h-dvh">
<FronteraChat tokenEndpoint="/api/chat-token" />
</div>
)
}
tokenEndpoint 是一条路由在 服务器返回
{ token: string, expiresAt: string } 签名人。 盖起它
路由是整合的另一半——见 键。 。 。 .
证书
正好通过一个 四种相入相入相入等相.
| Prop | 类型 | 页:1 |
|---|---|---|
tokenEndpoint | string | 建议. 服务器上的 URL 。 帮你处理续约 返回时 apiBaseUrl 或作为道具通过——交换不包括它. |
token + 键 apiBaseUrl | string + 键 string | 在它到期前你自己换的 谈话一结束就停止了. |
getToken | () => Promise<{ token, expiresAt, apiBaseUrl? }> | 复次召见. |
client | FronteraClient | (() => FronteraClient | null) | 你自己造的,例如从 useChatClient。 。 。 . |
升级
modes, (中文(简体) ), modelMode 财务报告和审定财务报表 defaultMode 已经消失——使用 modelSelector
模型在部署时与特工有关 主办方提供的列表 只会对实际运行产生分歧 而分歧是 隐形:取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取.
剩下的是,我们.. modelSelector?: boolean ——拾取者是否出现.
它提供哪种模式,以及选择哪个模式,现在来自代理商.
| 在此之前 | 之后 |
|---|---|
modes={[...]} | 删除它 — 使用代理器自己的模式 |
modes={[]} 隐藏拾取者 | modelSelector={false} |
modelMode="fast" 针入模型 | 配置该模式为代理默认; 道具没有替换 |
defaultMode="fast" | 同样——现在是代理的默认模式 |
TypeScript将这些报告为未知道具. Java 脚本没有 - 一个被忽视的
modelMode 保留运行代理服务器默认模式的聊天,并 a modes={[]}
用来隐藏拾取者 现在显示它,因为 modelSelector 默认为
true。搜索您的整合所有三个名称.
以部署方式运送 /v1/chat-agents 项目代理模式。 一个
旧的部署答案没有这些答案,拾取者就会空出.
道具
下面的一切都是可选的.
作曲家
| Prop | 类型 | 默认 | 它会做什么 |
|---|---|---|---|
approvalSelector | boolean | true | 批准 - 模式采取器. full ("未经批准就运行") 只有在符号带有 approval-mode 能力. |
fileUpload | boolean | true | 剪纸 财务报告和审定财务报表 随便哪里都行. false 使整个地表变得惰性. |
appsButton | boolean | false | 插件按钮 — 在询问前连接账户 。 要求数 connectRedirectUri。 。 。 . |
shortcuts | Shortcut[] | 无 | 空谈起步卡. 默认关闭:每张默认卡需要一台计算机设备的代理. |
modelSelector | boolean | true | 取出模特儿来 它提供的东西来自 代理人;当有一个模式而没有努力水平时,它会隐藏自己. |
placeholder | string | "Assign a task or ask anything..." | 作曲占位符. |
interface Shortcut {
id: string
label: string
description: string
prompt: string // dropped into the composer, not sent
}
谈话和代理
| Prop | 类型 | 默认 | 它会做什么 |
|---|---|---|---|
conversationId | string | 新建每个挂载 | 恢复一线. 如果您拥有一个线程列表, 则按它键该组件 . |
agentName | string | 选择 | 选择 并隐藏拾取者。 当证书已经修复代理时, 忽略了 . |
agentLabel | string | 代理人的自有姓名 | 显示 以上为答复。 那个化妆品. |
agentId | string | —— 说 | UUID探员 让作曲家提供经纪人的应用程序 @ 提及. |
agentPicker | boolean | true | 仅在证书到达多个代理时显示 . |
body | Partial<StartChatRequest> | —— 说 | 每次发送时都会看到额外的字段 . messages 财务报告和审定财务报表 conversationId 除外. |
版式和外观
| Prop | 类型 | 默认 | 它会做什么 |
|---|---|---|---|
header | boolean | true | 谈话自有头. |
sidePanel | boolean | true | 手动平板 (桌面) / 全屏平板 (移动),以及打开它的控制. |
theme | FronteraChatTheme | 继承 | 适用于外壳的设计符号 财务报告和审定财务报表 门户根. |
dark | boolean | OS 偏好 | 压住计划. 如果您的应用程序有主题切换, 请通过它或者两者意见不一. |
className | string | —— 说 | 添加到外壳元素中. |
empty | ReactNode | 平台问候 | 替换新会话屏幕. |
mobileMenu | ReactNode | 无 | 移动标题中的主控——您会话列表. 如果省略,则不会产生任何结果。 忽略了 \ 768px . |
interface FronteraChatTheme {
background?: string; surface?: string; border?: string
text?: string; muted?: string
accent?: string; accentText?: string; danger?: string
radius?: string; fontFamily?: string
}
连接流量
| Prop | 类型 | 它会做什么 |
|---|---|---|
connectRedirectUri | string | 您的 OAuth 回调页面 。 没有它,连接卡 解释什么是缺失 而不是提供一个死按钮. |
connectOrigin | string | 来源于,当它与重定向不同. |
活动
| Prop | 类型 | 何时 |
|---|---|---|
onStart | (info: { conversationId: string; runId: string }) => void | 跑步开始 自己线程列表的钩子 . |
onError | (error: Error) => void | 每运与溪出出错. 接这个 ——没有它,用户就能看到故障,在你的日志中也没有任何内容. |
键
浏览器从未持有您的代理密钥 。 您的服务器交换为 a
短寿命,每个用户 cht_ 符号 .
仅限服务器侧. 需求 @frontera-sdk/chat 财务报告和审定财务报表 @frontera-sdk/core 在你身边
明显,见 安装。 。 。 .
// POST /api/chat-token — your server
import { FronteraClient } from '@frontera-sdk/core/client'
import { exchangeChatToken } from '@frontera-sdk/chat/auth'
const frontera = new FronteraClient({
apiBaseUrl: process.env.FRONTERA_API_URL!,
// Either key kind goes here, same shape — see "Which key" below.
credential: { kind: 'apiKey', key: process.env.FRONTERA_WORKSPACE_KEY! },
})
export async function POST(req: Request) {
const user = await currentUser(req) // YOUR session
if (!user) return new Response('unauthorized', { status: 401 })
const token = await exchangeChatToken(frontera, {
externalUserId: user.id, // never from the body
ttlSeconds: 1800, // 60–86400, default 3600
capabilities: ['plugin-connect'],
})
// `apiBaseUrl` is yours to add — the exchange returns only the token and its
// expiry, and the component has no other way to learn which deployment the
// token belongs to. Without it: "No apiBaseUrl: pass one, or return it from
// your token endpoint". It is the origin the browser is about to call, so
// there is nothing secret in it.
return Response.json({ ...token, apiBaseUrl: process.env.FRONTERA_API_URL })
}
哪个键
代理密钥 sak_… | 工作空间密钥 sk-ws-… | |
|---|---|---|
| 范围 | 总是一个特工 | 工作空间中的每个聊天代理 |
| 用户选择 | 无 agentId 命名不同的代理为 403, (中文(简体) ), agentIds 实值 403 | agentId 为了一个, agentIds 一个子集(最多50个) |
| 代理人拾取器 | 从来没有显示,没有选择 | 显示,仅限于您所制作的 |
| 如果泄露的话 | 一个代理 | 每个聊天代理 |
| 所需额外经费 | —— 说 | 创建它与 嵌入式聊天 目的(工作空间设置 ~ API 密钥); 拒绝平台访问密钥, 指定其范围 |
一张地表,一张特工钥匙,停在那里 一个拾取者,或者不同 不同客户的代理商 – 工作空间密钥.
// Workspace key only — narrowing what this person's token may reach.
await exchangeChatToken(frontera, {
externalUserId: user.id,
agentId: 'support-bot', // exactly one
// or
agentIds: ['support-bot', 'billing-bot'], // a subset; the picker shows these
})
agentId 财务报告和审定财务报表 agentName 两者都接受代理人的UUID或它的弹出; 未知
一个是 404永远不要无声回落 缩小是强制服务器侧面——
在浏览器中过滤拾取器看起来完全相同,并且没有任何保护.
能力
| 能力 | 默认 | 打开 |
|---|---|---|
| (基数) | 永远 | 聊天 历史 自我对话 回答同意 |
plugin-connect | 打开 | 为插件连接自己的账户 |
schedule | 关 | 特工的预定任务 |
agent-mode | 关 | 工作项目、交流、交接 |
approval-mode | 关 | 选择"未经批准就跑" |
externalUserId, (中文(简体) ), capabilities, (中文(简体) ), agentId 财务报告和审定财务报表 ttlSeconds 是特权
决定。 各自从自己的会话中取出——如果呼叫者可以给用户取名,
任何签名的人都可以读别人的谈话.
更新是自动的, 最多12小时会话上限; 之后是您的服务器 薄荷又来.
其他入境点
| 导入 | 给你 |
|---|---|
@frontera-sdk/chat-ui/chat | FronteraChat - 整个地表 |
@frontera-sdk/chat-ui/client | useChatClient, (中文(简体) ), ChatClient, 公共类型—— 用于自己的侧边栏 |
@frontera-sdk/chat-ui/oauth-callback | FronteraOAuthCallback ——连接回调页面 |
@frontera-sdk/chat-ui/new-session | buildDefaultShortcuts, (中文(简体) ), Shortcut |
@frontera-sdk/chat-ui/message, (中文(简体) ), /composer, (中文(简体) ), /parts, (中文(简体) ), /header | 绘制自己的布局 |
@frontera-sdk/chat-ui/theme | FronteraChatTheme |
从你自己的铬读到谈话:
import { useChatClient, type Session } from '@frontera-sdk/chat-ui/client'
const { client, getClient } = useChatClient({ tokenEndpoint: '/api/chat-token' })
useEffect(() => {
client?.listSessions({ limit: 20 }).then(p => setThreads(p.data))
}, [client])
// Share the credential instead of minting a second token for the same person:
<FronteraChat client={getClient} conversationId={openId} />
连接用户自己的账户
对于扮演人物的插件(他们的邮件,文件). 四个 先决条件,所有要求:
- 在提供者(Google, Microsoft...)中注册您的回调 URL .
- 添加 你们自己 Frontera 中的 OAuth 客户端 = 设置 = 机密 。 一个提供者 只授权重定向其所有者已校验的域, 因此不能 我们的.
- 添加回调 URL 财务报告和审定财务报表 您的应用程序来源于嵌入式许可列表
(单位:千美元)
POST /v1/apps/embed-allowlist,需要一个工作空间成员与app:configure) (中文(简体) ). 没有默认,没有通配符. - 薄荷符号
plugin-connect。 。 。 .
// app/oauth/callback/page.tsx
'use client'
import { FronteraOAuthCallback } from '@frontera-sdk/chat-ui/oauth-callback'
export default function Page() { return <FronteraOAuthCallback /> }
<FronteraChat
tokenEndpoint="/api/chat-token"
connectRedirectUri="https://app.example.com/oauth/callback"
appsButton
/>
默认弹出,弹出被屏蔽时会进行全页重定向.
移动
在768px下,组件遵循平台,而不是缩小 桌面布局 :
- 侧面板变成一个 全屏幕工作表,而不是一栏;
- 标题是 固体和流动,并附有标题、摘要和 文件列表;
mobileMenu在那个酒吧的正前方... 你的会话列表,你的.. 组件;- 栏中保留一个新的会话,标题是“新会话”.
危害
| 你的CSS到达 | 规矩 button { padding: 8px } 重排聊天中的每个控件 。 范围: button:not(.fr-shell *)组合对话框 .fr-shell 我也一样. |
| 一个反应 | 两本断钩—— Cannot read properties of null (reading 'useState')检查 npm ls react。 。 。 . |
| 高度 | .fr-shell 实值 height: 100%一个没有高度的容器会崩溃. |
| 社区支助方案 | 允许您的 Frontera API 来源在 connect-src。 。 。 . |
解决问题
| 症状 | 原因 |
|---|---|
| 空聊天, 无错误 | onError 未接线 |
| 无能使/ 零高 | 集装箱没有高度 |
401 马上 | 托肯端点返回错误的形状——必须是 { token, expiresAt } |
| 一个小时后停止聊天 | 使用 token 不刷新; 使用 tokenEndpoint |
useState 无效 | 两个反应 |
| 控制显示错误 | 主机 CSS 外观元素 |
| 连接按钮不起作用 | connectRedirectUri 缺少, 或未在许可列表中的 URL |
| 无任何可点击的交谈停止 | 一个停放的批准.. GET /v1/chat/approvals?conversationId=… 同样的 |
浏览器所说的
为CSP授权列表或代理. 所有反对你的Frontera API的血统,与
cht_ 符号 :
POST /v1/chat conversation stream (SSE)
POST /v1/chat-tokens/renew refresh
GET /v1/chat-agents agent picker
GET /v1/sessions, /v1/sessions/:id history
PATCH /v1/sessions/:id title, approval mode
GET /v1/chat/approvals?conversationId=… parked decisions
POST /v1/chat/approvals/:id answer one
POST /v1/chat/app-connections/start|exchange|resume
POST /v1/chat-uploads attachments
GET /v1/chat-artifacts/:id[/file|/preview|/versions…]
PATCH /v1/chat-artifacts/:id save an edit