Team API 兼容性¶
Team API 兼容性边界¶
当前的远程连接通过三个有序的 WebRTC DataChannels 使用 Team API 协议 v8:rpc、events 和 files。每个 RTCPeerConnection 由一个沙盒化的隐藏 Chromium 页面持有。Electron 主进程使用 MessagePort,并以 ArrayBuffer 的形式传输二进制数据。Signal 仅承载 SDP 和 ICE,但 agent 的 Slack 应用的 Slack 请求除外(参见 Messaging connections)。OpenBot Mobile 使用相同的票据、认证记录、帧封装、RPC 编解码器和事件流。在 Expo Go 中,一个 Expo DOM 组件在隐藏的 WebView 内持有浏览器的 RTCPeerConnection,仅将可序列化、已验证的命令和事件传递给原生 React UI;无需原生 WebRTC 模块或开发构建。
主机的网络路由偏好(openbot-remote-network-route-v1.json)适用于与该计算机的每一条远程连接。使用 private 模式时,主机不向 WebRTC 提供任何 ICE 服务器,隐藏页面会移除所有不在私有地址(RFC 1918、100.64.0.0/10、fc00::/7 或 .local)上的 host 候选的本地、远程和 SDP 候选。切换到 private 会关闭已连接的 peer,因此每个 peer 都会在无中继的情况下重新连接。远程桌面运行时为每个流从主进程读取其 ICE 服务器并将其发送给查看者,因此其媒体也没有中继。其候选不会被过滤;直接的公网 IPv6 路径仍然可能。
抽屉和连接设置中的移动服务器标签描述的是经过认证的应用连接,而不是成员资格或 Signal 在线状态。当移动端处于活动状态时,每个成员资格都有自己的传输和恢复控制器。当返回到应用时,选中的服务器首先连接;其他服务器在它在线后或 3 秒后变为活动状态。切换服务器会更改可见的工作区,而不会关闭其他连接。iOS 的 inactive 转换不会干扰连接。进入后台会保留最后的连接状态并暂停恢复;在后台收到的传输失败会被保留以备恢复时处理。只有配对的桌面端是本地(Local);其他服务器无论账户角色如何都是远程(Remote)。连接在兼容性检查成功且 agents、读取状态和分区加载完成后变为在线(Online)。这三项读取同时进行。在线后缓存的会话会重新加载,首先加载打开的会话;之前未加载的聊天会在其打开时加载。传输失败和重连尝试显示为离线(Offline),协议失败显示为连接错误(Connection error)。现有的 RTC 连接更新和恢复控制器是事实来源;指示器不添加任何轮询或健康检查请求。
回到前台时会复用健康的连接并重新读取工作区,而不显示重连。离开的时间决定了连接会发生什么:少于 30 秒则保留该路径。30 秒后主机已停止使用该路径(ICE consent),因此 peer 会更新其 Signal socket 并重新启动 ICE;已断开连接的主机以新的指纹应答,peer 会立即失败,而不是在读取超时后失败。在返回检查期间丢失的连接会立即被替换,没有倒计时,与检查失败时的情况相同。160 秒后,Signal 已告知主机丢弃该连接(120 秒 socket 空闲超时,再加 30 秒),因此 peer 会在同一会话上立即被替换,无需恢复问候,并且第一次尝试就会连接。应用离开时处于在线(Online)状态的服务器,在返回后的第一次尝试期间会保持其在线外观,最长可达 5 秒(server-connection.tsx 中的 QUIET_RESUME_MS):服务器处于 resuming 状态,showsOnline 为 true,并且不会显示重连状态、变灰的头像或变灰的聊天。对处于 resuming 状态的服务器发出的工作区请求会等待在线(Online)而不是失败;当尝试失败、应用离开或服务器关闭时,它会失败。发件箱、队列、历史记录重新加载和浏览器视图仍然读取实时的 state。失败的尝试、冷却期、协议停止或 5 秒结束会显示正常的重连状态。应用离开时不在线的服务器会立即显示其状态。被取消的读取和事件重置会请求数据同步,而不会在健康连接上显示重连。邀请选择和手动刷新复用同一个控制器。
短暂的 RTC 断开状态有 15 秒的恢复窗口,包括在恢复时;失败或关闭状态会立即驱动恢复。Signal 的 rate_limited,或带有代码 1008 且没有错误帧的关闭,会使下一个 Signal socket 等待 60 秒;另一次带有代码 1008 的拒绝,例如无效票据,会立即重新连接。进入后台会暂停宽限计时器并取消待处理的读取,使它们无法阻塞恢复。显式刷新会绕过重试冷却,而不会与待处理的连接尝试重叠。原生/DOM 邮箱通过 ID 承载并发命令。切换或断开连接会立即取消待处理的调用者;peer 代次会拒绝来自已被取代的主机的延迟回调。
在正常桌面端和开发主机中,持久化的托管偏好会在启动时恢复。单独启动开发 HTTP API 不会发布 WebRTC;Mobile Connect 需要已发布的主机。单独的开发测试客户端角色从不自动发布。Mobile Connect 票据和 QR 码绑定已启动的主机 ID 和 SHA-256 公钥指纹。移动端在兑换时和对照目录验证该绑定,固定该密钥,并选择该主机而不是第一个账户拥有的桌面端。旧的未绑定 QR 码需要重新生成。永久 Mobile Connect 链接使用相同的 URL 和兑换路由,因此已发布的手机应用可以接受它。它具有相同的主机绑定,并且可以多次兑换。D1 只保留其哈希值。当桌面端替换或撤销它,或创建它的桌面会话结束时,它会停止工作。桌面端将链接保存在其加密的会话文件中,并在退出登录时删除它。
mobile_auth_sessions.connect_link_host_id 记录其链接在手机上登录的主机。撤销会使这些手机退出登录,即使链接行随其桌面会话一起消失,设备列表也会显示每部手机的登录方式。当桌面端取消其显示的代码时,DELETE /v1/mobile-auth/ticket?host= 会消耗该主机未使用的一次性代码。手机会话是账户级的:手机会打开账户目录中的每个主机,而不仅仅是其代码所属的主机。只有当该主机在目录中(具有活动成员资格和设备密钥)时,GET /v1/mobile-auth/devices?host= 才会列出账户的手机,以便它们可以打开它。没有 host 时,该路由会像以前一样返回所有手机。桌面端的已连接设备列表会发送其已启动的主机,并且在没有主机身份时不显示任何手机。账户会话仍然会列出并撤销每部手机。
手机也可以使用电子邮件验证码登录。它通过 /v1/auth/email/start 请求验证码,并通过 /v1/mobile-auth/email/verify 进行验证,后者会一次批量写入 auth_sessions 行及其 mobile_auth_sessions 行;/v1/auth/email/verify 则会创建桌面会话。此会话没有主机绑定:手机会随会话存储 signIn: "email",连接到账户目录中的每个主机,并在首次使用时固定每个主机密钥,就像 Web 客户端一样。没有主机且没有标记的存储会话仍然是旧的 QR 会话,会被撤销。开发 LAN 允许列表将两个电子邮件路由保留在回环地址上,因为开发代码是从其 challenge ID 生成的。
桌面端邀请 QR 码包含与“复制链接”相同的单次使用链接。已登录的移动端扫描器会验证该链接,并在接受之前打开邀请审查。这些代码加入一个服务器;Mobile Connect 代码登录到桌面账户。移动端会保持配对的主机为抽屉分隔线上方的默认服务器,直到用户更改它,并在第一个服务器上打开。两个客户端都从 D1 的索引 remote_memberships / remote_hosts 连接中读取账户级成员资格。离线的配对桌面端不会移除其他成员资格,移动端会独立地直接连接到每个主机。冷启动会刷新账户目录。两个客户端在活动状态下每 15 分钟再次检查一次。并发的目录读取会合并;非活动客户端不轮询。移动端进入后台会停止计时器,进入前台会开始新的 15 分钟间隔。iOS 的 inactive 转换,包括 Notification Center,不会触发检查或重置计时器。会话撤销、显式刷新和完成的邀请接受可以更早地刷新。丢失健康的连接也会请求成员资格协调;单独的传输失败永远不会移除服务器。
移动端成员控制使用相同的账户端点:所有者和管理员可以邀请、更改其他成员的角色、移除访问权限和结束其他成员的会话。没有人可以更改或移除所有者,只有所有者可以结束所有者的会话。packages/contracts/src/ipc-team-host.ts 中的 canAdministerServer 是客户端和主机的唯一角色检查。在具有账户目录的主机上,Team API 成员的 PATCH 和 DELETE 通过 HostService 写入 D1,因此下一次目录同步不会撤销它们;每次同步都会关闭 D1 已移除、禁用或赋予其他角色的成员的主机会话。D1 保留已撤销的成员资格记录并使受影响的会话失效;两个客户端都将非活动成员从活动列表和计数中排除。在旧的 HTTP(S) 主机上,桌面端会单独公开非活动记录,以便在新邀请之前移除;它不会恢复暂停/恢复控件或更改已发布的邀请规则。移动端将可共享链接与电子邮件邀请分开。电子邮件模式会创建绑定地址的邀请,并通过与桌面端相同的投递端点发送;投递失败会撤销新邀请。已发布的恢复端点与旧客户端保持兼容。成员和邀请列表在更改后或收到显式请求时刷新。
会话读取游标属于团队成员,并在该成员的设备之间共享。推进游标会发出会话失效通知,但不包含读者的身份或游标;即使会话内容修订版未更改,客户端也会重新加载自己的读取状态。移动端仅在前台、聚焦的聊天中确认已渲染的回复(位于最新消息处)。移动端附件使用 packages/contracts/src/attachment-files.ts 中共享的桌面文件名允许列表。原生的文档和照片选择器以及聊天内相机面板会准备本地草稿。现有的 Team 文件协议会在一条消息提交有序的草稿 ID 之前将它们上传到主机。由于原生/DOM 桥会复制 Base64 数据,移动端将每个文件限制为 10 MB。下载使用相同的经过认证的文件通道,验证大小、块顺序和 SHA-256,并通过命令桥将已验证的字节传回。移动端会对下载进行排队以限制并发复制。图片预览保持宽高比。音频和视频在聊天中播放。其他文件从 filePreviewKindForFile 获取桌面预览类型:Markdown、文本、HTML、PDF 和 .xlsx 文件在预览屏幕中打开。packages/contracts/src/spreadsheet-workbook.ts 中的 .xlsx 解析器在 DOM 组件中运行,因为它需要 DOMParser。iOS 在无脚本的原生 Web 视图中显示 PDF;Android 在 DOM 组件中使用 pdf.js 绘制其页面。视觉回复在聊天中显示其页面,无脚本。没有预览的文件通过临时缓存文件使用系统共享面板。
移动端聊天通过 conversation-page 加载最新的 50 条消息,并通过游标加载更早的页面。
其 Legend 列表(来自 @legendapp/list/keyboard 的 KeyboardAwareLegendList)仅渲染视口附近的行,
获取所有已加载的消息,并在添加更早页面时保持可见位置。
只有当消息本身发生变化时,一行才会重新渲染;其他行状态来自 React 上下文。
回复引用随每个页面一起传递。无重叠的页面会替换缓存的窗口,因此
重连不会留下不可见的间隙。较早页面的响应不会推进实时修订版本。
内存中的会话存储按 agent 通知订阅者,并每动画帧合并一次流式文本。
当最后一个订阅者离开时,超过 50 条消息的窗口会被释放;完整历史记录仍保留在宿主数据库中。
连接恢复优先处理已观察的聊天。
移动端聊天将视口和输入框的尺寸测量保存在其运动控制器中。最后一条用户
消息是列表 anchoredEndSpace 的锚点:列表在其下方添加一个空白区域,并且
流式回复消耗该空白区域而不自动滚动。初始历史记录定位和
首次发送/首次响应动画是独立的状态。待发送消息气泡通过
宿主回执 ID 协调,而不是消息文本。
移动端回复使用现有的 replyToMessageId 字段,并在投递后保留其来源。
Agent 气泡支持滑动回复和带触觉反馈的长按操作面板。该
面板有一个嵌套的原生栈用于操作和文本选择;消息文本保留在内存中,
不在路由参数中。发送失败会恢复回复目标,输入框可以取消它。
选中的移动端附件使用现有的 WebRTC 文件帧,后接附件上传端点;
原生/DOM 桥接器将每个文件限制为 10 MB,并在其连接被替换时取消传输。
可选的 conversation-unread 能力添加了一个独立的 POST /v1/agents/:id/conversation/unread
操作。普通的已读确认保持单调;显式的未读重置持久化在
宿主的 SQLite 中并发出相同的失效。较旧的宿主仅禁用此可选操作。
移动端外部链接通过 Expo Router 的 +native-intent 和链接功能进入。
邀请和 Mobile Connect 令牌保存在有界的内存存储中;导航仅携带
本地请求 ID。邀请会等待登录完成,并在显式加入前显示已验证的宿主预览。
Mobile Connect 链接需要确认,不能替换已登录的账户。
唯一的例外是开发构建:bun run dev:mobile 使用 simctl openurl 打开链接,
__DEV__ 构建仅在其账户服务是回环或私网 http: 源时,无需确认即可兑换该链接。
发布构建始终使用确认流程。
插件链接在应用内浏览器中打开其经过验证的公共页面。不支持的链接显示
安全的后备页面。在 iOS 上,共享扩展独立发送共享内容,不经过应用:它显示
agents,一个隐藏的 Web 视图运行 share-sender.html,这是 Team 客户端
(apps/mobile/src/features/share/extension/share-sender.ts) 的一个构建,用于连接、上传文件并
发送消息。该扩展自行发出每个账户服务请求,并拒绝任何其他
来源。它按应用中的顺序读取服务器,带头像的 agents,
ShareExtensionSync 写入 App Group 的强调色和本地化文本,以及来自
仅应用和扩展共享的钥匙串组的会话。应用为每个发送目标 agent 捐赠
INSendMessageIntent,附带其头像,使共享面板优先显示这些 agents。
在没有数据、应用锁开启、单条消息无法容纳的共享内容,或用户交给
应用处理但发送失败的情况下,扩展会像之前一样打开 openbot://expo-sharing。Android 始终使用该
路径。共享内容在原生存储中等待登录完成。共享
面板将其文件移入应用缓存,用户选择一个 agent,该聊天的输入框会获得
文本和文件,这些文件遵循上述附件规则。手机读取共享链接的响应头;
最多 10 MB 的图片链接会被下载并作为文件而不是链接呈现。
永久邀请元数据来自共享的 Team 客户端;撤销会阻止
新的加入,而不会移除现有成员。
iOS 将 https://openbot.run/join 和 https://openbot.run/agents/* 与 run.openbot.mobile 关联。关联域名的更改
需要新的原生应用构建以及网站关联文件的部署。Android
继续在浏览器中打开 HTTPS 邀请,其按钮打开 openbot://join。启用
经过验证的 Android App Links 需要发布应用签名证书的 SHA-256 指纹、
/.well-known/assetlinks.json 以及匹配的已验证 /join 意图过滤器。此仓库中尚未存储
任何证书指纹。
移动端设置使用一个原生表单面板,具有稳定的 detents 和嵌套的 Expo Router 栈。
内部页面在面板内推送并使用原生返回导航;独立表单仍然是
适应内容的面板。两者都复用 SheetScrollView。General、Profile、Connections 和 About 使用 HeroUI 排版和共享
表单字段;外观选择器仍然是原生的 Expo UI 控件。外观存储在 SecureStore 中,仅限设备本地;
Uniwind、导航和原生表单宿主共享所选的浅色/深色/系统主题。Profile
更改和账户会话管理使用现有的账户端点,profile 写入
以存储的凭据仍与发起会话匹配为条件。
移动端客户端使用与桌面端相同的 /v1/me/profile、/v1/me/avatar 和
/v1/mobile-auth/devices?includeDesktop=true 端点;最后一条路由的历史
名称并不限制其仅用于手机。头像上传通过 Expo fetch 直接发送经过验证的二进制字节,
无需从类型化数组构造 React Native Blob。Profile 读取、写入及其 UI 状态的应用
一起串行化。在编辑后排队的读取可以应用更新的远程 profile;在后续
编辑之前的读取不能覆盖该编辑。结果仅应用于发起登录。
账户会话查询以每次登录为范围,不将凭据包含在查询键中,
在放弃时取消,并在账户切换时移除。HTTP 401 仅清除其
发起的凭据;传输失败保留会话以供重试。
账户 profile 写入在返回前,将 account-profile-changed 失效排入现有的签名
账户到 Signal 发件箱。Worker waitUntil 在 profile 保存响应路径之外交付通知,
每个请求有五秒超时和发件箱重试。Signal 仅将可选帧转发给该用户的
已验证套接字;该帧不包含 profile 或凭据。桌面端和移动端在收到通知、
冷启动以及活跃期间每 15 分钟通过账户 API 获取 profile。
成员资格写入以同样方式将 account-servers-changed 失效排入队列,目标
是账户而不是宿主:接受邀请、更改成员资格以及注册该账户
之前没有的宿主,都会为服务器列表已更改的成员排队一个失效。
重新发布现有宿主会轮换其凭据而不更改列表,也不排队任何内容。Signal 将其转发给该账户
持有的每个已验证套接字,并且该帧不提及任何服务器。这就是在一个设备上加入的服务器如何到达
同一账户的其他设备。桌面窗口聚焦不会触发自动账户或目录
检查;未持有 Signal 套接字的设备会在下一次 15 分钟检查时发现更改。
移动端每个账户端点使用一个共享的生命周期订阅和一个刷新控制器。
返回前台会检查绝对新鲜度:成功的账户和目录响应在 15 分钟内保持
新鲜,后台时间计入该截止时间。移动端失败的检查在前台时
一分钟后重试。并发请求通过 Deferred 共享一个 Effect 结果;在请求期间收到的
失效会在成功后导致一次后续检查。iOS 单独的 inactive 不会重置这些截止时间。
存储的移动端会话在启动验证完成之前即可用;网络故障会保留
它们,验证结果仅应用于发起登录。
显式 profile 失效会触发更早的检查,并在移动端位于
后台时延迟。Signal 就绪不会触发 profile 检查;账户计时器仍然独立
于传输恢复。桌面端失败的自动检查使用相同的间隔。
每个移动端服务器有一个连接恢复所有者。它在返回前台时重新加载工作区读取,
而不会将健康的服务器更改为 connecting 或禁用其操作。这些读取复用
现有的 WebRTC peer,不请求新的账户会话或票据。第一次替换
在实际连接丢失后立即开始。
所需的兼容性读取有三秒超时,用于检测过时的开放通道。延迟
在失败的替换后生效,并在应用切换后持续。peer 拥有 Signal 套接字恢复,
而不是完整的连接重试。普通传输丢失不会使账户目录失效。
较旧的 Signal 客户端忽略此可选事件。API 和 Signal 都需要事件支持才能推送;
定期检查在 Signal 不可用时仍作为后备。未更改的响应不会
发布新的身份。桌面端忽略被本地编辑、退出登录或关闭所超越的读取;
其中央认证更改事件会更新渲染器和宿主身份。移动端抽屉和设置
都显示会话名称,并针对其账户 API 解析头像路径。
移动端隐藏/置顶聊天偏好是设备本地的,按账户 API、账户 ID 和主机 ID 持久化在 SecureStore 中;它们不属于共享侧边栏布局或对话已读状态的一部分。
账户/设备会话和逻辑远程会话刻意不设基于时间的过期期限;一个有限的 Date 最大截止期限保留了现有的数字线上契约。配对码、连接票据和 Signal 恢复凭据仍然是短时有效的。每个逻辑远程会话都绑定到其发起账户凭据。原子化的 D1 触发器在登出/设备撤销时结束该凭据的远程会话,并将断开操作排队;其他手机保持连接。旧版未绑定会话在撤销时会在整个账户范围内被结束,因为其发起凭据未知。
移动端登出会保留加密凭据和本地会话,直到账户 API 确认撤销。如果 DELETE 响应失败,移动端会验证同一 token:401 确认其不再有效,并立即完成登出。成功的会话检查或不确定的网络/服务错误会保留凭据以供重试;迟到的结果不能清除更新的登录。
桌面端在重试期间会保持远程连接错误在工作区中可见。成功连接后清除该错误。新的连接序列或恢复在线会重新加载活动工作区,而不会重新挂载其提供者,因此失败的刷新会保留缓存数据。服务器切换仍会销毁旧作用域;加载世代和作用域守卫会拒绝迟到的响应。
主机通过新增的 Signal 问候 multiplex 标志选择加入;旧版桌面端保持其单对等端限制,因此第二个手机不能取代现有客户端的连接。Signal 按逻辑会话对连接进行多路复用,隐藏的桌面渲染器为每个设备持有一个独立的 RTC 对等端。主进程按对等端分别维护认证、RPC 缓存、文件暂存和事件流。传输清理会关闭本地访问,而不会撤销替代连接。设置 → 个人资料 → 账户会话会列出并撤销桌面端和移动端凭据。账户 API 现有的移动设备路由通过 includeDesktop=true 暴露这些内容;其默认的仅移动端行为保持不变。响应包含会话 ID 和活动元数据,绝不包含 token 或 token 哈希,所有操作都限定在已认证账户范围内。
Cloudflare 签发短时效的 ES256 连接票据并存储逻辑会话。Signal 签发 10 分钟的恢复 token,因此短暂的 Signal 更新不会结束活动的 WebRTC 连接。Signal 在本地验证可信且未过期的恢复 token。Signal 重启后,token 的首次使用会检查一次持久控制平面。过期的 token 也需要一次持久检查,Signal 才会签发替代 token。后续重连使用内存中的信任缓存。这不是心跳机制。
会话结束和访问变更使用持久化的 D1 outbox。Cloudflare 立即将每次撤销发送给 Signal,并通过调度任务重试失败的投递。这样可以在 Signal 暂时不可用时保持重连验证的本地化,同时不丢失撤销。
协议 v1 为兼容性测试夹具而保持冻结,但其公共 HTTP、WebSocket 和 Cloudflare Tunnel 传输已退役。旧的公共端点返回 host_update_required。
桌面客户端以 GET /v1/compatibility 开始每次远程连接。响应包含主机应用程序版本、Team API 协议版本的最小值和最大值,以及主机能力。客户端在共享范围内选择最高的协议。应用程序的 SemVer 不用于选择或拒绝协议。
首个发布的 Team API 协议是 1。后续所有 HTTP 请求都包含 OpenBot-Protocol-Version 和 OpenBot-App-Version。事件套接字使用 openbot-team-v1 WebSocket 子协议。没有兼容性端点的主机被视为旧主机并被阻止。没有必需协议头的请求被视为旧客户端并被阻止。
每个协议在 packages/contracts/src/team-protocol 中都有冻结的编解码器(codec)和适配器。v1 HTTP 编解码器拥有固定的路由注册表,并在适配器转换当前值之前验证 JSON 请求和响应。上传、下载和其他二进制路由使用相同的协商头和错误信封。主机不会将当前服务或 IPC 值直接写入网络。破坏性变更或语义变更会添加新的协议目录和注册表条目。已发布的适配器保持其原始含义。
从协议 8 开始,提供者 ID 和认证类型(auth kinds)是开放值。新的提供者是一个新值,而不是新协议。客户端会保留来自其不认识的提供者的 agent,并将其显示为禁用状态,附带更新提示。参见 Providers 了解冻结列表,这些列表会向低于 8 的对等端隐藏新提供者。
能力描述增量行为。客户端在设置事件作用域时发送其能力列表。主机仅当客户端声明了相关能力时才发送可选事件。缺失的能力仅禁用该功能。未知的可选事件被忽略。格式错误的已知事件会以 protocol_error 关闭连接,因为客户端无法安全地应用它。
可选的 agent-memories-v1 能力增加了三条 POST 路由。/v1/agent-memories/page 返回最多 256 条记忆。/v1/agent-memories/selection 返回最多 256 条选择记录、agent ID 和 essential-memory 的字节使用量。两者都使用递增的记忆 ID 和 after 游标(第一页为 null)。客户端验证所有者和游标顺序。编辑不会在页面之间移动 ID。跨多个页面的读取不是原子快照;下次刷新会看到并发更改。/v1/agent-memories/inclusion 使用预期修订版本更改最多 25 条选择,并返回空确认;客户端随后再次读取选择页面。每条路由都需要认证和可见的 agent。选择写入使用与现有记忆写入相同的成员访问权限。用户选择覆盖自动选择。
已发布的完整列表 GET 路由、记忆结构和 2 MiB 帧限制保持不变。新客户端连接到旧主机时,保留文本编辑功能并隐藏选择控件。旧客户端可以在新主机上编辑文本,而无需更改包含状态。存储选项仍为 64、128、256 和 512。降低该设置绝不会删除现有条目。
只有必要的记忆会进入启动指令,且该块限制为 8,192 UTF-8 字节。Claude 改为通过用户轮次获取该块:首次轮次和压缩(compaction)后提供完整块,记忆编辑后仅提供变更内容。记忆变更因此会保留缓存的系统提示词,并且不会重新启动 Claude 查询。配置文件变更仍会重新启动查询。已保存的记忆保留在主机上的 SQLite 中。代理可以使用有界本地搜索和按 ID 分页的列表来召回其他条目。FTS5 使用 unicode61 和 BM25。查询会匹配任何字面术语。unicode61 不进行词干提取,因此长度不少于 6 个字符的术语还会作为其前 N 个字符的前缀进行匹配,其中 N 为去掉最后 3 个字符后的全部字符数,且至少为 4 个字符:"closing" 也能找到 "closes"。得分相同时,以最新更新优先,其次以记忆 ID 优先。搜索最多返回 10 条结果,维护页面最多返回 25 条。两种响应的上限均为 8,192 UTF-8 字节。搜索索引保持本地。必要的提示词文本和请求的工具结果通过现有的秘密脱敏路径发送到当前提供商。
选择元数据与已发布的记忆结构相互独立。迁移 32 会保留记忆文本、ID 和日期,并优先选取近期手动条目,然后才是近期自动条目。同一个序列化器会在迁移、变更和提示词生成期间检查完整的提示词块。自动文本和选择变更将保持待处理状态,直到该轮次成功完成。提交时会再次检查所有权、修订版本、用户选择和容量。代理工具无法更改或删除用户控制的选择。用户可以解除该控制,而无需更改其包含状态。
Team API 失败时使用包含 error 和稳定 code 的 JSON 错误信封。兼容性代码为 client_update_required、host_update_required 和 protocol_error。在桌面连接状态中,身份验证失败和网络失败分别映射为 authentication_required 和 network_unavailable。已确认的兼容性或协议错误会停止数据平面请求和自动重连,直到用户选择 Retry、重新启动或更新。
协议支持没有固定的时间或版本限制。移除协议属于例外性的架构决策。移除的前提是存在安全问题、数据丢失风险、无法保持的语义,或无法在适配器中控制的技术成本。该决策还必须包含变更日志条目、更新说明、针对旧客户端/新主机和新客户端/旧主机两个方向的测试,以及清晰的阻塞式 UI。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 openbo/openbot