-
…e shared kernel + PreviewService (previewId Redis binding, save-side re-validation, state legality checks) + queue-only OpService (sMakePerson dual-write, status=confirmed); retire ProposeWriteTool/OpController/AuditService/ErpClient writes; preview card frontend; skills/prompt/bench sync; D: checkBusinessData stub behind erp.dry-run.enabled
-
…is 客户名称 — exact match silently dropped the prefill); deterministic tie-break prefers unique fkselect/名称 field, ambiguous cases skip
-
- single ReAct entry for all free text: 7 fixed tools (useSkill + 6); flow knowledge lives in 5 skill files (resources/skills/*.md, first line = brief for prompt index; xly.skills.dir overrides for hot reload) - useSkill returns skill body and logs skill_active; projection pins the active skill full text on the flow card until confirm/cancel/new skill - system prompt from template prompts/system.txt (domain map + skill index); bench reads the same files to avoid replica drift - delete IntentService/Intent/SlotFillService/LlmJsonClient/StateService/ OkHttpUtil and route()/handleCreate/handleWrite/deriveWriteAction/ ground/withState; dimension-split regex migrated into FormCollectTool prefill assist (model provably fails dimension splitting) - anti-fabrication guards now unconditional (zero-tools+digits retry, WRITE_CLAIM check); invariant layer and button endpoints untouched - bench_ext: --arch new (same-source prompt/skills) and --fifty (bench50 cases judged on full trajectory for both arches)
-
P4 retirement + code slim-down (~18.5k lines deleted), on top of the intent-gate WIP (docs §17/§18 + agent/tool refinements): - Delete old 8-scene multi-agent stack: XlyErpService, SceneSelector/ Chati/ErpAi/DynamicTableNl2Sql agents, DynamicToolProvider (62 meta tools), Scene/ToolMeta/ParamRule entities+mappers+startup caches - Delete whole milvus/tts/ocr packages, /api/tts + /api/ocr endpoints, tts.html, python stream_server.py; strip dead TTS JS from chat.html (playByIndex/handleNormalResponse had no callers) - Three-pass orphan sweep: 17 dead utils, 16 dead entities, dead constants/exceptions, RedisService+RedisConfig, duplicate JacksonConfig, OperableChatMemoryProvider, old prompt generators; fold PageController into MvcConfig; trim OkHttpUtil 495→39 lines - pom: ~35→13 deps (drop mybatis/JPA/webflux/tika/pdfbox/poi/jieba/ jsoup/gson/fastjson2/springdoc/mapstruct/pagehelper/pinyin4j/ spring-retry/jnr-ffi/hutool/ocr/milvus/embeddings; add starter-jdbc); war 200M+→48M - application.yml: drop milvus/tts/ocr/tesseract/mybatis blocks; GlobalExceptionHandler returns plain {code,message} JSON - docs: mark P4 retirement done in agent-architecture §13/§18 Verified: mvn clean package OK; boot smoke on :8199 (Started 0.9s, /chat 200, health db UP). Old /api/tts & /api/ocr now 404 by design.
-
Bug: '我要报价纸盒' -> agent put product '纸盒' into 客户名称, FK-lookup failed, then asked to CREATE a customer named 纸盒. - System prompt rule 6: 新增报价 ALWAYS collectForm first; never map product/spec/盒型 to 客户名称; unknown customer -> let user pick from dropdown, never invent or offer to create. - collectForm(entityKeyword, knownFieldsJson?): pre-fills the form from what the user already said (产品/数量/尺寸); customer/product render as dropdowns to pick real records. - FK-not-found message no longer implies creating (was '请确认是否已存在' -> LLM read as 'create it?'); now '不是系统里已有的X,请从下拉选真实存在的X,不要新建'. Verified: '我要报价纸盒,1000个,长和宽50cm,高5cm' -> collectForm with 产品名称=纸盒(prefilled), 长/宽=50/高=5/数量=1000(prefilled), 客户名称=empty dropdown (no more guessing/create-customer).
-
User: form rendered every field as a plain text box; no type (dropdown/date/number), and FK fields didn't pull options from their source tables. - FormCollect schema now carries per-field type: fkselect | select | number | date | text (+ options for select, fkTable for fkselect, hint for placeholder). Types inferred from column data type for generic forms; curated for quote. - New GET /api/agent/form/options?table=&q=&brandsid= -> FK options from the source table (elecustomer/eleproduct/elematerials...), whitelisted to tables that appear as sFkTable in the field dict (rejects arbitrary tables e.g. gdslogininfo), tenant-filtered + LIMIT. - chat.html renderFormCollect renders by type: fkselect = searchable <input list=datalist> that fetches options on focus/typing; select = <select>; number = <input type=number>; date picker; text. - Fix: tolerant label matching (strip parentheticals) so '多数量' maps whether or not the LLM keeps the '(逗号分隔)' hint -> multi-qty rows now reliably created. Verified via agent: quote form shows 客户/产品/物料=fkselect, 单位/印刷/颜色/单双面=select, 尺寸/数量/单价/系数=number; options endpoint returns real names (客户 q=Little -> Little Antelope); non-FK table rejected; full write incl 多数量 (BJD202607086 -> 2000/4000/6000).
-
Root cause of the reported failure: - collectForm sourced fields from gdsconfigformslave -> quote master's form config only exposes 3 system/header fields (失效时间/制单人/单据日期); user filled 单据日期(tCreateDate,datetime)='12' -> ERP type mismatch. - proposeCreate never coerced by column type, never FK-resolved names, used addBusinessData (no billNo). Fixes: - FormResolverService: businessFields() curated authoritative label->{col,fk} for quoquotationmaster (客户名称/产品名称/数量/长/宽/高/单价 -> real writable cols sCustomerId/sProductId(FK)/dQty/dLength/dWidth/dHeight/dPrice), field-dict fallback for other tables; columnTypes/coerce/typeDefault/resolveFk/nextBillNo(BJD+YYYYMM+seq); isSystemColumn excludes reserve/money/rate/discount/person/date/bool/tenant/maker; resolveMasterForm excludes param/slave/control/config/color secondary tables. - collectForm: fields from businessFields (excludes system/header); gdsconfigformslave fallback. - proposeCreate: label->{col,fk} via businessFields; FK name->id; type-coerce; skip system cols; auto sId/sFormId + generated sBillNo; type-correct required defaults. - ErpClient.createForm: addUpdateDelBusinessData(handleType=add)+moduleId (was addBusinessData). - ProposeWriteTool.resolveForm unified to FormResolverService. Verified via agent end-to-end (real write): collectForm shows correct fields; created quoquotationmaster BJD202607082 = Little Antelope / 妇科三醇乳膏 / qty5000 / dims / price, tenant+maker+date auto-injected. -
…ormCollect + Skills + KgSearch - AgentIdentity + AgentFactory: build agent per request with token+form-allowlist carried in tool instances (per-call context; robust vs LC4j callback threading) - ErpClient: token-aware read/write/examine; user-token expiry does NOT silently re-login as dev-admin (no privilege escalation) - AuthzService: devIdentity()/userIdentity() resolve granted-form set (sAuthsId) - proposeExamine tool + OpController examine dispatch + forward user Authorization on confirm - InteractionTool.askUser (structured options), FormCollectTool.collectForm (real gdsconfigformslave schema) - SkillService + SkillTool.loadSkill + ai_skill digest in system prompt - KgQueryTool.kgSearch: L2 neighbors/flow + L3 field->table - tools ErpReadTool/ProposeWriteTool/QueryTool/FormCollectTool now per-request (not @Component)
-
…i_op_queue staging cols + ai_skill registry - proposeCreate tool -> ai_op_queue draft(payload) -> confirm executes addBusinessData - ai_op_queue: add sPayload/sSourceRef/bAutoExecute/sResultBillId/sErrorMsg/tExecutedDate/tExpireAt (create/examine/auto-flow ready) - ai_skill registry table + seed playbooks (Skills §6) - QueryTool: self-repair retry (feed SQL error back to model, up to 3x) - TracingChatModelListener: per-call LLM latency/token/error trace (Langfuse hook point)