diff --git a/docs/agent-architecture.md b/docs/agent-architecture.md index 90687e3..16192e1 100644 --- a/docs/agent-architecture.md +++ b/docs/agent-architecture.md @@ -207,12 +207,23 @@ ai_op_queue( - **审计**:`ai_audit_log` 记 propose/confirm/cancel/query。 - **ERP 接入**:`ErpClient` dev-login(admin/666666)拿真实会话 token;读 `getBusinessDataByFormcustomId`,写 `addUpdateDelBusinessData`(`column` 列表 + `handleType`)。 -**尚未做 / 被外部条件阻塞**(按原因归类): -- **授权层(§7)**:机制可建,但 dev-login=admin 时全通、无意义;**需生产的透传用户 token 才能真正约束**。 -- **写:新增 / 删除 / 审核**:`create` 撞 NOT-NULL 连环(sId/sParentId…);`delete/审核` 格式与校验各异且后果重。正解是**架构里的 ERP 侧暂存执行器(跨团队)**;当前只做安全的 `update`。 -- **FormCollect(§5)**:需 ERP 前端在对话里渲染表单——**跨团队**。 -- **ERP 侧暂存执行器 + 预填 + 深链(§10)**:**跨团队**,本项目未覆盖。 -- **Langfuse(§1)**:需自托管实例——**基础设施**。 -- **AskUser 结构化选项**:当前 agent 用自然语言澄清(如 lookupRecord 命中多条会请用户说具体),功能已覆盖,结构化选项为后续优化。 -- **稳健 NL2SQL**:`queryData` 安全但选表/拼 join 精度有限(架构 §14.1 早已标注为待专项攻关)。 -- **现网安全发现上报**(后端权限关 / 旧 NL2SQL 越权 / 读 API 可写):**业务侧事项**,非本次代码。 +## 16. 缺口补齐(2026-07-22,分支 `kg-edge-flow`) + +上一轮 §15 里「尚未做 / 被外部条件阻塞」的缺口,本轮全部补齐(含跨团队 ERP 侧)。均已编译通过(xlyAi mvn + ERP gradle)。 + +**xlyAi 侧** +- **授权 + token 透传(§7)**:新增 `AgentIdentity` + `AgentFactory` —— **按每次请求的身份新建 agent**,把透传的用户 ERP token 与「表单权限集」(`sAuthsId` → `AuthzService.grantedIds`)放进每请求的工具实例(规避 LC4j 流式工具在回调线程执行、ThreadLocal 不可靠的问题,即架构说的 per-call context)。前端逐请求带 `authorization`+身份;`ErpClient` 所有读写 **转发用户 token**;**用户 token 过期绝不用 dev(admin) 重登**(防静默提权)。dev-login 仅作本地兜底。 +- **写:新增 / 删除 / 审核**:`proposeCreate`(自动补主键/必填)、`proposeDelete`、`proposeExamine` 三个 HITL 工具,均只暂存 `ai_op_queue` draft、确认端点才执行;确认转发用户 token。`ai_op_queue` 加 `sPayload/sSourceRef/bAutoExecute/sResultBillId/sErrorMsg/tExecutedDate/tExpireAt`。 +- **FormCollect(§5)**:`collectForm` 从 ERP 表单元数据(`gdsconfigformslave`:字段/控件/必填/下拉/默认)取 schema → SSE `form_collect` → **xlyAi 聊天页内渲染表单**(无需 ERP 前端),提交拼回 `proposeCreate`。 +- **AskUser(§5)**:`askUser(question, options)` → SSE `question` → 前端渲染可点选项片。 +- **Skills(§6)**:`ai_skill` 注册表 + `SkillService`(name+何时用进 system prompt)+ `loadSkill` 工具(按需注入完整 playbook);种子技能:新建报价 / 月度对账 / 库存查询。 +- **KgSearch(§5/§11)**:`kgSearch` 暴露 L2 邻居/流转(`viw_kg_form_neighbors`)+ L3 字段→表列(`viw_kg_field_dict`),按词查、截断。 +- **稳健 NL2SQL(§9)**:`QueryTool` 加**表白名单**(`viw_*` + 表单数据源 + 字段字典表,用 jsqlparser `TablesNamesFinder` 校验 → 挡住 `gdslogininfo`/`sysjurisdiction`/`ai_op_queue` 等敏感表)+ **单表租户谓词注入**(`sBrandsId`)+ prompt 品牌提示 + 自修复重试。 +- **Langfuse(§1)**:`TracingChatModelListener` 增加**配置开关的 ingestion 导出**(generation span,走 JDK HttpClient,不引依赖);`docker-compose.langfuse.yml` 自托管;默认关闭。 + +**ERP 侧(saas-8s+ `release/customer/2025/saas-8s+`,backup 分支未动)** +- **暂存执行器 + 预填 + 待办(§10)**:`AiStagingController @/ai` —— `execStaging/{sId}`(POST,执行)、`staging/{sId}`(GET,预填加载供原生表单深链)、`myTodos`(GET,AI待办);全部 `@Authorization`+`@CurrentUser`。`AiStagingService(Impl)` 读共享库 `ai_op_queue` → 以**用户身份**走 ERP 自己的写入/审核逻辑(`addUpdateDelBusinessData` / `doExamine`,复用租户隔离、单号、审核存储过程)→ 幂等 + 回写状态/结果。xlyAi 确认端点按 `erp.exec-staging.enabled` 委托它(生产路径)或直连(本地默认)。 + +**仍属业务/运维决策(非代码缺口)** +- 现网安全发现(后端逐用户表单权限被注释关 / 读 API 可被 `bUpdate` 触发写 / 旧 NL2SQL 越权)——`docs/security-findings.md` 已成文,**是否整改由业务定**。授权层真正“收紧到非管理员”只有在**生产以真实用户 token 运行**时才能观测(本地 dev-login=admin 全通)。 +- 报价改双确认、首个灰度只读场景选型 —— 业务确认项。 diff --git a/src/main/resources/templates/chat.html b/src/main/resources/templates/chat.html index ad2b540..6a7f702 100644 --- a/src/main/resources/templates/chat.html +++ b/src/main/resources/templates/chat.html @@ -472,7 +472,10 @@ let brandsid= "1111111111"; let subsidiaryid= "1111111111"; let usertype= "sysadmin"; - let authorization="CE444885A9BCFDDE1FD793F8A0931301E9D7DE6CEDD9DE4B83ECE2219C7829A8F3419238942A93E9AD666629E18D159A8BB22EBE26EF12CD9A1EEDB89DC6FB33178153C379FB82F53B4B689DA1BE7060687D4EF8281542FFC87C4EB776974C6A538155B7ADAEE71E899235DC1122F426"; + // ERP 登录 token(透传给后端 → 转发给 ERP,用于按真实用户身份读写;绝不进 prompt)。 + // 本地独立聊天页无浏览器登录流程,留空 → 后端回退 dev-login(admin)读写; + // 生产环境由 ERP 外壳把用户的实时有效 token 注入这里,即启用逐用户 token 透传 + 表单权限收紧。 + let authorization=""; let hrefLock = window.location.origin+"/xlyAi"; const CONFIG = {