• …p+CAS, tenant enforcement
    
    Audit findings 1-5 confirmed real; root causes were (a) identity self-reported by
    the client, (b) every failure path defaulting open.
    
    - ERP /ai/whoami (saas-8s+ @c8e0057 follow-up) resolves token → real user/tenant/type;
      AuthzService.resolveIdentity is now the single identity entry point. Client-supplied
      userid/brandsid/usertype removed from all request bodies and from chat.html.
    - dev-login is a real switch (erp.dev-login.enabled, default false) and its ERP creds
      no longer have built-in admin/666666 defaults; blank token in production → 401,
      never a silent fall back to the dev (sysadmin) account.
    - conversations/op/form endpoints require login; conversation ids are namespaced by
      user id and ownership-checked (403 otherwise); /op/pending no longer returns sPayload.
    - op confirm/cancel check the proposer, and confirm claims the draft via CAS so
      concurrent/repeat confirms cannot execute twice; bill numbers are regenerated at
      execution time instead of replaying the propose-time snapshot.
    - FK options take the tenant from the introspected identity and return empty rather
      than dropping the sBrandsId predicate.
    - secrets moved to env vars (DB_URL/DB_USERNAME/DB_PASSWORD/REDIS_*/LLM_*/ERP_BASEURL);
      allowMultiQueries=false. NOTE: the previously committed credentials must be rotated.
    - ids interpolated into ERP URLs are validated (safeId) to stop query/path injection.
    - update path rejects system columns, resolves FK names, and coerces by column type;
      numeric coercion now rejects unparseable input instead of writing 0/truncating, and
      proposal summaries show the value that will actually be written.
    - ResponseStatusException keeps its 401/403 status instead of being wrapped as 200.
    - anti-fabrication guard stays on when the intent gate itself fails.
    zichun authored
     
    Browse Code »

  • - delete queryData (QueryTool, sqlChatModel bean, llm.sql-model, jsqlparser dep)
    - delete kgSearch (findForms stays), delete loadSkill (SkillTool/SkillService)
    - single system prompt (domain map + 业务常识) replaces 3 ToolScope versions; ToolScope removed
    - intent gate reduced to 查询/新增/操作已有单据/其他 with class definitions only;
      write action derived from utterance in router
    - dedup: shared locateRecord() in ProposeWriteTool; name-field/label lookups
      consolidated into FormResolverService
    zichun authored
     
    Browse Code »
  • - Replace langchain4j-ollama with langchain4j-open-ai; AgentFactory/
      QueryTool depend on ChatModel/StreamingChatModel interfaces
    - OllamaJsonClient -> LlmJsonClient: raw /v1/chat/completions with
      response_format json_schema; single OkHttpClient instance
    - Thinking off at all 3 call sites via reasoning_effort=none (the only
      switch that works on /v1; think:false and /no_think are ignored)
    - Drop client-side length params (num_ctx/num_predict/max_tokens) —
      server-side OLLAMA_CONTEXT_LENGTH=16384 on xlyllm covers them
    - Unified tracing: TracingChatModelListener.record() shared by listener
      callbacks and LlmJsonClient; per-request model name from ctx; sql
      model now has the listener too (was untraced and mislabeled)
    - Config keys langchain4j.ollama.* -> llm.{base-url,api-key,chat-model,
      sql-model}; both models = qwen3.6-27b-iq3:latest (tools+thinking+
      vision, verified: streaming tool-calls / json_schema / reasoning off)
    
    Verified end-to-end on :8199: intent gate traced (340/28 tokens), agent
    tool loop, correct answers; warm 1-4s, cold load ~96s (KEEP_ALIVE=30s).
    zichun authored
     
    Browse Code »
  • 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.
    zichun authored
     
    Browse Code »