Desktop 客户端边界
工作台展示与本机执行
Renderer 呈现服务端事件及本地草稿。需要本机能力的请求进入 Main,由本机执行上下文和对应宿主处理;显示中的任务状态不构成一份独立业务权威。
Desktop session 与 Server session 显式配对。2026-10-12 tip 起 chat 提交与观察统一走 Work 路径(register-runtime-v2-ipc 已删除,见证据块),runtime-v2.1 入口已从 chat 移除。图中只保留本轮三个仓库内有依据的客户端边界。
相关:agent-config-pipeline(agents 配置如何接到本主题能力面)。
设置与摄取合同收紧(2026-10-14 钉点)
设置只接受 v2 形状:旧设置迁移(config-migration.ts)与「恢复旧服务地址」入口已删除,旧形状(无版本/v1、aidaBase、明文 token)回落默认值,不留兼容开关。文档摄取 markSent 必须给出 intakeIds,空数组为无操作,不再整会话翻转。
aida-desktop 仓职责
- 负责:Renderer 呈现;Main 持有本机执行上下文、授权文件夹与绝对路径、PluginHost(管插件 Worker)、本机文件执行与回执。
- 本地存储:Main 的 AtomicJsonStore(write-state、授权夹等)是装置级投影,不授权服务端工作、不跨设备。
- 不持有:Run / IX / LF Operation / 业务效应的 SoT(在 Agent);断线重连只拉投影、续传回执。详见
state-authority。
reply_user 消息的展示(钉点 8eecd12081db)
Desktop 识别 reply_user_message 事件:记在当前 run 卡上,同一 messageId 重放不重复;再物化成独立助手消息行,放在最终回复之前,不并入最终正文。服务端默认不挂载该工具(见 enterprise-task-e2e),所以多数会话看不到这类消息。
过期卡「结束原任务」与续办展示(钉点 8eecd12081db)
- 结束原任务:只在卡状态为 expired 时出现。要停的 rootRunId 取自这张卡所属的消息或 owner 投影,几个来源不一致、会话对不上就拒绝,不从「当前 active run」推断;请求期间视图或观察身份变了也中止。先读服务端 active-run 视图:Runtime Work 经
stopOriginalRuntimeWork→ MainstopSubmission,以原提交身份(chat-submission:<clientRequestId>)持久停止,卡过期、窗口重载后仍有效;已有在线观察者就复用它的 abort,不发第二条命令。legacy run(active-run 返回 426)沿用服务端cancelRun。对话已被其他工作占用 → 不停任何任务。服务端同时会在下一轮受理时自动关闭只等过期卡的任务树(见state-authority)。 - 已收到答复 ≠ 暂停:Work 为
suspended且最近一张可见交互已 resolved,显示「已收到答复,等待后续处理」;否则仍是「处理已暂停」。 - 续办后的新问题:观察中的 Work 进入或离开等待(
suspended/pending_resume↔pending/running)时重新水合会话历史,续办中再问的问题卡能及时出现。以上都是界面投影,不改服务端状态。
Linux x64 平台与本机凭证(钉点 8eecd12081db)
- 平台:Linux x64 是支持平台,electron-builder 产出 x64 AppImage(
dist:linux可在 macOS 上交叉打包);skillHostPlatform不再需要AIDA_E2E_LINUX_TEST_ONLY;钉点 Desktop8eecd12081db起agentWirePlatforms过滤已删除,Skill 入口platforms线上枚举含linux(Agent ADR-0090 D3)。仓里的.gitlab-ci.yml已删除(提交说明:这个仓用不了 GitLab CI),没有 CI 打包任务。 - 发布链路已接上(代码层):发布脚本 targets 加了 linux-x64,这个目标跑
dist:linux,产出 AppImage +latest-linux.yml,不走 Velopack feed;Agentdesktop_distribution_releases平台 CHECK(ddl.ts与迁移 176)放行 linux-x64 插件行;Plugin 协议Platform枚举也加了 linux-x64。钉点 Desktop8eecd12081db起,package.json的linux.publish为 generic 更新源,发布脚本构建时以-c.linux.publish.url指到<base>/internal/linux-x64(26187f12修复 Linux 更新清单生成);部署脚本另维护固定下载地址AidaWork-linux-x86_64.AppImage,只在线上latest-linux.yml与本地产物一致时才复制(08f6d362,runbook 补齐四个平台固定下载与 feed 地址)。还差的:迁移 176 不随启动执行,各环境是否已跑未核;官方插件plugin.jsontargets 仍只有 darwin / win32;仓里有 0.1.62 / 0.1.63 发布提交,但 Linux 包是否真的上线、AppImage 自动更新是否在真机走通未核。证据:aida-desktop·apps/desktop/package.jsonL192–210 ·AppImage·4346d79eb364;aida-desktop·scripts/deploy-aida-updates.mjsL361–407 ·latest-linux.yml·4346d79eb364 - safeStorage 严格策略:Linux 上 Electron 可能静默选
basic_text(硬编码密钥,等同明文混淆)却仍报告「可加密」。Main 用strictSafeStorage包装:后端为basic_text/unknown即视为不可用,加解密直接抛错。凭证库因此退回 session-only(不落盘);提交观察日志在没有强加密时只留内存、跳过落盘(告警一次),有强加密时也改成后台尽力写盘,不再因此拒绝提交;非 KDE 且用户未指定时默认--password-store=gnome-libsecret。- 已核(代码):策略、Main 接线、凭证库 session-only 分支、单测「basic_text 下不写 vault 文件」均已读源码。
- 未核(真机):本轮未跑 Desktop 单测;未在真实 Linux 桌面(GNOME / KDE、有无 Secret Service)运行 Electron。等 Stanley 真机验证,不算通过。
Computer Use 与邮件连接(钉点 Desktop fb3e4fdfd5a2)
- Computer Use:Main
ComputerUseHost拥有唯一交互桌面 lease(Workers 不可造授权);方法computer.capabilities|listApps|listWindows|observe|act|release;八种窗口操作(click / setValue / typeText / pasteText / drag / pressKey / hotkey / scroll);渲染侧ComputerUsePanel/window.aidaDesktop.computerUse。真机 macOS/Windows 授权与截图链路未核。 - 邮件:
MailConnectorClient经/api/connectors/mail/authorize取authorizePath=/mailbox/connect#…,会话内打开连接;插件详情中aida-session邮箱连接的状态读取 Desktop 邮箱账号列表(与连接设置同源,已移除旧directory-batch目录归档)。邮箱读与附件下载仍走 JWT,不依赖 connect ticket。 - 证据:
aida-desktop·apps/desktop/electron/computer-use/computer-use-host.tsL32–33 ·ComputerUseMethod·4346d79eb364;aida-desktop·apps/desktop/electron/computer-use/computer-use-host.tsL180 ·Owns one interactive desktop·4346d79eb364;aida-desktop·apps/desktop/src/local-executor/ComputerUsePanel.tsxL34 ·computerUse·4346d79eb364;aida-desktop·apps/desktop/electron/auth/mail-connector-client.tsL92–115 ·authorize·4346d79eb364;aida-desktop·apps/desktop/electron/plugin-host/register-plugin-host-ipc.tsL81–112 ·listAccounts·4346d79eb364
会话冷启动水合与提交连续性核销(coldStartHydration & submissionContinuity)
- 游标驱动冷启动水合(
hydrateConversationColdStart):服务端历史分页在展示过滤前截断,因此空可见页仍可能有更早历史;Desktop 严格跟随服务端分页游标拉取,并在每步核对chatObservationIdentity()未切换(否则抛AbortError中止旧观察)。 - Carrier 消息投影(
projectWorkCarrierMessage):将同一rootRunId下的publicProcess快照合并(若rootRunId或conversationId失配则记录PUBLIC_WORK_PROCESS_BINDING_MISMATCH并丢弃),并按(interactionId, presentation.version, updatedAt)聚合该 carrier 作用域下的最新交互卡。 - 提交连续性核销与排队取消(
releaseRespondedChatSubmission/cancelQueuedChatSubmission):持久化的答复、拒绝或队列关闭回执仅核销其自身の发送意图(clientRequestId),不篡改原 Work 身份;核销前先经acknowledgeSubmissionObservation落盘确认,且若被准入拒绝(status === 'rejected')则自动恢复输入草稿(rejectedSubmissionId)。
证据与范围
aida-agent·docs/architecture/lifecycle-map.mdL42–98 ·77fe76838aa4(历史引用:该文档已在 aida-agent44d63e20退役,钉点e2adc9a3c325无此文件;见 ATLAS-DEBT)aida-desktop·CONTEXT.mdL1388–1418 ·Dual session identity·4346d79eb364(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT)aida-desktop·apps/desktop/electron/plugin-host/plugin-host.tsL1–59 ·4346d79eb364aida-desktop·apps/desktop/electron/agent-loop/register-runtime-work-ipc.tsL251–276 ·submitSubmission·4346d79eb364(register-runtime-v2-ipc 已删除,统一 Work 提交/观察)aida-agent·packages/agent/src/runtime/work/run-work-admission.tsL16–57 ·bindAdmittedWork·e2adc9a3c325aida-desktop·apps/desktop/electron/config/config-store.tsL279–319 ·normalizePersistedConfig·4346d79eb364aida-desktop·apps/desktop/electron/document-intake/intake-service.tsL164–172 ·markSent·4346d79eb364
结论来自固定版本的静态源码与合同阅读;实现存在、默认开关和生产启用分别判断。本站代码证据面板列出声明状态与具体限制。
aida-desktop·apps/desktop/src/chat/core/runTimeline.tsL294–306 ·reply_user_message·4346d79eb364aida-desktop·apps/desktop/src/chat/core/replyUserMessages.tsL11–39 ·projectReplyUserMessages·4346d79eb364aida-desktop·apps/desktop/src/chat/interaction-workbench/endOriginalWork.tsL33–74 ·endOriginalWorkForExpiredCard·4346d79eb364aida-desktop·apps/desktop/src/chat/interaction-workbench/ConnectedConversationInteractionWorkbench.tsxL893–916 ·ORIGINAL_WORK_BINDING_MISSING·4346d79eb364aida-desktop·apps/desktop/src/chat/core/runtimeWorkObservation.tsL354–376 ·stopOriginalRuntimeWork·4346d79eb364aida-desktop·apps/desktop/electron/agent-loop/register-runtime-work-ipc.tsL345–395 ·stopSubmission·4346d79eb364aida-desktop·apps/desktop/src/chat/responseDisplayState.tsL61–69 ·已收到答复·4346d79eb364aida-desktop·apps/desktop/src/chat/useDesktopSSEChat.tsL1202–1244 ·refreshWorkHistory·4346d79eb364aida-desktop·apps/desktop/shared/skill-execution-platform.tsL1–14 ·skillHostPlatform·4346d79eb364aida-desktop·apps/desktop/package.jsonL192–210 ·AppImage·4346d79eb364aida-desktop·scripts/publish-desktop.mjsL51–91 ·linux-x64·4346d79eb364aida-desktop·scripts/publish-desktop.mjsL941–981 ·dist:linux·4346d79eb364aida-agent·packages/agent/migrations/176_desktop_distribution_linux_x64.sqlL1–8 ·linux-x64·e2adc9a3c325aida-plugins·packages/protocol/schema/protocol.schema.jsonL31–36 ·linux-x64·a33ce3733365aida-desktop·apps/desktop/electron/agent-loop/submission-observation-journal.tsL153–195 ·encryption_unavailable·4346d79eb364aida-agent·packages/agent/src/config/ddl.tsL590–610 ·win32-x64·e2adc9a3c325aida-desktop·apps/desktop/electron/security/safe-storage-policy.tsL1–52 ·basic_text·4346d79eb364aida-desktop·apps/desktop/electron/main.tsL669–709 ·strictSafeStorage·4346d79eb364aida-desktop·apps/desktop/electron/security/safe-storage-policy.tsL1–52 ·basic_text·4346d79eb364aida-desktop·apps/desktop/electron/auth/credential-vault.tsL85–96 ·session-only·4346d79eb364aida-desktop·apps/desktop/electron/security/safe-storage-policy.test.tsL84–95 ·session-only·4346d79eb364aida-desktop·apps/desktop/electron/auth/credential-vault.tsL85–96 ·session-only·4346d79eb364
STA-188 业务 Task 续办身份(钉点 4346d79eb364)
从业务 Task CTA 续办时只传 businessTaskId / engagementId 等服务端可校验身份,不发送客户端 capabilityId(客户端能力不是 Host Work 路由授权)。
aida-desktop·apps/desktop/src/app-surfaces/engagements/EngagementsSurface.tsxL305–315 ·4346d79eb364