Phoenix PC 唤端能力接入说明
本文面向 Web 前端同学,说明从网页一键唤起 Phoenix PC / Accio Desktop,并在端内自动打开页面或发起 Query 的接入方式。
能力范围
当前端内支持两类通道:
4097本地 Gateway:网页通过fetch('http://localhost:4097/desktop/deeplink')向已打开的桌面端发送指令。- 自定义协议:通过
accio://...唤起桌面端;本地开发桌面端使用accio-dev://...。
当前支持的动作:
- 发起 Query,可指定 Agent 和 Skill。
- 打开 Agent 列表页、Agent 详情页。
- 打开 Plugin 列表页、Plugin 详情页。
- 打开 Skill、Connector、Channel 页面。
推荐唤端流程
网页侧建议按下面顺序处理:
- 先尝试
4097Gateway。 - 如果 Gateway 不可达或请求失败,再 fallback 到
accio://协议。 - 如果协议唤起后仍无响应,引导用户安装或打开桌面端。
三种状态的处理:
| 状态 | 判断方式 | 推荐处理 |
|---|---|---|
| 已打开 | http://localhost:4097/health 可访问,或 /desktop/deeplink 返回成功 |
直接通过 Gateway 分发指令 |
| 已安装未打开 | Gateway 不可达,但协议可唤起 | 跳转 accio://... |
| 未安装 | Gateway 不可达,协议唤起无确认 | 展示下载/安装引导 |
注意:浏览器无法可靠判断自定义协议是否一定唤起成功,协议通道需要配合超时和页面可见性变化做降级提示。
Agent 定位规则
不要在 Web 侧硬编码 agentId。agentId 是端内本地实例 ID,不具备语义,也不适合跨设备、跨账号复用。
Web 侧直接传扁平字段,不需要包一层对象:
sourcePluginId?: string
agentType?: string
端内解析顺序:
sourcePluginId + agentTypeagentTypeagentId,仅作为旧链接兼容 fallback
如果匹配多个 Agent,端内会视为歧义,不会静默选择第一个。
推荐:
{
"sourcePluginId": "shopify-plugin",
"agentType": "shopify-agent"
}
内置 Agent 没有 sourcePluginId 时,可以只传:
{
"agentType": "daily-assistant"
}
Gateway 接入
请求地址:
POST http://localhost:4097/desktop/deeplink
Content-Type: application/json
成功响应:
{
"ok": true,
"accepted": true,
"launchId": "optional-launch-id"
}
常见错误:
| HTTP 状态 | code | 含义 |
|---|---|---|
| 400 | INVALID_JSON |
请求体不是合法 JSON |
| 400 | INVALID_DEEP_LINK_COMMAND |
指令结构不合法 |
| 401 | Unauthorized |
Origin 未被免鉴权,或缺 Basic Auth |
| 501 | DESKTOP_DEEP_LINK_UNAVAILABLE |
当前桌面端未挂载 deeplink handler |
| 500 | DESKTOP_DEEP_LINK_DISPATCH_FAILED |
端内分发失败 |
生产网页的 Origin 需要在桌面端白名单内。目前支持:
https://www.accio.com
https://pre-www.accio.com
https://app.accio.com
https://www.accio-ai.com
https://pre-www.accio-ai.com
本地 Web 开发页如果直接从 localhost 调 Gateway,可能被 Basic Auth 拦截。调试时优先用协议通道,或在桌面端开发环境显式放开本地 Origin。
发起 Query
await fetch('http://localhost:4097/desktop/deeplink', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({
action: 'query',
query: '帮我分析这个 Shopify 店铺的转化问题',
sourcePluginId: 'shopify-plugin',
agentType: 'shopify-agent',
skillId: 'shopify-admin',
source: 'home',
launchId: crypto.randomUUID(),
}),
})
字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
action |
'query' |
是 | 固定为 query |
query |
string |
是 | 要发送到桌面端的用户问题 |
sourcePluginId |
string |
否 | Agent 来源 Plugin,推荐与 agentType 一起传 |
agentType |
string |
否 | Agent 业务类型;没有 sourcePluginId 时会单独用它匹配 |
agentId |
string |
否 | 兼容旧链路,不推荐新接入使用 |
skillId |
string |
否 | 自动选择的 Skill ID;多个 Skill 用英文逗号分隔 |
source |
string |
否 | 来源标识,用于日志/埋点 |
launchId |
string |
否 | 本次唤端 ID,用于串联日志 |
traceId |
string |
否 | 外部链路追踪 ID |
打开 Agent 详情页
await fetch('http://localhost:4097/desktop/deeplink', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({
action: 'navigate',
target: 'agentDetail',
sourcePluginId: 'alibaba-com-seller-assistant',
agentType: 'alibaba-com-seller-assistant',
source: 'home',
launchId: crypto.randomUUID(),
}),
})
打开 Plugin 详情页
await fetch('http://localhost:4097/desktop/deeplink', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({
action: 'navigate',
target: 'pluginDetail',
id: 'shopify-plugin',
source: 'home',
launchId: crypto.randomUUID(),
}),
})
可用 target:
type NavigateTarget =
| 'agents'
| 'agentDetail'
| 'plugins'
| 'pluginDetail'
| 'skills'
| 'connectors'
| 'channels'
协议接入
生产环境使用 accio://:
accio://chat/new?query=帮我分析店铺问题&sourcePluginId=shopify-plugin&agentType=shopify-agent&skillId=shopify-admin&source=home
本地桌面端开发环境使用 accio-dev://:
accio-dev://chat/new?query=hi&sourcePluginId=shopify-plugin&agentType=shopify-agent
打开 Agent 详情页:
accio://agents/detail?sourcePluginId=alibaba-com-seller-assistant&agentType=alibaba-com-seller-assistant&source=home
打开 Plugin 详情页:
accio://plugins/detail?pluginId=shopify-plugin&source=home
其他页面:
accio://agents
accio://plugins
accio://skills
accio://connectors
accio://channels
协议参数说明:
| 参数 | 适用路径 | 说明 |
|---|---|---|
query |
/chat/new |
要发送的问题 |
sourcePluginId |
/chat/new, /agents/detail |
Agent 来源 Plugin |
agentType |
/chat/new, /agents/detail |
Agent 业务类型 |
agentId |
/chat/new, /agents/detail |
旧链路兼容,不推荐 |
skillId |
/chat/new |
逗号分隔的 Skill ID |
pluginId / id |
/plugins/detail |
Plugin ID |
source |
全部 | 来源标识 |
launchId |
全部 | 唤端 ID |
traceId |
全部 | 外部 trace ID |
URL 参数必须做 encodeURIComponent。
Web 侧推荐封装
type InvokeQueryOptions = {
query: string
sourcePluginId?: string
agentType?: string
skillId?: string
source: string
}
async function invokeDesktopQuery(options: InvokeQueryOptions) {
const launchId = crypto.randomUUID()
const command = {
action: 'query',
query: options.query,
sourcePluginId: options.sourcePluginId,
agentType: options.agentType,
skillId: options.skillId,
source: options.source,
launchId,
}
try {
const res = await fetch('http://localhost:4097/desktop/deeplink', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify(command),
signal: AbortSignal.timeout(800),
})
if (res.ok) return { ok: true, channel: 'gateway', launchId }
} catch {
// fallback to protocol
}
const params = new URLSearchParams()
params.set('query', options.query)
params.set('source', options.source)
params.set('launchId', launchId)
if (options.sourcePluginId) params.set('sourcePluginId', options.sourcePluginId)
if (options.agentType) params.set('agentType', options.agentType)
if (options.skillId) params.set('skillId', options.skillId)
window.location.href = `accio://chat/new?${params.toString()}`
return { ok: true, channel: 'protocol', launchId }
}
接入注意事项
- Web 侧不要依赖本地
agentId。 - Web 侧要传
launchId,方便桌面端、Gateway、Web 三侧排查。 query有长度限制,当前最大 8000 字符。skillId支持英文逗号分隔多个 Skill,最多 20 个。sourcePluginId、agentType、skillId、pluginId只允许安全 ID 字符:字母、数字、.、_、:、@、/、-。- Gateway 只监听本机回环地址,不接受局域网机器直接调用。
- 协议唤起不适合做成功率精确判断,需要结合 Gateway 优先策略和安装引导兜底。
推荐测试样例
打开 Shopify Agent 详情:
accio://agents/detail?sourcePluginId=shopify-plugin&agentType=shopify-agent
向 Shopify Agent 发起 Query:
accio://chat/new?query=hi&sourcePluginId=shopify-plugin&agentType=shopify-agent
打开国际站生意助手详情:
accio://agents/detail?sourcePluginId=alibaba-com-seller-assistant&agentType=alibaba-com-seller-assistant
打开 Skills 页面:
accio://skills