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