AIDAWORK / ARCHITECTURE

Desktop 客户端边界

独立图页 ↗
机制说明(SoT)图是辅读 · 结论以说明与证据为准

Renderer 呈现服务端事件及本地草稿。需要本机能力的请求进入 Main,由本机执行上下文和对应宿主处理;显示中的任务状态不构成一份独立业务权威。

本页可直接往下读完整机制说明,不需要「演示 / 播放故事」。术语不熟先看 术语表。

先读机制说明,结论以说明与证据为准 · 基于固定代码版本核验 · 部署状态另行确认

机制说明(全文)

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 → Main stopSubmission,以原提交身份(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;钉点 Desktop 8eecd12081db 起 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;Agent desktop_distribution_releases 平台 CHECK(ddl.ts 与迁移 176)放行 linux-x64 插件行;Plugin 协议 Platform 枚举也加了 linux-x64。钉点 Desktop 8eecd12081db 起,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.json targets 仍只有 darwin / win32;仓里有 0.1.62 / 0.1.63 发布提交,但 Linux 包是否真的上线、AppImage 自动更新是否在真机走通未核。证据:aida-desktop · apps/desktop/package.json L192–210 · AppImage · 4346d79eb364;aida-desktop · scripts/deploy-aida-updates.mjs L361–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.ts L32–33 · ComputerUseMethod · 4346d79eb364;aida-desktop · apps/desktop/electron/computer-use/computer-use-host.ts L180 · Owns one interactive desktop · 4346d79eb364;aida-desktop · apps/desktop/src/local-executor/ComputerUsePanel.tsx L34 · computerUse · 4346d79eb364;aida-desktop · apps/desktop/electron/auth/mail-connector-client.ts L92–115 · authorize · 4346d79eb364;aida-desktop · apps/desktop/electron/plugin-host/register-plugin-host-ipc.ts L81–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.md L42–98 · 77fe76838aa4(历史引用:该文档已在 aida-agent 44d63e20 退役,钉点 e2adc9a3c325 无此文件;见 ATLAS-DEBT)
  • aida-desktop · CONTEXT.md L1388–1418 · Dual session identity · 4346d79eb364(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT)
  • aida-desktop · apps/desktop/electron/plugin-host/plugin-host.ts L1–59 · 4346d79eb364
  • aida-desktop · apps/desktop/electron/agent-loop/register-runtime-work-ipc.ts L251–276 · submitSubmission · 4346d79eb364(register-runtime-v2-ipc 已删除,统一 Work 提交/观察)
  • aida-agent · packages/agent/src/runtime/work/run-work-admission.ts L16–57 · bindAdmittedWork · e2adc9a3c325
  • aida-desktop · apps/desktop/electron/config/config-store.ts L279–319 · normalizePersistedConfig · 4346d79eb364
  • aida-desktop · apps/desktop/electron/document-intake/intake-service.ts L164–172 · markSent · 4346d79eb364

结论来自固定版本的静态源码与合同阅读;实现存在、默认开关和生产启用分别判断。本站代码证据面板列出声明状态与具体限制。

  • aida-desktop · apps/desktop/src/chat/core/runTimeline.ts L294–306 · reply_user_message · 4346d79eb364
  • aida-desktop · apps/desktop/src/chat/core/replyUserMessages.ts L11–39 · projectReplyUserMessages · 4346d79eb364
  • aida-desktop · apps/desktop/src/chat/interaction-workbench/endOriginalWork.ts L33–74 · endOriginalWorkForExpiredCard · 4346d79eb364
  • aida-desktop · apps/desktop/src/chat/interaction-workbench/ConnectedConversationInteractionWorkbench.tsx L893–916 · ORIGINAL_WORK_BINDING_MISSING · 4346d79eb364
  • aida-desktop · apps/desktop/src/chat/core/runtimeWorkObservation.ts L354–376 · stopOriginalRuntimeWork · 4346d79eb364
  • aida-desktop · apps/desktop/electron/agent-loop/register-runtime-work-ipc.ts L345–395 · stopSubmission · 4346d79eb364
  • aida-desktop · apps/desktop/src/chat/responseDisplayState.ts L61–69 · 已收到答复 · 4346d79eb364
  • aida-desktop · apps/desktop/src/chat/useDesktopSSEChat.ts L1202–1244 · refreshWorkHistory · 4346d79eb364
  • aida-desktop · apps/desktop/shared/skill-execution-platform.ts L1–14 · skillHostPlatform · 4346d79eb364
  • aida-desktop · apps/desktop/package.json L192–210 · AppImage · 4346d79eb364
  • aida-desktop · scripts/publish-desktop.mjs L51–91 · linux-x64 · 4346d79eb364
  • aida-desktop · scripts/publish-desktop.mjs L941–981 · dist:linux · 4346d79eb364
  • aida-agent · packages/agent/migrations/176_desktop_distribution_linux_x64.sql L1–8 · linux-x64 · e2adc9a3c325
  • aida-plugins · packages/protocol/schema/protocol.schema.json L31–36 · linux-x64 · a33ce3733365
  • aida-desktop · apps/desktop/electron/agent-loop/submission-observation-journal.ts L153–195 · encryption_unavailable · 4346d79eb364
  • aida-agent · packages/agent/src/config/ddl.ts L590–610 · win32-x64 · e2adc9a3c325
  • aida-desktop · apps/desktop/electron/security/safe-storage-policy.ts L1–52 · basic_text · 4346d79eb364
  • aida-desktop · apps/desktop/electron/main.ts L669–709 · strictSafeStorage · 4346d79eb364
  • aida-desktop · apps/desktop/electron/security/safe-storage-policy.ts L1–52 · basic_text · 4346d79eb364
  • aida-desktop · apps/desktop/electron/auth/credential-vault.ts L85–96 · session-only · 4346d79eb364
  • aida-desktop · apps/desktop/electron/security/safe-storage-policy.test.ts L84–95 · session-only · 4346d79eb364
  • aida-desktop · apps/desktop/electron/auth/credential-vault.ts L85–96 · session-only · 4346d79eb364

STA-188 业务 Task 续办身份(钉点 4346d79eb364)

从业务 Task CTA 续办时只传 businessTaskId / engagementId 等服务端可校验身份,不发送客户端 capabilityId(客户端能力不是 Host Work 路由授权)。

  • aida-desktop · apps/desktop/src/app-surfaces/engagements/EngagementsSurface.tsx L305–315 · 4346d79eb364

机制说明

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 → Main stopSubmission,以原提交身份(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;钉点 Desktop 8eecd12081db 起 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;Agent desktop_distribution_releases 平台 CHECK(ddl.ts 与迁移 176)放行 linux-x64 插件行;Plugin 协议 Platform 枚举也加了 linux-x64。钉点 Desktop 8eecd12081db 起,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.json targets 仍只有 darwin / win32;仓里有 0.1.62 / 0.1.63 发布提交,但 Linux 包是否真的上线、AppImage 自动更新是否在真机走通未核。证据:aida-desktop · apps/desktop/package.json L192–210 · AppImage · 4346d79eb364;aida-desktop · scripts/deploy-aida-updates.mjs L361–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.ts L32–33 · ComputerUseMethod · 4346d79eb364;aida-desktop · apps/desktop/electron/computer-use/computer-use-host.ts L180 · Owns one interactive desktop · 4346d79eb364;aida-desktop · apps/desktop/src/local-executor/ComputerUsePanel.tsx L34 · computerUse · 4346d79eb364;aida-desktop · apps/desktop/electron/auth/mail-connector-client.ts L92–115 · authorize · 4346d79eb364;aida-desktop · apps/desktop/electron/plugin-host/register-plugin-host-ipc.ts L81–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.md L42–98 · 77fe76838aa4(历史引用:该文档已在 aida-agent 44d63e20 退役,钉点 e2adc9a3c325 无此文件;见 ATLAS-DEBT)
  • aida-desktop · CONTEXT.md L1388–1418 · Dual session identity · 4346d79eb364(历史引用:该文件在上一钉点与当前钉点均不存在,未能复核;见 ATLAS-DEBT)
  • aida-desktop · apps/desktop/electron/plugin-host/plugin-host.ts L1–59 · 4346d79eb364
  • aida-desktop · apps/desktop/electron/agent-loop/register-runtime-work-ipc.ts L251–276 · submitSubmission · 4346d79eb364(register-runtime-v2-ipc 已删除,统一 Work 提交/观察)
  • aida-agent · packages/agent/src/runtime/work/run-work-admission.ts L16–57 · bindAdmittedWork · e2adc9a3c325
  • aida-desktop · apps/desktop/electron/config/config-store.ts L279–319 · normalizePersistedConfig · 4346d79eb364
  • aida-desktop · apps/desktop/electron/document-intake/intake-service.ts L164–172 · markSent · 4346d79eb364

结论来自固定版本的静态源码与合同阅读;实现存在、默认开关和生产启用分别判断。本站代码证据面板列出声明状态与具体限制。

  • aida-desktop · apps/desktop/src/chat/core/runTimeline.ts L294–306 · reply_user_message · 4346d79eb364
  • aida-desktop · apps/desktop/src/chat/core/replyUserMessages.ts L11–39 · projectReplyUserMessages · 4346d79eb364
  • aida-desktop · apps/desktop/src/chat/interaction-workbench/endOriginalWork.ts L33–74 · endOriginalWorkForExpiredCard · 4346d79eb364
  • aida-desktop · apps/desktop/src/chat/interaction-workbench/ConnectedConversationInteractionWorkbench.tsx L893–916 · ORIGINAL_WORK_BINDING_MISSING · 4346d79eb364
  • aida-desktop · apps/desktop/src/chat/core/runtimeWorkObservation.ts L354–376 · stopOriginalRuntimeWork · 4346d79eb364
  • aida-desktop · apps/desktop/electron/agent-loop/register-runtime-work-ipc.ts L345–395 · stopSubmission · 4346d79eb364
  • aida-desktop · apps/desktop/src/chat/responseDisplayState.ts L61–69 · 已收到答复 · 4346d79eb364
  • aida-desktop · apps/desktop/src/chat/useDesktopSSEChat.ts L1202–1244 · refreshWorkHistory · 4346d79eb364
  • aida-desktop · apps/desktop/shared/skill-execution-platform.ts L1–14 · skillHostPlatform · 4346d79eb364
  • aida-desktop · apps/desktop/package.json L192–210 · AppImage · 4346d79eb364
  • aida-desktop · scripts/publish-desktop.mjs L51–91 · linux-x64 · 4346d79eb364
  • aida-desktop · scripts/publish-desktop.mjs L941–981 · dist:linux · 4346d79eb364
  • aida-agent · packages/agent/migrations/176_desktop_distribution_linux_x64.sql L1–8 · linux-x64 · e2adc9a3c325
  • aida-plugins · packages/protocol/schema/protocol.schema.json L31–36 · linux-x64 · a33ce3733365
  • aida-desktop · apps/desktop/electron/agent-loop/submission-observation-journal.ts L153–195 · encryption_unavailable · 4346d79eb364
  • aida-agent · packages/agent/src/config/ddl.ts L590–610 · win32-x64 · e2adc9a3c325
  • aida-desktop · apps/desktop/electron/security/safe-storage-policy.ts L1–52 · basic_text · 4346d79eb364
  • aida-desktop · apps/desktop/electron/main.ts L669–709 · strictSafeStorage · 4346d79eb364
  • aida-desktop · apps/desktop/electron/security/safe-storage-policy.ts L1–52 · basic_text · 4346d79eb364
  • aida-desktop · apps/desktop/electron/auth/credential-vault.ts L85–96 · session-only · 4346d79eb364
  • aida-desktop · apps/desktop/electron/security/safe-storage-policy.test.ts L84–95 · session-only · 4346d79eb364
  • aida-desktop · apps/desktop/electron/auth/credential-vault.ts L85–96 · session-only · 4346d79eb364

STA-188 业务 Task 续办身份(钉点 4346d79eb364)

从业务 Task CTA 续办时只传 businessTaskId / engagementId 等服务端可校验身份,不发送客户端 capabilityId(客户端能力不是 Host Work 路由授权)。

  • aida-desktop · apps/desktop/src/app-surfaces/engagements/EngagementsSurface.tsx L305–315 · 4346d79eb364

代码证据

引用核验检查固定 commit 的文件与范围;实现结论来自代码阅读。自动检查不证明生产环境已启用。

已核验实现

Desktop 的渲染是服务端事件与本地草稿的投影,本机能力归 Main。

aida-agentpackages/agent/src/shared/interaction-kernel-state.ts:11–417f2e519936b57902d4907ed8026fe1ecdd146e82符号:INTERACTION_STATUSES
aida-desktopGLOSSARY.md:1361–13674346d79eb36402355e51118df0edf1f98586880c符号:Dual session identity
aida-desktopapps/desktop/electron/plugin-host/plugin-host.ts:96–1274346d79eb36402355e51118df0edf1f98586880c符号:export class PluginHost
已核验实现

tip 已删除 Desktop 的文本 V2 启动/观察桥(register-runtime-v2-ipc、runtime-v2-core-contract、agent-loop 合同);Main 经 RuntimeWorkIpcCoordinator.submitSubmission 走统一 Work 提交与观察,Agent 侧以 bindAdmittedWork 绑定。

aida-desktopapps/desktop/electron/agent-loop/register-runtime-work-ipc.ts:485–5104346d79eb36402355e51118df0edf1f98586880c符号:submitSubmission
aida-agentpackages/agent/src/runtime/work/run-work-admission.ts:30–717f2e519936b57902d4907ed8026fe1ecdd146e82符号:bindAdmittedWork
已核验实现

Desktop 设置只接受 v2 形状:旧设置迁移(config-migration)与「恢复旧服务地址」入口已删除,旧形状回落默认值;文档摄取 markSent 必须给出 intakeIds,空数组为无操作,不再整会话翻转。

aida-desktopapps/desktop/electron/config/config-store.ts:299–3234346d79eb36402355e51118df0edf1f98586880c符号:normalizePersistedConfig
aida-desktopapps/desktop/electron/document-intake/intake-service.ts:168–1764346d79eb36402355e51118df0edf1f98586880c符号:markSent
已核验实现

Desktop 把 reply_user_message 记到当前 run 卡的 runDetail,同一 messageId 重放不重复;projectReplyUserMessages 把它们物化成独立助手消息行,排在最终回复之前,不并入最终正文。

aida-desktopapps/desktop/src/chat/core/runTimeline.ts:323–3354346d79eb36402355e51118df0edf1f98586880c符号:reply_user_message
aida-desktopapps/desktop/src/chat/core/replyUserMessages.ts:17–424346d79eb36402355e51118df0edf1f98586880c符号:projectReplyUserMessages
已核验实现

过期卡「结束原任务」:仅在卡状态为 expired 时出现;rootRunId 取自卡所属消息/owner 投影,多个来源不一致或会话不匹配即拒绝(ORIGINAL_WORK_BINDING_MISSING),不从当前 active run 推断;视图或观察身份在请求期间变化则中止(ORIGINAL_WORK_OBSERVER_DETACHED)。Runtime Work 经 stopOriginalRuntimeWork → Main stopSubmission 以原提交身份(sourceRef chat-submission:<clientRequestId>)持久停止,已有在线观察者时复用其 abort;legacy run(active-run 426)沿用 cancelRun。

aida-desktopapps/desktop/src/chat/interaction-workbench/endOriginalWork.ts:51–924346d79eb36402355e51118df0edf1f98586880c符号:endOriginalWorkForExpiredCard
aida-desktopapps/desktop/src/chat/interaction-workbench/ConnectedConversationInteractionWorkbench.tsx:985–10084346d79eb36402355e51118df0edf1f98586880c符号:ORIGINAL_WORK_BINDING_MISSING
aida-desktopapps/desktop/src/chat/interaction-workbench/ConnectedConversationInteractionWorkbench.tsx:1258–12584346d79eb36402355e51118df0edf1f98586880c符号:onEndOriginalWork
aida-desktopapps/desktop/src/chat/core/runtimeWorkObservation.ts:768–7894346d79eb36402355e51118df0edf1f98586880c符号:stopOriginalRuntimeWork
aida-desktopapps/desktop/electron/agent-loop/register-runtime-work-ipc.ts:609–6594346d79eb36402355e51118df0edf1f98586880c符号:stopSubmission
已核验实现

展示状态:Work 为 suspended 且最近一张可见交互已 resolved 时显示「已收到答复,等待后续处理」(recovering),否则仍是「处理已暂停」;续办观察在 Work 进入或离开等待(suspended / pending_resume → pending / running)时重新水合会话历史,使续办后的新问题卡及时出现。均为界面投影,不改服务端状态。

aida-desktopapps/desktop/src/chat/responseDisplayState.ts:149–1574346d79eb36402355e51118df0edf1f98586880c符号:已收到答复
aida-desktopapps/desktop/src/chat/useDesktopSSEChat.ts:2205–22474346d79eb36402355e51118df0edf1f98586880c符号:refreshWorkHistory
已核验实现

Linux x64 是 Desktop 支持平台:skillHostPlatform 接受 darwin / win32 / linux;原先不向 Agent 广告 linux 的 agentWirePlatforms 过滤已删除,Skill 入口 platforms 线上枚举含 linux(ADR-0090 D3);electron-builder 产出 x64 AppImage(dist:linux,可在 macOS 上交叉打包;linux.publish 为 generic 更新源);仓内已删除 .gitlab-ci.yml,没有 CI 打包任务;Desktop releasePlatformSchema 增加 linux-x64。

aida-desktopapps/desktop/shared/skill-execution-platform.ts:9–154346d79eb36402355e51118df0edf1f98586880c符号:skillHostPlatform
aida-agentpackages/tool-client/src/types/skill-script.ts:502–5057f2e519936b57902d4907ed8026fe1ecdd146e82符号:"linux"
aida-desktopapps/desktop/package.json:78–784346d79eb36402355e51118df0edf1f98586880c符号:dist:linux
aida-desktopapps/desktop/package.json:199–2174346d79eb36402355e51118df0edf1f98586880c符号:AppImage
aida-desktopapps/desktop/shared/desktop-distribution.ts:18–234346d79eb36402355e51118df0edf1f98586880c符号:linux-x64
已核验实现

Linux 发布链路在代码上已接通:发布脚本 targets 增加 linux-x64,该目标走 dist:linux 产出 AppImage + latest-linux.yml(不走 Velopack feed),构建时以 -c.linux.publish.url 把更新源指到 <base>/internal/linux-x64(package.json linux.publish 为 generic provider,desktop 26187f12 起);部署脚本另维护固定下载地址 AidaWork-linux-x86_64.AppImage(先核对线上 latest-linux.yml 与本地产物一致才复制,desktop 08f6d362);Agent desktop_distribution_releases 平台 CHECK(ddl 与迁移 176)允许 linux-x64 插件行;Plugin 协议 Platform 枚举增加 linux-x64。官方插件 plugin.json targets 仍只有 darwin/win32。

迁移 176 不随启动自动执行,各环境是否已执行未核实;生产是否已发 Linux 包未核实;本轮未实跑发布脚本。

aida-desktopscripts/publish-desktop.mjs:71–764346d79eb36402355e51118df0edf1f98586880c符号:linux-x64
aida-desktopscripts/publish-desktop.mjs:941–9814346d79eb36402355e51118df0edf1f98586880c符号:dist:linux
aida-agentpackages/agent/src/config/ddl.ts:625–6457f2e519936b57902d4907ed8026fe1ecdd146e82符号:linux-x64
aida-agentpackages/agent/migrations/176_desktop_distribution_linux_x64.sql:1–87f2e519936b57902d4907ed8026fe1ecdd146e82符号:Runtime does not auto-apply
aida-pluginspackages/protocol/schema/protocol.schema.json:31–36a33ce3733365db48413a4b97a0f4f65066856175符号:linux-x64
aida-pluginsplugins/aida-cli/plugin.json:10–14a33ce3733365db48413a4b97a0f4f65066856175符号:win32-x64
aida-desktopscripts/deploy-aida-updates.mjs:380–4264346d79eb36402355e51118df0edf1f98586880c符号:latest-linux.yml
已核验实现

safeStorage 严格策略:Main 用 strictSafeStorage 包装 Electron safeStorage;Linux 上后端为 basic_text / unknown(硬编码密钥,等同明文混淆)时视为不可用,encrypt/decrypt 直接抛 SAFE_STORAGE_STRONG_ENCRYPTION_UNAVAILABLE。凭证库因此退回 session-only(不落盘);提交观察日志在强加密不可用时只保留内存记录、跳过落盘(encryption_unavailable 告警一次),有强加密时也改为后台尽力写盘,不再拒绝提交。非 KDE 且未指定 password-store 时,Main 默认追加 --password-store=gnome-libsecret。

分层:代码与单测文本已读(静态核验);本轮未运行 Desktop 单测;未在真实 Linux 桌面(GNOME/KDE、有/无 Secret Service)运行 Electron 验证 basic_text 判定与 session-only 退回——等 Stanley 真机验证。

aida-desktopapps/desktop/electron/security/safe-storage-policy.ts:1–524346d79eb36402355e51118df0edf1f98586880c符号:basic_text
aida-desktopapps/desktop/electron/main.ts:680–6934346d79eb36402355e51118df0edf1f98586880c符号:strictSafeStorage
aida-desktopapps/desktop/electron/auth/credential-vault.ts:89–1004346d79eb36402355e51118df0edf1f98586880c符号:session-only
aida-desktopapps/desktop/electron/agent-loop/submission-observation-journal.ts:251–2934346d79eb36402355e51118df0edf1f98586880c符号:encryption_unavailable
aida-desktopapps/desktop/electron/security/safe-storage-policy.test.ts:84–954346d79eb36402355e51118df0edf1f98586880c符号:session-only
aida-desktopapps/desktop/electron/auth/credential-vault.test.ts:118–1274346d79eb36402355e51118df0edf1f98586880c符号:session-only
条件路径

Desktop Computer Use:ComputerUseHost 拥有唯一交互桌面 lease(Workers 不可造授权);方法 computer.capabilities|listApps|listWindows|observe|act|release;八种窗口操作;渲染侧 ComputerUsePanel / window.aidaDesktop.computerUse。真机 macOS/Windows 授权与截图链路未跑。

代码与合同已读;未在真实 macOS/Windows 桌面跑授权、截图或 OS helper。

aida-desktopapps/desktop/electron/computer-use/computer-use-host.ts:32–334346d79eb36402355e51118df0edf1f98586880c符号:ComputerUseMethod
aida-desktopapps/desktop/electron/computer-use/computer-use-host.ts:180–1804346d79eb36402355e51118df0edf1f98586880c符号:Owns one interactive desktop
aida-desktopapps/desktop/src/local-executor/ComputerUsePanel.tsx:34–344346d79eb36402355e51118df0edf1f98586880c符号:computerUse
已核验实现

Desktop 邮件连接:MailConnectorClient 经 /api/connectors/mail/authorize 取 authorizePath=/mailbox/connect#ticket,会话内打开连接;aida-session 邮箱连接状态读取 Desktop 邮箱账号列表(configured/connected/accountCount,旧 directory-batch 能力已移除)。

aida-desktopapps/desktop/electron/auth/mail-connector-client.ts:92–1154346d79eb36402355e51118df0edf1f98586880c符号:authorize
aida-desktopapps/desktop/electron/plugin-host/register-plugin-host-ipc.ts:51–814346d79eb36402355e51118df0edf1f98586880c符号:mailConnectorOverlay
已核验实现

会话冷启动与提交连续性:hydrateConversationColdStart 沿服务端分页游标拉取并核对 chatObservationIdentity;projectWorkCarrierMessage 校验 rootRunId/conversationId 合并 publicProcess 与最新交互卡;releaseRespondedChatSubmission 与 cancelQueuedChatSubmission 按 clientRequestId 核销发送意图并在 rejected 时恢复草稿。

aida-desktopapps/desktop/src/chat/core/coldStartHydration.ts:80–1514346d79eb36402355e51118df0edf1f98586880c符号:projectWorkCarrierMessage
aida-desktopapps/desktop/src/chat/core/submissionContinuity.ts:91–1624346d79eb36402355e51118df0edf1f98586880c符号:releaseRespondedChatSubmission
已核验实现

STA-188:业务 Task 续办只传服务端可校验的 businessTaskId/engagementId 等身份,不再发送客户端 capabilityId(非 Host Work 路由授权)。

aida-desktopapps/desktop/src/app-surfaces/engagements/EngagementsSurface.tsx:305–3154346d79eb36402355e51118df0edf1f98586880c符号:businessTaskId