@sophonsai/agent-panel-sdk
v0.6.0
Published
Framework-independent browser SDK for integrating Sophon Agent Panel.
Maintainers
Readme
@sophonsai/agent-panel-sdk
@sophonsai/agent-panel-sdk 是 SophonsAI 智能体平台提供的 Agent 面板快速接入 SDK,帮助原生 JavaScript 和 TypeScript 应用以简单、统一的方式集成完整的智能体交互能力。
安装
# npm
npm install @sophonsai/agent-panel-sdk
# pnpm
pnpm add @sophonsai/agent-panel-sdk
# yarn
yarn add @sophonsai/agent-panel-sdk
# bun
bun add @sophonsai/agent-panel-sdk快速开始
<div id="agent-panel" style="height: 640px"></div>import { createAgentPanel, type AgentAppearance, type AgentPanelInstance } from '@sophonsai/agent-panel-sdk'
const appearance: AgentAppearance = {
theme: { preset: 'glacier-blue' },
fontSize: 16,
header: {
historyButton: true,
newConversationButton: true,
themeSettingButton: false,
},
}
const client = createAgentPanel({
initConfig: {
endpoint: 'https://agent.example.com',
agentId: 'agent-id',
auth: { type: 'platform.user.credential', credential: 'access-token' },
threadId: 'optional-conversation-id',
},
appearance,
onReady(instance) {
instance.focusInput()
},
onAuthFailed({ code, message }) {
console.error('鉴权失败', code, message)
},
onAgentLoadFailed({ code, message }) {
console.error('智能体加载失败', code, message)
},
onSettled(result) {
console.log('本轮会话结束', result)
},
})
const container = document.getElementById('agent-panel')!
await client.mount(container)
const instance: AgentPanelInstance = await client.whenReady()
instance.sendMessage({ text: '你好,请介绍一下自己' })页面退出或不再使用面板时应主动销毁:
client.destroy()初始化配置
createAgentPanel(options) 创建一个独立的 AgentPanelClient。每个 client 只能挂载一次。
initConfig
| 字段 | 类型 | 必填 | 说明 |
| ---------- | ---------------- | ---- | ----------------------------------------------------------- |
| endpoint | string | 是 | Sophon 服务端点,例如 https://agent.example.com |
| baseUrl | string | 否 | 已弃用的 endpoint 兼容别名,下一个版本移除 |
| basePath | string | 否 | Extension 应用部署路径,默认 /app/extension;根路径传 / |
| agentId | string | 是 | 要加载的智能体 ID |
| auth | AgentPanelAuth | 是 | 平台用户凭证或扩展用户身份鉴权配置 |
| token | string | 否 | 已弃用的 token 模式兼容写法 |
| threadId | string | 否 | 指定要打开的已有会话;不传时由面板创建或选择会话 |
平台用户凭证模式:
auth: { type: 'platform.user.credential', credential: 'access-token' }扩展用户身份模式由 Extension 服务使用 appId + externalUser.id 换取访问凭证:
auth: {
type: 'extension.user.identity',
appId: 'third-party-app-id',
externalUser: {
id: 'user-id-in-your-system',
name: '用户显示名', // 可选
},
}扩展用户身份仅通过 bridge init 消息发送,不进入 iframe URL。换取访问凭证成功后才会继续用户鉴权、Agent 加载和 ready 生命周期。不要把访问凭证或外部用户身份记录到公开日志或发送给无关第三方。
initConfig 和所有回调函数会在 createAgentPanel() 时保存为快照,之后修改原对象不会更新已经创建的 client。需要切换智能体、token、会话或回调时,应销毁旧 client 并创建新 client。
endpoint 与 baseUrl 至少提供一个;同时提供时优先使用 endpoint。
外观配置
const appearance: AgentAppearance = {
theme: { preset: 'studio-white' },
fontSize: 16,
header: {
historyButton: true,
newConversationButton: true,
themeSettingButton: true,
},
}header.themeSettingButton 默认值为 false,只有显式设置为 true 时才显示主题设置按钮。
可用主题
可以使用 AgentPanelThemePreset 枚举式常量设置主题:
import { AgentPanelThemePreset } from '@sophonsai/agent-panel-sdk'
client.updateTheme({ preset: AgentPanelThemePreset.GlacierBlue })| 主题名 | preset | 类型 |
| ------ | ----------------- | -------- |
| 曜石紫 | obsidian-violet | 深色主题 |
| 石墨青 | graphite-cyan | 深色主题 |
| 午夜靛 | midnight-indigo | 深色主题 |
| 深海蓝 | deep-ocean | 深色主题 |
| 森野绿 | forest-emerald | 深色主题 |
| 影棚白 | studio-white | 浅色主题 |
| 珍珠紫 | pearl-violet | 浅色主题 |
| 冰川蓝 | glacier-blue | 浅色主题 |
| 暖杏色 | warm-cream | 浅色主题 |
| 薰衣草 | lavender-mist | 浅色主题 |
动态更新
创建 client 后,只有外观支持动态更新:
client.updateTheme({ preset: 'warm-cream' })
client.updateFontSize(18)
client.updateHeader({
historyButton: false,
newConversationButton: true,
themeSettingButton: false,
})传入 undefined 会撤销对应的受控配置,让面板恢复内部默认值:
client.updateTheme(undefined)
client.updateFontSize(undefined)
client.updateHeader(undefined)面板内部主动切换主题或字号时,会调用 onThemeChange 或 onFontSizeChange。如果宿主把这些字段作为受控状态,应在回调中同步外部状态,再调用相应的更新方法。
mount 与 ready
这两个阶段含义不同:
挂载面板
→ mount 完成
→ 鉴权并加载智能体
→ 面板就绪
→ whenReady 完成mount(container)
mount() 会把 SDK 管理的面板挂载到指定容器。mount() 完成只表示面板已经启动,不表示面板已经初始化完成。
以下情况会让 mount() reject:
- client 已销毁;
- 同一个 client 被重复挂载;
- 面板无法挂载到指定容器;
- 面板启动失败;
- 在挂载完成前调用了
destroy()。
当前没有内置 mount 超时。如果面板持续处于加载中且没有返回错误,Promise 会保持 pending,业务可按需在外层增加超时。
whenReady()
whenReady() 等待面板初始化完成,并返回可调用的 AgentPanelInstance。它可以调用多次;ready 后再次调用会立即返回同一个 instance。
在 ready 之前调用 instance 命令会抛出 AgentPanel is not ready.。推荐只保存 whenReady() 或 onReady 返回的实例。
鉴权或智能体加载失败不会让已经完成的 mount() 重新失败,而是通过 onAuthFailed 或 onAgentLoadFailed 报告。
实例方法
AgentPanelInstance 提供以下命令:
| 方法 | 说明 |
| ----------------------------------- | ------------------------------------------------------- |
| sendMessage({ text }) | 立即提交一条消息;正在生成回复时会使用面板的 steer 行为 |
| addInputQuery({ text, context? }) | 把文本和可选上下文写入输入框,但不立即提交 |
| abortResponse() | 终止当前回复 |
| openHistoryPanel() | 打开历史会话面板 |
| openThemeSettingsPanel() | 打开主题设置面板 |
| newConversation() | 新建会话 |
| focusInput() | 聚焦输入框 |
| scrollToBottom() | 滚动到消息底部 |
示例:
const agent = await client.whenReady()
agent.addInputQuery({
text: '请解释这段内容',
context: '用户在页面中选中的文本',
})
agent.focusInput()生命周期回调
| 回调 | 参数 | 说明 |
| -------------------- | ---------------------------- | -------------------- |
| onReady | AgentPanelInstance | 面板初始化完成 |
| onThemeChange | AgentPanelTheme | 面板内部主题发生变化 |
| onFontSizeChange | number | 面板内部字号发生变化 |
| onIdentityResolved | AgentPanelResolvedIdentity | 外部用户身份解析成功 |
| onAuthFailed | AgentPanelAuthFailure | 鉴权失败 |
| onAgentLoadFailed | AgentPanelAgentLoadFailure | 智能体信息加载失败 |
onReady(instance)
面板初始化完成后调用,参数与 whenReady() 返回值相同。
onAuthFailed(failure)
鉴权失败时调用。failure.code 可能是:
| code | 含义 |
| ---------------------------- | ------------------------- |
| missing_token | 未提供访问凭证 |
| invalid_token | token 无效或已失效 |
| identity_resolution_failed | 外部用户身份换取 JWT 失败 |
| forbidden | 当前凭证无访问权限 |
| request_failed | 鉴权请求失败 |
onAgentLoadFailed(failure)
智能体信息加载失败时调用。failure.code 可能是:
| code | 含义 |
| ---------------- | ---------------- |
| not_found | 未找到智能体 |
| forbidden | 无权访问该智能体 |
| request_failed | 智能体请求失败 |
两个 failure 都包含适合展示或记录的 message。失败发生后不会触发 onReady。
会话事件
可以在 createAgentPanel() 中传入以下全部运行事件回调:
| 回调 | 参数 | 说明 |
| --------------------------- | --------------------------------------------------------------- | ------------------------------------------- |
| onConcurrentSend | 无 | 回复生成期间再次发送消息 |
| onEvent | AgentServerEvent | 接收原始服务端事件 |
| onSessionContextReady | AgentSessionContext | 会话上下文可用,包含 threadId 和 turnId |
| onToolCallCreated | AgentToolCallCreatedEvent, AgentSessionEventContext | 创建一个工具调用 |
| onToolApprovalRequested | AgentToolApprovalRequestedEvent, AgentSessionEventContext | 一组工具调用需要确认 |
| onToolCallStarted | AgentToolCallStartedEvent, AgentSessionEventContext | 工具调用开始 |
| onToolCallProgressUpdated | AgentToolCallProgressUpdatedEvent, AgentSessionEventContext | 工具调用进度更新 |
| onToolCallBackgrounded | AgentToolCallBackgroundedEvent, AgentSessionEventContext | 工具调用转为后台执行 |
| onToolCallSucceeded | AgentToolCallSucceededEvent, AgentSessionEventContext | 工具调用成功 |
| onToolCallFailed | AgentToolCallFailedEvent, AgentSessionEventContext | 工具调用失败 |
| onToolCallCancelled | AgentToolCallCancelledEvent, AgentSessionEventContext | 工具调用取消 |
| onClientActionRequest | AgentClientActionRequestEvent, AgentSessionEventContext | 智能体请求宿主执行客户端动作 |
| onUserFeedbackConsumed | AgentUserFeedbackConsumedEvent, AgentSessionEventContext | 用户反馈已被处理 |
| onUserSteerConsumed | AgentUserSteerConsumedEvent, AgentSessionEventContext | 用户 steer 指令已被处理 |
| onUserSteerCancelled | AgentUserSteerCancelledEvent, AgentSessionRunEventContext | 用户 steer 指令已取消 |
| onUserInputSubmitted | AgentUserInputSubmittedEvent, AgentSessionEventContext | 用户输入已提交 |
| onSessionTurnStarted | AgentSessionTurnStartedEvent, AgentSessionEventContext | Turn 开始执行 |
| onSessionTurnSucceeded | AgentSessionTurnSucceededEvent, AgentSessionEventContext | Turn 执行成功 |
| onSessionTurnFailed | AgentSessionTurnFailedEvent, AgentSessionEventContext | Turn 执行失败 |
| onSessionTurnCancelled | AgentSessionTurnCancelledEvent, AgentSessionEventContext | Turn 已取消 |
| onSessionRunStarted | AgentSessionRunStartedEvent, AgentSessionRunEventContext | Run 已开始 |
| onSessionRunIdled | AgentSessionRunIdledEvent, AgentSessionRunEventContext | Run 已空闲 |
| onSessionRunEnded | AgentSessionRunEndedEvent, AgentSessionRunEventContext | Run 已结束 |
| onSystemMessageConsumed | AgentSystemMessageConsumedEvent, AgentSessionEventContext | 系统消息已被处理 |
| onSuccess | AgentSessionSuccess | 本轮会话成功结束 |
| onError | AgentSessionFailure | 本轮会话失败 |
| onCancelled | AgentSessionCancelled | 本轮会话取消 |
| onSettled | AgentSessionSettlement | 本轮会话以任意状态结束 |
所有事件、事件参数及上下文类型都从包中导出,可以直接用于 TypeScript 标注。
const client = createAgentPanel({
initConfig,
onToolCallFailed(event, context) {
console.error(context.turnId, event.toolName, event.error)
},
onSettled(result) {
if (result.status === 'failure') console.error(result.error)
},
})用户回调内部抛出的异常会被 SDK 隔离,不会影响其他回调或面板后续运行。
销毁与清理
client.destroy()destroy() 会:
- 移除面板;
- 注销浏览器事件监听器;
- 拒绝尚未完成的 mount/ready 等待;
- 使 client 和已经获得的 instance 失效。
重复调用 destroy() 是安全的。销毁后调用外观更新或实例命令会抛错,销毁后的 client 也不能重新挂载。
