Lskj.AgentPet
这是桌宠的无框透明 Web UI 层,按 Codex v1 精灵图协议渲染 8×9、192×208 像素的九种动画,完整图集必须为 1536×1872。仓库不包含 guga 图片;Windows 宿主在运行时先验证包外图集的 WebP 结构和精确尺寸,再从只读句柄载入内存,仅以固定虚拟 Web 地址注入 spriteUrl。页面会用 WebView2 对素材做完整异步解码和实际尺寸复核;通过前聊天、附件和 ERP 执行全部禁用,损坏或超时不会降级为无图运行。
鼠标在宠物上有意停留约 480 ms 会展开对话面板,但不会抢走旧 ERP 当前控件的键盘焦点;悬停展开后的第一次点击只把焦点放进输入框,不会反而收起面板,再次点击才允许收起。每次展开都会通过只读 context.get 刷新标题中的当前活动模块,真正发送问题后 AstrBot 仍会再次获取实时上下文,避免用户切换菜单后沿用旧界面信息。标题下方还会显示当前受信任 ERP 会话范围的账套、子系统、用户和数据库指纹前 12 位证据;不会显示服务器、库名、连接串或完整数据库指纹。该范围无效时仍允许用户聊天和重新发现能力,但执行按钮保持关闭。
快捷入口包含采购发票录入、自然语言请假、当前界面说明和只读配置诊断,发送的都是固定安全引导,仍由 AstrBot 先读取实时上下文与能力,不能绕过命令 Schema。只有受信任上下文明确标记当前身份为 ERP 内置管理员时才显示“检查业务能力”;它引导调用服务端权限保护的 adapters.status,仅解释稳定阻断代码和下一步。按钮隐藏只是界面便利,真正授权始终由 ERP 桥复核。
推荐宿主是独立的 .NET 8 Windows 透明窗口 + WebView2 sidecar,不要把 WebView2 和新依赖直接装进仍为 .NET Framework 4.0、DevExpress 15.2 的 ERP 主进程。宿主只做四件事:
- 校验
%LOCALAPPDATA%\Langsu\Lserp\AgentBridge\agentbridge-*.json,并只连接启动会话绑定的 ERP 进程;未绑定且存在多个有效 ERP 时直接拒绝,不按文件时间猜测目标。 - 把 WebView2 的
lserp.bridge.request/response消息转换为桥协议的长度前缀 JSON。 - 把聊天和已上传的 AstrBot 附件 ID 转发给 HTTP/SSE,并只向 AstrBot 暴露读取与“生成计划”工具,不暴露
command.execute。 - 从单一只读句柄验证并读入精灵图,只在固定
https://lserp-sprite.local/atlas.webp返回内存副本;不映射父目录、不上传素材。
真正执行只能由本 UI 的“在 ERP 中确认并执行”触发;随后 ERP 主进程还会显示原生确认窗口。任何来自模型正文的“已确认”都无效。桌宠会在按钮点击后、发送执行请求前再次读取当前 ERP 登录范围;数据库、用户、账套或子系统任一无法确认或已经变化时,旧计划立即作废并要求重新生成预览。宿主和 ERP 桥还会独立执行相同的前后复核,页面检查不是唯一安全边界。采购逐行来源匹配和动态低代码新增/修改都必须先滚动核对完整结构化预览;动态新增按主表与每行明细展示不透明参数 ID、标签、类型和值,动态修改按唯一业务描述展示每个字段的修改前/后值。缺字段、重复参数、未知物理字段、投影不一致、并发证据或适配器证据无效时按钮保持禁用。
Web UI 会在发出请求前校验方法与 payload 的精确形状;接收响应时同时绑定协议版本、requestId 和 correlationId,并拒绝未知字段、错误类型和非服务器格式的计划 ID。宿主还会独立重复同样的校验,并用 AstrBot 会话的 SHA-256 派生值覆盖页面提供的 clientSessionId;页面携带的幂等键也只作形状检查,ERP 实际使用的是宿主为可信计划生成并绑定的键。因此页面脚本不能伪造会话、替换幂等键或跨桌宠执行计划。
可执行计划还必须携带宿主从 AstrBot 正式工具结果取得的 bridgeCorrelationId。页面点击时原样带回该值,宿主再次与可信计划比较;遗漏或替换会在 ERP 调用前失败。执行成功后页面显示同一关联 ID,ERP 的计划、确认、完成审计和请假后续计划可以直接串联取证。
执行成功也不直接展示客户处理器返回的自由文本。Host 按命令与稳定结果码重新生成固定消息,只允许 success/code/message/recordId/replayed/data 精确回执;普通命令的 data 固定为空,非法结果码、额外 SQL、物理标识或提示词文本会以 bridge_protocol_error 失败关闭。初始化追踪是唯一允许安全诊断投影的成功结果:页面只收到稳定分类、计数、哈希、不可反查调用点别名和固定建议,原始事件、异常文字和 SQL 不进入 WebView。
追踪完成后,Host 会把同一份安全投影绑定为最多十分钟、最多一条的可信诊断上下文。用户下一次向桌宠追问原因时,它作为独立的宿主消息部件送入 AstrBot,完整流成功后立即消费;聊天失败会保留以便重试,第二次正常提问不会重复注入。ERP 用户、账套、子系统或数据库范围变化会立即清除它;用户正文伪造保留标记会被拒绝。
执行失败不再只显示一段自由文本。Host 只向页面投影精确的 data.recovery={action,retryable,planInvalidated,message},其中 action 只能是九个固定恢复动作;页面同时显示稳定错误码、固定下一步和关联 ID。错误主文案也由 Host 按稳定错误码固定映射,不转发客户过程返回的自由 reason。Host 会剥离错误 data 中的额外字段,页面也会拒绝未知动作、错误类型、控制字符、SQL/物理字段等扩展。重复发票、来源/请假规则变化和过期凭证会撤销旧计划并要求重新生成;用户取消保留原预览,明确的桥超时或数据库未知结果只允许以同一宿主幂等键做结果核对式重试。未识别错误默认撤销页面计划并要求按关联 ID 查询审计,不能由模型猜测是否已经写入。
请假意图要求“创建后提交”时,第一次点击只创建草稿。ERP 桥返回独立的提交预览后,桌宠会保留新计划并要求第二次点击;两次计划使用不同幂等键,第二次点击仍会触发 ERP 原生确认。采购或请假适配器返回 needsUi=true 时,桥会优先返回独立的模块导航预览,避免直接提交仍需补充界面信息的草稿。任何后续计划无效或生成失败时按钮保持禁用,并明确提示“后续操作尚未执行”。
附件按钮不使用 HTML file input。WebView 只发送 lserp.attachment.pick/remove,本地路径、内容魔数校验、内容摘要和 AstrBot multipart 上传都在 WPF 宿主内完成。聊天结果不再由页面自行清空附件,页面只服从宿主的 lserp.attachments.changed;因此零/多候选的澄清回复会保留原附件,只有宿主验证采购创建计划绑定了同一附件集合后才清空。
测试:
npm test
当前 24 项 Node 测试包含悬停展开后的点击焦点/收起状态回归、采购/请假固定安全引导、管理员业务能力入口的受信任范围显示门禁、ERP 会话范围的有界安全投影与无效范围失败关闭、请求/响应串线负例、业务错误恢复白名单及恶意 SQL 扩展拒绝、成功回执白名单与诊断结果注入负例、受信任关联 ID 与后续计划绑定、幂等键重试、后续计划独立幂等键、采购/请假/初始化诊断的可信确认预览、动态模块新增与并发修改的边界和篡改负例,以及图集完整解码、错误尺寸、损坏与超时失败关闭。