远程组件宿主桥接
宿主桥接连接远程组件 iframe、工作台宿主和插件视图提供器。它不是任意远程调用通道:每项能力都必须同时具有清单声明、宿主消息处理和对应的服务端实现。三层能力契约
缺少任意一层时,该能力都不应执行。
消息信封
所有消息使用固定通道和协议版本:- iframe 加载完成后发送
ready。 - 宿主使用
init返回instanceId、视图清单、初始查询、语言、主题和调试配置。 - 后续消息必须携带匹配的
instanceId。 - 请求与响应使用同一个
requestId。 - iframe 只接受
window.parent发出的消息;宿主只接受当前 iframecontentWindow发出的消息。
支持的消息
宿主发送给 iframe:
iframe 发送给宿主:
能力映射
TypeScript 桥接客户端
将桥接代码集中在bridge.ts,不要让业务组件直接拼接消息。
requestData()、executeAction() 和 invokeClientCommand() 等具名方法。桥接层返回稳定错误代码,由 UI 多语言层转换成用户可见文案。
查询数据
XpertViewQuery.parameters 只支持标量或标量数组。复杂筛选条件应序列化为明确的 JSON 字符串参数,并由提供器安全解析。
大型表格应使用服务端分页。远程组件不要一次把所有记录加载到 iframe。
执行操作
普通业务变更使用 JSON 操作:actionKey 必须存在于 manifest.actions,且传输方式必须匹配。提供器仍需校验目标对象、当前用户和租户/组织范围。
文件上传使用 executeFileAction,不要把二进制内容或 Base64 放进 JSON 操作。文件预览与下载使用 requestFileAccess,由宿主换取有时效的访问授权。
客户端命令
客户端命令用于宿主本地 UI 行为,不调用插件提供器。例如发送 Assistant 消息、设置 Assistant 上下文、打开文件或导航到另一工作台视图。 它是一个封闭的三方契约:- 源视图在
manifest.clientCommands中声明命令键。 - 当前宿主注册同名处理器。
- 远程组件通过
invokeClientCommand调用,并处理结构化失败结果。
宿主事件
远程组件可以订阅宿主归一化后的事件,例如 Agent 中间件工具完成:refresh。远程组件优先使用 forward,根据业务 ID 只刷新受影响的数据区域,并在本地存在未保存编辑时避免静默覆盖。
初始化、主题和多语言
以init.locale 为准,在入口处一次性归一化为 BCP 47 语言标签,例如 en-US、zh-Hans 和 zh-Hant。不要在业务组件中根据语言直接选择文本。
应用 init.theme.tokens 后,调用 installShadcnThemeVars() 安装语义主题变量。调试日志由 init.debug.enabled 控制;不要根据 URL、主机名或平台身份猜测开发环境。
不要依赖 localStorage 或 sessionStorage。临时状态保存在 React 状态中,持久状态通过宿主桥接写入服务端。
安全检查
- 不向 iframe 传递访问令牌、API 地址、Assistant ID、租户 ID 或组织 ID。
- 不让 iframe 自行选择
hostType或hostId。 - 不执行清单未声明的操作、文件能力或客户端命令。
- 不在日志中输出令牌、文件内容、完整业务快照或个人敏感信息。
- 提供器对每次读取和变更重新执行授权与租户/组织隔离。
- 对消息来源、协议版本、实例 ID 和请求 ID 添加自动化测试。