插件与智能应用埋点
核查日期:2026-09-20。用户已确认现有 PostHog 链路可通;本次修复客户端覆盖和统计口径,不以本地测试代替生产入库验收。
事件合同
事件以 wework/src/telemetry/registry/ 为唯一来源,生成 TypeScript 白名单、公开 JSON 和 Markdown 目录。当前插件 38 个、智能应用 35 个,共 73 个事件。完整名称和失败阶段见 wework/telemetry/catalog/public-events.md。
| 模块 | 覆盖行为 | 结果口径 |
|---|---|---|
| 插件 | 市场/管理访问、启停、卸载 | 保留原事件名,统一 local/cloud 来源;插件事件同时进入统一分发 |
| 插件安装 | 安装请求、当前设备安装结果 | 请求被 API 接受才记 install_request_succeeded;匹配设备和版本后才记 device_install_succeeded 和 plugin_installed,pending 不记成功,failed 记确认失败 |
| 插件创建 | 创建请求 | create_request_succeeded 表示任务提交,不能解释为插件生成或校验完成 |
| 插件管理 | 复制、ZIP 导入、删除、分享、撤回、更新策略 | 相应操作边界返回成功或失败,每次尝试只记一个最终结果 |
| 插件发布 | 发布请求、修订提交、发布结果 | 请求/修订被接受与正式发布分开;立即 approved 才记发布成功,pending 不记成功 |
| 插件授权与试用 | 本地认证、云端 OAuth、退出授权、示例试用 | 授权终态确认成功,取消静默;试用只表示示例进入输入流程,不代表工具已执行 |
| 插件自动更新 | 非空更新或设备同步修复批次 | 批次处理结果;无操作巡检不计成功,不等同于每个插件设备版本最终完成 |
| 插件聊天调用 | 已归属插件的 MCP 工具调用 | 以运行时工具块终态报告成功或失败;开始与结束按调用 ID 去重,未归属插件的内置工具不计入 |
| 智能应用 | 市场/已拥有/应用访问,安装、更新、ZIP 导入 | 保留原事件;返回 failed 的安装不再误记成功 |
| 智能应用 | 创建、复制、关联目录、导出、分享、卸载、启停、配置、校验、添加插件 | 在共享 API 边界报告结果;启动须 running、校验须 passed,创建/关联等须 installed 或 running |
| 智能应用发布 | 发布申请与正式发布 | 申请接受独立统计;立即 published/rejected 才产生正式发布结果 |
设备安装结果追踪限当前客户端会话观察到的请求,队列最多 100 条;不跨应用重启持久化,不能替代后端全量安装台账。异步审批完成后未被本次客户端观察到的结果也不纳入正式发布计数。插件 MCP 工具调用通过运行时工具块的终态统计。生成完成、耗时与 Skill 激活仍需独立的执行器事实,不能从任务提交、访问或试用事件推断。
聊天中的插件使用
最新代码中的 recordPluginUsageFromInput 只在消息被接受后解析 plugin:// 引用,把展示名和时间写入本机 localStorage,用于 30 天内的插件排序和首次试用引导。它不进入 PostHog,也不能证明模型实际调用了插件。一次消息可能引用插件但未触发工具;模型也可能在没有显式引用的情况下调用已经启用的 MCP 工具。
真实调用以执行器产生的 MCP 工具块开始和结束为事实边界,再通过统一遥测分发。Codex mcpToolCall 携带的 pluginId 是首选归属;执行器将它投影为工具块的 plugin_id,客户端再结合当前设备的已安装且启用插件清单补齐分发类型、marketplace 和版本。其他执行器未提供 plugin_id 时,才使用插件声明的 MCP server 映射作为兜底。只有归属明确的 MCP 调用才进入插件统计,空间、浏览器、计算机等未归属插件的内置工具不会被计入。开始与结束按设备、任务、轮次和工具调用 ID 去重,只产生一个终态。Skill 是提示与上下文能力,没有统一的独立调用终态,应和 MCP 工具调用分开统计。
公开 PostHog 按每个已确认的 MCP 调用终态上报 plugin_invocation_succeeded 或 plugin_invocation_failed,并只保留下列低基数维度:
capability_type:mcpexecution_surface:task、project_task、automation或unknownexecutor_location:local、cloud、remote或unknownplugin_distribution:official、enterprise、personal或unknown- 失败事件的
failure_stage:invoke、timeout、cancelled或unknown
公开事件不包含插件名、MCP server 名、工具名、任务 ID、参数、输出或原始错误。当前失败终态统一记为 failure_stage=invoke;运行时尚未提供可靠的超时与取消分类时,不根据错误文本猜测。内部 sink 会额外保存稳定的 plugin_key、marketplace、版本、工具名和耗时,用于按插件分析和排障,但仍不记录参数、输出和认证信息;trace ID 与受控错误码需待执行器提供稳定字段后再补充。
后端普通日志不适合作为插件使用量的主数据源:本地执行可离线完成,不一定经过后端;后端看到的转发事件也未必带有可靠的插件归属。应由执行器产生结构化调用事实,云端后端只负责接收、持久化和聚合该事实。需要在线排障时,可以按采样和保留期打印上述内部字段,避免为每次工具调用输出自由文本日志。
分发与隐私
业务层仅发布受控事件或操作结果,由 TelemetryAgent 分发。公开构建沿用用户遥测同意与 PostHog SDK;内部构建仅交给内部 sink,不绕过发行版边界。监听器异常不改变业务操作结果。取消和重复终态通知不会产生额外结果。
PostHog 仅接收事件白名单中的枚举属性,例如 domain、failure_stage、source、scope、surface、enabled;插件/应用名称、资源 ID、路径、账户信息、原始错误文本不进入公开事件。匿名安装身份不能解释为登录账户 UV,公开数据不支持按单个插件名称排行。
正式打包步骤将已有 GitHub Secrets WEWORK_POSTHOG_KEY、WEWORK_POSTHOG_HOST 映射到对应 Vite 变量。事件目录同步只更新定义,不采集业务事件;同步任务跳过不代表接收链路断开。
QA 计划与验收
前置条件:隔离 worktree、独立 Electron home、真实本地后端、合成插件和智能应用、本地 PostHog 测试接收器;不得使用个人窗口或生产账户数据作为测试夹具。
| 场景 | 操作与期望 | 负向与恢复 |
|---|---|---|
| 安装确认 | 提交后 pending 不计安装成功;同设备同目标版本 installed 后只计一次 | failed 记确认失败;其他设备/旧版本/重复通知不计;显式重试可成功 |
| 共享操作边界 | API 成功/抛错/返回失败状态与结果事件一致 | 错误原样返回,遥测监听器抛错不影响业务;重试独立计数 |
| 授权 | OAuth 和本地认证完成计成功 | 拒绝/关窗取消不计失败;请求失败计受控阶段,不上传账户与错误内容 |
| 分发 | public 接收安全投影,internal 接收内部事实 | 拒绝或撤回公开遥测停止采集;内部构建不调用公开 SDK |
| 插件桌面 checkpoint | plugin-marketplace-lifecycle:打开插件市场并导入 ZIP,接收访问与导入成功事件 | 使用现有场景的真实安装、同步、更新、卸载与清理 |
| 智能应用桌面 checkpoint | harness-apps:创建、安装、启动、停止、导出、分享、卸载;发布弹窗取消 | 断言本地接收器事件及隐私字段;沿用真实后端及既有错误/恢复场景 |
| 独立 Electron | ai:verify 启动、snapshot、插件/智能应用导航和最终截图 | 隔离窗口关闭并停止 session,清除会话认证链接 |
本地测试与 CI 实际结果记录在 PR。上线后仍需在目标 PostHog 项目按新版本和事件名核对实际操作与接收数量;旧版与新版安装/创建事件口径不可直接合并比较。