springbootAI 2.3.10__tar.gz → 2.3.11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) hide show
  1. {springbootai-2.3.10 → springbootai-2.3.11}/CHANGELOG.md +10 -0
  2. {springbootai-2.3.10/springbootAI.egg-info → springbootai-2.3.11}/PKG-INFO +8 -7
  3. {springbootai-2.3.10 → springbootai-2.3.11}/README.md +5 -5
  4. {springbootai-2.3.10 → springbootai-2.3.11}/pyproject.toml +41 -3
  5. springbootai-2.3.11/requirements-ai.txt +44 -0
  6. {springbootai-2.3.10 → springbootai-2.3.11}/requirements.txt +1 -6
  7. {springbootai-2.3.10 → springbootai-2.3.11/springbootAI.egg-info}/PKG-INFO +8 -7
  8. {springbootai-2.3.10 → springbootai-2.3.11}/springbootAI.egg-info/SOURCES.txt +6 -0
  9. {springbootai-2.3.10 → springbootai-2.3.11}/springbootAI.egg-info/requires.txt +1 -0
  10. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/__init__.py +1 -1
  11. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/ai/__init__.py +4 -3
  12. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/ai/advisors.py +102 -10
  13. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/ai/annotation_runtime.py +138 -18
  14. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/ai/annotations.py +26 -4
  15. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/ai/autoconfig.py +95 -14
  16. springbootai-2.3.11/springbootai/ai/core.py +1076 -0
  17. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/ai/memory.py +79 -15
  18. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/ai/observability.py +5 -3
  19. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/ai/providers.py +211 -49
  20. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/ai/resilience.py +186 -8
  21. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/ai/tools.py +268 -20
  22. springbootai-2.3.11/springbootai/ai/vectorstore.py +719 -0
  23. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/annotations/cache.py +2 -1
  24. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/annotations/core.py +1 -1
  25. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/aop/cloud_aop.py +62 -4
  26. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/aop/comprehensive_aop.py +264 -129
  27. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cli/scaffold.py +5 -1
  28. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cloud/__init__.py +3 -1
  29. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cloud/bus.py +226 -59
  30. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cloud/discovery.py +39 -21
  31. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cloud/feign.py +28 -2
  32. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cloud/gateway.py +328 -108
  33. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cloud/nacos_config.py +6 -2
  34. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cloud/tracer.py +103 -56
  35. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/config/binding.py +3 -1
  36. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/config/spring-configuration-metadata.json +25 -1
  37. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/context/application_context.py +20 -5
  38. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/context/bean_factory.py +185 -140
  39. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/core/graceful_shutdown.py +3 -1
  40. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/csv/__init__.py +1 -1
  41. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/data/__init__.py +1 -1
  42. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/data/repository.py +113 -27
  43. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/datasource/__init__.py +1 -1
  44. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/datasource/dynamic.py +5 -1
  45. springbootai-2.3.11/springbootai/event/publisher.py +103 -0
  46. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/excel/__init__.py +1 -1
  47. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/i18n/__init__.py +1 -1
  48. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/__init__.py +1 -1
  49. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/adapters.py +6 -2
  50. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/autoconfig.py +10 -4
  51. springbootai-2.3.11/springbootai/langchain/loaders/loaders.py +440 -0
  52. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/partners.py +3 -1
  53. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/tools/tools.py +32 -4
  54. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langgraph/autoconfig.py +10 -4
  55. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langgraph/config.py +36 -3
  56. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langgraph/runtime.py +292 -51
  57. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/logging/context.py +8 -3
  58. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/main.py +28 -17
  59. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/mcp/autoconfig.py +3 -1
  60. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/mcp/client.py +295 -38
  61. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/mcp/config.py +37 -0
  62. springbootai-2.3.11/springbootai/messaging/kafka.py +552 -0
  63. springbootai-2.3.11/springbootai/messaging/rabbitmq.py +925 -0
  64. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/monitoring/prometheus.py +24 -7
  65. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/__init__.py +2 -0
  66. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/database.py +190 -50
  67. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/migration.py +328 -222
  68. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/mybatis_integration.py +3 -1
  69. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/__init__.py +4 -3
  70. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/cache/redis_cache.py +226 -160
  71. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/circuit_breaker/circuit_breaker.py +73 -23
  72. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/configuration.py +3 -1
  73. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/core/sql_session.py +1003 -24
  74. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/dynamic_sql/dynamic_sql.py +6 -1
  75. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/pool/connection_pool.py +29 -86
  76. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/security/__init__.py +7 -1
  77. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/security/access_control.py +120 -47
  78. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/security/sql_injection_detector.py +35 -10
  79. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/transaction/transaction.py +41 -7
  80. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/version.py +1 -1
  81. springbootai-2.3.11/springbootai/py.typed +1 -0
  82. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/retry/retry_decorator.py +55 -1
  83. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/scheduling/scheduler.py +230 -125
  84. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/security/jwt_utils.py +2 -0
  85. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/security/oauth2.py +141 -35
  86. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/security/replay_protection.py +94 -26
  87. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/test/__init__.py +1 -1
  88. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/tx/__init__.py +1 -1
  89. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/tx/events.py +28 -2
  90. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/tx/synchronization.py +34 -13
  91. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/utils/banner.py +2 -2
  92. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/utils/redis_client.py +123 -68
  93. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/validation/__init__.py +1 -1
  94. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/web/actuator.py +140 -47
  95. springbootai-2.3.11/springbootai/web/exception_handler.py +101 -0
  96. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/web/health.py +108 -88
  97. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/web/interceptor.py +33 -15
  98. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/web/request_metrics.py +23 -5
  99. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/web/swagger.py +1 -1
  100. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/web/web_context.py +149 -12
  101. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/websocket/__init__.py +1 -1
  102. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/websocket/broker.py +108 -16
  103. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/websocket/handler.py +8 -4
  104. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/websocket/router.py +207 -20
  105. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/websocket/session.py +92 -39
  106. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_actuator_prometheus_admin.py +12 -8
  107. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_ai_comprehensive.py +105 -0
  108. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_ai_module.py +42 -7
  109. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_ai_stream_hardening.py +59 -0
  110. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_cloud_embedded_full.py +32 -0
  111. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_config_fixes_185.py +24 -0
  112. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_di_config_event_full.py +32 -0
  113. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_enterprise_safety_regressions.py +68 -0
  114. springbootai-2.3.11/tests/test_final_enterprise_hardening.py +452 -0
  115. springbootai-2.3.11/tests/test_followup_enterprise_fixes.py +422 -0
  116. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_io_http_logging_hardening.py +153 -5
  117. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_langchain_comprehensive.py +3 -1
  118. springbootai-2.3.11/tests/test_latest_enterprise_audit_fixes.py +267 -0
  119. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_mcp_module.py +52 -0
  120. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_oauth2.py +36 -1
  121. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_optional_component_timeouts.py +95 -5
  122. springbootai-2.3.11/tests/test_post_audit_enterprise_fixes.py +425 -0
  123. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_production_readiness.py +4 -3
  124. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_pymybatis_contract.py +37 -0
  125. springbootai-2.3.11/tests/test_remaining_enterprise_hardening.py +684 -0
  126. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_scheduling.py +25 -12
  127. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_security.py +3 -2
  128. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_security_full.py +12 -5
  129. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_websocket_module.py +40 -2
  130. springbootai-2.3.10/requirements-ai.txt +0 -50
  131. springbootai-2.3.10/springbootai/ai/core.py +0 -526
  132. springbootai-2.3.10/springbootai/ai/vectorstore.py +0 -428
  133. springbootai-2.3.10/springbootai/event/publisher.py +0 -69
  134. springbootai-2.3.10/springbootai/langchain/loaders/loaders.py +0 -207
  135. springbootai-2.3.10/springbootai/messaging/kafka.py +0 -275
  136. springbootai-2.3.10/springbootai/messaging/rabbitmq.py +0 -506
  137. springbootai-2.3.10/springbootai/web/exception_handler.py +0 -60
  138. {springbootai-2.3.10 → springbootai-2.3.11}/LICENSE +0 -0
  139. {springbootai-2.3.10 → springbootai-2.3.11}/MANIFEST.in +0 -0
  140. {springbootai-2.3.10 → springbootai-2.3.11}/SECURITY.md +0 -0
  141. {springbootai-2.3.10 → springbootai-2.3.11}/requirements-langgraph.txt +0 -0
  142. {springbootai-2.3.10 → springbootai-2.3.11}/requirements-mcp.txt +0 -0
  143. {springbootai-2.3.10 → springbootai-2.3.11}/setup.cfg +0 -0
  144. {springbootai-2.3.10 → springbootai-2.3.11}/setup.py +0 -0
  145. {springbootai-2.3.10 → springbootai-2.3.11}/springbootAI.egg-info/dependency_links.txt +0 -0
  146. {springbootai-2.3.10 → springbootai-2.3.11}/springbootAI.egg-info/entry_points.txt +0 -0
  147. {springbootai-2.3.10 → springbootai-2.3.11}/springbootAI.egg-info/top_level.txt +0 -0
  148. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/ai/etl.py +0 -0
  149. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/annotations/__init__.py +0 -0
  150. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/annotations/batch.py +0 -0
  151. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/annotations/cloud.py +0 -0
  152. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/annotations/conditional.py +0 -0
  153. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/annotations/data.py +0 -0
  154. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/annotations/enterprise.py +0 -0
  155. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/annotations/langchain.py +0 -0
  156. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/annotations/langgraph.py +0 -0
  157. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/annotations/lombok.py +0 -0
  158. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/annotations/messaging.py +0 -0
  159. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/annotations/security.py +0 -0
  160. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/aop/__init__.py +0 -0
  161. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/aop/aspect.py +0 -0
  162. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/aop/method_interceptor.py +0 -0
  163. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/aop/proxy_factory.py +0 -0
  164. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/batch/__init__.py +0 -0
  165. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cli/__init__.py +0 -0
  166. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cli/main.py +0 -0
  167. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cloud/config_center.py +0 -0
  168. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cloud/load_balancer.py +0 -0
  169. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cloud/seata.py +0 -0
  170. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cloud/seata_at_proxy.py +0 -0
  171. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cloud/seata_bridge.py +0 -0
  172. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cloud/sentinel.py +0 -0
  173. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/cloud/transaction_store.py +0 -0
  174. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/config/__init__.py +0 -0
  175. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/config/config_loader.py +0 -0
  176. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/config/config_monitor.py +0 -0
  177. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/context/__init__.py +0 -0
  178. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/context/bean_definition.py +0 -0
  179. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/context/lifecycle.py +0 -0
  180. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/context/registry.py +0 -0
  181. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/context/scanner.py +0 -0
  182. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/core/__init__.py +0 -0
  183. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/core/typing_utils.py +0 -0
  184. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/csv/annotations.py +0 -0
  185. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/csv/converters.py +0 -0
  186. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/csv/easy_csv.py +0 -0
  187. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/csv/exceptions.py +0 -0
  188. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/csv/reader.py +0 -0
  189. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/csv/writer.py +0 -0
  190. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/data/page.py +0 -0
  191. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/data/rest.py +0 -0
  192. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/data/specification.py +0 -0
  193. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/datasource/annotations.py +0 -0
  194. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/datasource/context.py +0 -0
  195. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/devtools.py +0 -0
  196. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/event/__init__.py +0 -0
  197. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/excel/annotations.py +0 -0
  198. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/excel/converters.py +0 -0
  199. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/excel/easy_excel.py +0 -0
  200. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/excel/exceptions.py +0 -0
  201. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/excel/reader.py +0 -0
  202. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/excel/style.py +0 -0
  203. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/excel/writer.py +0 -0
  204. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/i18n/accessor.py +0 -0
  205. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/i18n/auto_config.py +0 -0
  206. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/i18n/holder.py +0 -0
  207. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/i18n/locale.py +0 -0
  208. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/i18n/locale_resolver.py +0 -0
  209. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/i18n/message_source.py +0 -0
  210. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/i18n/middleware.py +0 -0
  211. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/i18n/properties.py +0 -0
  212. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/i18n/sources.py +0 -0
  213. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/agents/__init__.py +0 -0
  214. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/agents/services.py +0 -0
  215. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/annotations.py +0 -0
  216. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/callbacks/__init__.py +0 -0
  217. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/callbacks/handlers.py +0 -0
  218. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/chains/__init__.py +0 -0
  219. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/chains/services.py +0 -0
  220. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/core.py +0 -0
  221. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/indexes/__init__.py +0 -0
  222. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/indexes/index.py +0 -0
  223. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/loaders/__init__.py +0 -0
  224. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/memory/__init__.py +0 -0
  225. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/memory/memory.py +0 -0
  226. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/parsers/__init__.py +0 -0
  227. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/parsers/parsers.py +0 -0
  228. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/prompts/__init__.py +0 -0
  229. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/prompts/templates.py +0 -0
  230. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/retrievers/__init__.py +0 -0
  231. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/retrievers/retrievers.py +0 -0
  232. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/tools/__init__.py +0 -0
  233. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/utilities/__init__.py +0 -0
  234. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/utilities/utils.py +0 -0
  235. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/vectorstores/__init__.py +0 -0
  236. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langchain/vectorstores/stores.py +0 -0
  237. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langgraph/__init__.py +0 -0
  238. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langgraph/annotation_runtime.py +0 -0
  239. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langgraph/annotations.py +0 -0
  240. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/langgraph/checkpoint.py +0 -0
  241. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/logging/__init__.py +0 -0
  242. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/logging/loguru_logger.py +0 -0
  243. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/mcp/__init__.py +0 -0
  244. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/mcp/annotation_runtime.py +0 -0
  245. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/mcp/annotations.py +0 -0
  246. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/mcp/server.py +0 -0
  247. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/messaging/__init__.py +0 -0
  248. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/monitoring/__init__.py +0 -0
  249. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/monitoring/admin_client.py +0 -0
  250. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/ddl_auto.py +0 -0
  251. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/annotations/__init__.py +0 -0
  252. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/annotations/annotations.py +0 -0
  253. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/cache/__init__.py +0 -0
  254. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/cache/cache.py +0 -0
  255. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/circuit_breaker/__init__.py +0 -0
  256. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/core/__init__.py +0 -0
  257. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/core/sql_session_factory.py +0 -0
  258. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/dialect/__init__.py +0 -0
  259. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/dialect/dialect.py +0 -0
  260. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/dynamic_sql/__init__.py +0 -0
  261. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/interceptor/__init__.py +0 -0
  262. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/interceptor/interceptor.py +0 -0
  263. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/mapper/__init__.py +0 -0
  264. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/mapper/mapper.py +0 -0
  265. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/metrics/__init__.py +0 -0
  266. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/metrics/metrics.py +0 -0
  267. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/pool/__init__.py +0 -0
  268. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/security/password_encoder.py +0 -0
  269. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/security/sensitive_data_masker.py +0 -0
  270. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/transaction/__init__.py +0 -0
  271. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/type_handler/__init__.py +0 -0
  272. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/type_handler/type_handler.py +0 -0
  273. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/xml_parser/__init__.py +0 -0
  274. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/orm/pymybatis/xml_parser/xml_parser.py +0 -0
  275. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/retry/__init__.py +0 -0
  276. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/retry/recovery.py +0 -0
  277. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/retry/retry_annotations.py +0 -0
  278. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/scheduling/__init__.py +0 -0
  279. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/security/__init__.py +0 -0
  280. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/security/secret_manager.py +0 -0
  281. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/security/security_aop.py +0 -0
  282. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/security/security_context.py +0 -0
  283. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/test/slicing.py +0 -0
  284. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/tracing/__init__.py +0 -0
  285. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/tracing/skywalking.py +0 -0
  286. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/utils/__init__.py +0 -0
  287. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/utils/bean_utils.py +0 -0
  288. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/utils/logger.py +0 -0
  289. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/validation/aop.py +0 -0
  290. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/validation/constraints.py +0 -0
  291. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/validation/exceptions.py +0 -0
  292. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/validation/validator.py +0 -0
  293. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/web/__init__.py +0 -0
  294. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/web/csrf.py +0 -0
  295. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/web/hateoas.py +0 -0
  296. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/web/result.py +0 -0
  297. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/websocket/annotations.py +0 -0
  298. {springbootai-2.3.10 → springbootai-2.3.11}/springbootai/websocket/exceptions.py +0 -0
  299. {springbootai-2.3.10 → springbootai-2.3.11}/sql/seata_undo_log.sql +0 -0
  300. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_actuator.py +0 -0
  301. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_ai_annotations.py +0 -0
  302. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_ai_declarative_annotations.py +0 -0
  303. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_ai_enterprise_hardening.py +0 -0
  304. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_annotation_combinations.py +0 -0
  305. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_annotations_contract.py +0 -0
  306. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_aop_annotations_full.py +0 -0
  307. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_aop_pointcut_enhancements.py +0 -0
  308. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_audit_time.py +0 -0
  309. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_batch.py +0 -0
  310. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_bean_utils.py +0 -0
  311. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_bus.py +0 -0
  312. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_cache_annotations.py +0 -0
  313. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_cli.py +0 -0
  314. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_cloud_log_safety.py +0 -0
  315. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_component_init_error.py +0 -0
  316. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_compositional_annotations.py +0 -0
  317. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_conditional_annotations.py +0 -0
  318. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_config_admin_hardening.py +0 -0
  319. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_config_binding.py +0 -0
  320. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_config_center.py +0 -0
  321. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_config_center_hardening.py +0 -0
  322. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_config_monitor.py +0 -0
  323. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_connection_resilience.py +0 -0
  324. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_core.py +0 -0
  325. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_core_annotations_full.py +0 -0
  326. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_csrf.py +0 -0
  327. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_csv_module.py +0 -0
  328. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_data_repository.py +0 -0
  329. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_data_rest.py +0 -0
  330. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_datasource_routing.py +0 -0
  331. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_ddl_auto.py +0 -0
  332. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_declarative_aop_post_authorize_recover.py +0 -0
  333. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_devtools.py +0 -0
  334. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_devtools_lifecycle_hardening.py +0 -0
  335. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_excel_module.py +0 -0
  336. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_hateoas.py +0 -0
  337. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_i18n_module.py +0 -0
  338. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_ioc_lifecycle_enhancements.py +0 -0
  339. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_jpa_version_transient.py +0 -0
  340. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_kafka.py +0 -0
  341. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_langchain_ext.py +0 -0
  342. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_langchain_module.py +0 -0
  343. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_langgraph_comprehensive.py +0 -0
  344. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_langgraph_module.py +0 -0
  345. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_logging_config.py +0 -0
  346. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_lombok_annotations.py +0 -0
  347. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_metadata.py +0 -0
  348. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_migration.py +0 -0
  349. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_nacos_config.py +0 -0
  350. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_new_annotations.py +0 -0
  351. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_new_features.py +0 -0
  352. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_orm_pymybatis_full.py +0 -0
  353. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_pymybatis_configuration_hardening.py +0 -0
  354. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_request_metrics.py +0 -0
  355. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_retry.py +0 -0
  356. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_runtime_configuration_fixes.py +0 -0
  357. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_scaffold_hardening.py +0 -0
  358. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_seata_at_proxy.py +0 -0
  359. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_seata_bridge.py +0 -0
  360. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_seata_durable_store.py +0 -0
  361. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_security_hardening.py +0 -0
  362. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_select_page.py +0 -0
  363. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_starter.py +0 -0
  364. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_startup_lifecycle.py +0 -0
  365. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_swagger_module.py +0 -0
  366. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_test_slicing.py +0 -0
  367. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_tracing.py +0 -0
  368. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_transactional_events.py +0 -0
  369. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_validation_module.py +0 -0
  370. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_web_annotations_full.py +0 -0
  371. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_web_file_upload.py +0 -0
  372. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_web_root_mapping.py +0 -0
  373. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_web_security_responses.py +0 -0
  374. {springbootai-2.3.10 → springbootai-2.3.11}/tests/test_web_static_files.py +0 -0
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.3.11] - 2026-09-01
4
+
5
+ - 修复 PyMyBatis 访问控制仅覆盖查询、行级条件直接拼接及 SQL 尾部条件位置错误,写操作和字段权限现在失败关闭,动态租户值必须使用绑定参数。
6
+ - 修复事务提交前监听器异常被吞掉及 `REQUIRES_NEW`/`NOT_SUPPORTED` 同步上下文错误,提交否决会触发回滚并恢复外层上下文。
7
+ - 修复 Spring Cloud Bus RabbitMQ API 调用错误和缺失消费者,增加 Broker 确认、广播消费者、去重、消息大小限制及明确的失败状态。
8
+ - 加固 MCP/AI 工具边界:限制 HTTP 响应、队列、集合和 Schema 深度,拒绝压缩炸弹及高风险正则表达式。
9
+ - 修复 Prometheus Summary 创建失败、Tracer 已结束 Span 无界增长以及 Actuator/启动日志暴露原始异常的问题。
10
+ - 修复 CI 在 AI 测试切片后提前执行总覆盖率门槛的问题,覆盖率阈值现在只在全部测试切片完成后统一校验。
11
+ - 修复 LangChain 完整演示未声明文档加载根目录的问题,并为临时文件自动清理及 Windows 重定向控制台增加 UTF-8 输出兼容。
12
+
3
13
  ## [2.3.10] - 2026-08-29
4
14
 
5
15
  - 修复 AI 代理上下游消息被 SQL 注入检测误报:`#{...}` 绑定值始终按数据处理,不再扫描消息内容;`${...}` 原始替换仍默认拒绝,只有配置允许且值完整匹配严格白名单时才能使用。
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: springbootAI
3
- Version: 2.3.10
3
+ Version: 2.3.11
4
4
  Summary: Spring-style Python framework with Web, ORM, Cloud and AI integrations
5
5
  Author-email: YuConggen <1516933915@qq.com>
6
6
  License-Expression: MIT
@@ -19,7 +19,7 @@ Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
20
20
  Classifier: Topic :: Database
21
21
  Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
22
- Requires-Python: >=3.10
22
+ Requires-Python: <3.13,>=3.10
23
23
  Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
25
  Requires-Dist: fastapi==0.141.1
@@ -120,6 +120,7 @@ Requires-Dist: psutil==6.1.1; extra == "all"
120
120
  Provides-Extra: dev
121
121
  Requires-Dist: pytest==9.1.1; extra == "dev"
122
122
  Requires-Dist: pytest-cov==7.1.0; extra == "dev"
123
+ Requires-Dist: mypy==1.18.2; extra == "dev"
123
124
  Requires-Dist: redis==8.1.0; extra == "dev"
124
125
  Requires-Dist: sqlglot==27.28.1; extra == "dev"
125
126
  Provides-Extra: full
@@ -218,7 +219,7 @@ SpringBootAI 是一个采用 Spring 风格注解和分层结构的 Python 应用
218
219
  | AI 与编排 | 模型调用、Tools、RAG、Chain、状态图、MCP client/server | LangChain / LangGraph / 官方 MCP SDK |
219
220
  | 生产治理 | 健康检查、Prometheus、限流熔断、追踪、Swagger | prometheus-client / OpenTelemetry / OpenAPI |
220
221
 
221
- 当前版本是 `2.3.10`;支持 Python 3.10、3.11 和 3.12,许可证为 MIT。项目仍标记为 Beta。用于公网高并发、合规敏感或支付/订单/库存等核心系统前,必须完成目标数据库、流量模型、故障恢复和安全基线验证。内嵌 Gateway 适合内部路由,不替代公网 Nginx/Kong/WAF;Seata `distributed` 对接官方 TC + TCC 回调;`at` 是无 TC 全局锁的单进程受限补偿模式,不应当作跨服务强一致方案。
222
+ 当前版本是 `2.3.11`;支持 Python 3.10、3.11 和 3.12,许可证为 MIT。项目仍标记为 Beta。用于公网高并发、合规敏感或支付/订单/库存等核心系统前,必须完成目标数据库、流量模型、故障恢复和安全基线验证。内嵌 Gateway 适合内部路由,不替代公网 Nginx/Kong/WAF;Seata `distributed` 对接官方 TC + TCC 回调;`at` 是无 TC 全局锁的单进程受限补偿模式,不应当作跨服务强一致方案。
222
223
 
223
224
  [新手指南](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/BEGINNER_GUIDE.md) | [全部文档](https://github.com/YUCONGGEN/springbootAI/tree/master/doc) | [变更日志](https://github.com/YUCONGGEN/springbootAI/blob/master/CHANGELOG.md) | [安全报告](https://github.com/YUCONGGEN/springbootAI/blob/master/SECURITY.md) | [发布检查](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/RELEASE_CHECKLIST.md)
224
225
 
@@ -349,10 +350,10 @@ SpringBootAI 是一个 **Python Web 框架**。它把 Java Spring Boot 的"注
349
350
 
350
351
  | 组件 | 当前版本 |
351
352
  |------|----------|
352
- | `springbootai` 框架 API | 2.3.10 |
353
- | `springbootai.orm.pymybatis` | 2.3.10 |
354
- | `springbootai.ai` AI 模块 | 2.3.10 |
355
- | `springbootai.langchain` LangChain 模块 | 2.3.10 |
353
+ | `springbootai` 框架 API | 2.3.11 |
354
+ | `springbootai.orm.pymybatis` | 2.3.11 |
355
+ | `springbootai.ai` AI 模块 | 2.3.11 |
356
+ | `springbootai.langchain` LangChain 模块 | 2.3.11 |
356
357
  | Python | 3.10+ |
357
358
 
358
359
  ### 1.4 适合什么场景
@@ -56,7 +56,7 @@ SpringBootAI 是一个采用 Spring 风格注解和分层结构的 Python 应用
56
56
  | AI 与编排 | 模型调用、Tools、RAG、Chain、状态图、MCP client/server | LangChain / LangGraph / 官方 MCP SDK |
57
57
  | 生产治理 | 健康检查、Prometheus、限流熔断、追踪、Swagger | prometheus-client / OpenTelemetry / OpenAPI |
58
58
 
59
- 当前版本是 `2.3.10`;支持 Python 3.10、3.11 和 3.12,许可证为 MIT。项目仍标记为 Beta。用于公网高并发、合规敏感或支付/订单/库存等核心系统前,必须完成目标数据库、流量模型、故障恢复和安全基线验证。内嵌 Gateway 适合内部路由,不替代公网 Nginx/Kong/WAF;Seata `distributed` 对接官方 TC + TCC 回调;`at` 是无 TC 全局锁的单进程受限补偿模式,不应当作跨服务强一致方案。
59
+ 当前版本是 `2.3.11`;支持 Python 3.10、3.11 和 3.12,许可证为 MIT。项目仍标记为 Beta。用于公网高并发、合规敏感或支付/订单/库存等核心系统前,必须完成目标数据库、流量模型、故障恢复和安全基线验证。内嵌 Gateway 适合内部路由,不替代公网 Nginx/Kong/WAF;Seata `distributed` 对接官方 TC + TCC 回调;`at` 是无 TC 全局锁的单进程受限补偿模式,不应当作跨服务强一致方案。
60
60
 
61
61
  [新手指南](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/BEGINNER_GUIDE.md) | [全部文档](https://github.com/YUCONGGEN/springbootAI/tree/master/doc) | [变更日志](https://github.com/YUCONGGEN/springbootAI/blob/master/CHANGELOG.md) | [安全报告](https://github.com/YUCONGGEN/springbootAI/blob/master/SECURITY.md) | [发布检查](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/RELEASE_CHECKLIST.md)
62
62
 
@@ -187,10 +187,10 @@ SpringBootAI 是一个 **Python Web 框架**。它把 Java Spring Boot 的"注
187
187
 
188
188
  | 组件 | 当前版本 |
189
189
  |------|----------|
190
- | `springbootai` 框架 API | 2.3.10 |
191
- | `springbootai.orm.pymybatis` | 2.3.10 |
192
- | `springbootai.ai` AI 模块 | 2.3.10 |
193
- | `springbootai.langchain` LangChain 模块 | 2.3.10 |
190
+ | `springbootai` 框架 API | 2.3.11 |
191
+ | `springbootai.orm.pymybatis` | 2.3.11 |
192
+ | `springbootai.ai` AI 模块 | 2.3.11 |
193
+ | `springbootai.langchain` LangChain 模块 | 2.3.11 |
194
194
  | Python | 3.10+ |
195
195
 
196
196
  ### 1.4 适合什么场景
@@ -12,7 +12,7 @@ build-backend = "setuptools.build_meta"
12
12
  [project]
13
13
  # Distribution name: springbootAI (pip install springbootAI); import package: springbootai.
14
14
  name = "springbootAI"
15
- version = "2.3.10"
15
+ version = "2.3.11"
16
16
  description = "Spring-style Python framework with Web, ORM, Cloud and AI integrations"
17
17
  readme = "README.md"
18
18
  license = "MIT"
@@ -32,7 +32,7 @@ classifiers = [
32
32
  "Topic :: Database",
33
33
  "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
34
34
  ]
35
- requires-python = ">=3.10"
35
+ requires-python = ">=3.10,<3.13"
36
36
 
37
37
  # ========================================
38
38
  # 核心依赖——类似 Spring Boot Starter Web/Core
@@ -199,6 +199,7 @@ all = [
199
199
  dev = [
200
200
  "pytest==9.1.1",
201
201
  "pytest-cov==7.1.0",
202
+ "mypy==1.18.2",
202
203
  "redis==8.1.0",
203
204
  "sqlglot==27.28.1",
204
205
  ]
@@ -278,6 +279,43 @@ markers = [
278
279
  "seata_integration: requires a compatible Seata SDK and real Seata Server",
279
280
  ]
280
281
 
282
+ [tool.coverage.run]
283
+ branch = true
284
+ source = ["springbootai"]
285
+
286
+ [tool.coverage.report]
287
+ fail_under = 68
288
+ show_missing = true
289
+
290
+ [tool.mypy]
291
+ python_version = "3.10"
292
+ files = [
293
+ "springbootai/ai/annotation_runtime.py",
294
+ "springbootai/ai/advisors.py",
295
+ "springbootai/ai/vectorstore.py",
296
+ "springbootai/cloud/gateway.py",
297
+ "springbootai/websocket/router.py",
298
+ "springbootai/messaging/kafka.py",
299
+ "springbootai/messaging/rabbitmq.py",
300
+ "springbootai/data/repository.py",
301
+ "springbootai/retry/retry_decorator.py",
302
+ "springbootai/ai/tools.py",
303
+ "springbootai/cloud/bus.py",
304
+ "springbootai/cloud/tracer.py",
305
+ "springbootai/mcp/client.py",
306
+ "springbootai/mcp/config.py",
307
+ "springbootai/monitoring/prometheus.py",
308
+ "springbootai/orm/pymybatis/core/sql_session.py",
309
+ "springbootai/orm/pymybatis/security/access_control.py",
310
+ "springbootai/tx/synchronization.py",
311
+ ]
312
+ ignore_missing_imports = true
313
+ follow_imports = "skip"
314
+ allow_untyped_defs = true
315
+ allow_incomplete_defs = true
316
+ check_untyped_defs = true
317
+ show_error_codes = true
318
+
281
319
  [project.urls]
282
320
  Homepage = "https://github.com/YUCONGGEN/springbootAI"
283
321
  Repository = "https://github.com/YUCONGGEN/springbootAI.git"
@@ -296,4 +334,4 @@ include = ["springbootai*"]
296
334
  namespaces = false
297
335
 
298
336
  [tool.setuptools.package-data]
299
- springbootai = ["*.py", "**/*.py", "**/*.xml", "**/*.yml", "**/*.yaml"]
337
+ springbootai = ["*.py", "py.typed", "**/*.py", "**/*.xml", "**/*.yml", "**/*.yaml"]
@@ -0,0 +1,44 @@
1
+ # ========================================
2
+ # SpringBootAI optional AI/LangChain dependencies (exact versions)
3
+ # ========================================
4
+ # The AI module uses optional dependencies with a built-in fallback:
5
+ # - Without this file, native HTTP providers and FakeChatModel remain usable.
6
+ # - Installing it enables LangChain adapters detected by ai/providers.py.
7
+ #
8
+ # Install examples:
9
+ # pip install -r requirements-ai.txt
10
+ # pip install langchain-openai==1.4.2
11
+ #
12
+ # Recommended Python: 3.10+ (CI covers 3.10, 3.11 and 3.12).
13
+ # Every pinned version is covered by tests and dependency auditing.
14
+ # Keep this file ASCII-only: pip-audit may use the Windows system encoding.
15
+ # ========================================
16
+
17
+ # LangChain core (BaseChatModel, Embeddings and Runnable APIs).
18
+ langchain-core==1.5.4
19
+
20
+ # Classic APIs including LLMChain, ConversationChain and initialize_agent.
21
+ langchain-classic==1.0.8
22
+
23
+ # OpenAI-compatible providers (OpenAI, Azure, DeepSeek and Moonshot).
24
+ langchain-openai==1.4.2
25
+
26
+ # RecursiveCharacterTextSplitter and CharacterTextSplitter.
27
+ langchain-text-splitters==1.1.2
28
+
29
+ # Community integrations including FAISS, Chroma, DuckDuckGo and Wikipedia.
30
+ langchain-community==0.4.2
31
+
32
+ # Vector similarity calculations; 2.2.6 retains Python 3.10 compatibility.
33
+ numpy==2.2.6
34
+
35
+ # Pydantic v2 for validation and structured output parsing.
36
+ pydantic==2.13.4
37
+
38
+ # ========================================
39
+ # Additional optional packages (install only when needed)
40
+ # ========================================
41
+
42
+ # Vector database: faiss-cpu
43
+ # PDF document loading: pypdf
44
+ # HTML parsing: beautifulsoup4
@@ -55,9 +55,4 @@ pydantic==2.13.4
55
55
  # 测试依赖
56
56
  pytest==9.1.1
57
57
  pytest-cov==7.1.0
58
- openpyxl==3.1.5
59
-
60
- bcrypt
61
- springbootai
62
- springbootai
63
- springbootai
58
+ openpyxl==3.1.5
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: springbootAI
3
- Version: 2.3.10
3
+ Version: 2.3.11
4
4
  Summary: Spring-style Python framework with Web, ORM, Cloud and AI integrations
5
5
  Author-email: YuConggen <1516933915@qq.com>
6
6
  License-Expression: MIT
@@ -19,7 +19,7 @@ Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
20
20
  Classifier: Topic :: Database
21
21
  Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
22
- Requires-Python: >=3.10
22
+ Requires-Python: <3.13,>=3.10
23
23
  Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
25
  Requires-Dist: fastapi==0.141.1
@@ -120,6 +120,7 @@ Requires-Dist: psutil==6.1.1; extra == "all"
120
120
  Provides-Extra: dev
121
121
  Requires-Dist: pytest==9.1.1; extra == "dev"
122
122
  Requires-Dist: pytest-cov==7.1.0; extra == "dev"
123
+ Requires-Dist: mypy==1.18.2; extra == "dev"
123
124
  Requires-Dist: redis==8.1.0; extra == "dev"
124
125
  Requires-Dist: sqlglot==27.28.1; extra == "dev"
125
126
  Provides-Extra: full
@@ -218,7 +219,7 @@ SpringBootAI 是一个采用 Spring 风格注解和分层结构的 Python 应用
218
219
  | AI 与编排 | 模型调用、Tools、RAG、Chain、状态图、MCP client/server | LangChain / LangGraph / 官方 MCP SDK |
219
220
  | 生产治理 | 健康检查、Prometheus、限流熔断、追踪、Swagger | prometheus-client / OpenTelemetry / OpenAPI |
220
221
 
221
- 当前版本是 `2.3.10`;支持 Python 3.10、3.11 和 3.12,许可证为 MIT。项目仍标记为 Beta。用于公网高并发、合规敏感或支付/订单/库存等核心系统前,必须完成目标数据库、流量模型、故障恢复和安全基线验证。内嵌 Gateway 适合内部路由,不替代公网 Nginx/Kong/WAF;Seata `distributed` 对接官方 TC + TCC 回调;`at` 是无 TC 全局锁的单进程受限补偿模式,不应当作跨服务强一致方案。
222
+ 当前版本是 `2.3.11`;支持 Python 3.10、3.11 和 3.12,许可证为 MIT。项目仍标记为 Beta。用于公网高并发、合规敏感或支付/订单/库存等核心系统前,必须完成目标数据库、流量模型、故障恢复和安全基线验证。内嵌 Gateway 适合内部路由,不替代公网 Nginx/Kong/WAF;Seata `distributed` 对接官方 TC + TCC 回调;`at` 是无 TC 全局锁的单进程受限补偿模式,不应当作跨服务强一致方案。
222
223
 
223
224
  [新手指南](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/BEGINNER_GUIDE.md) | [全部文档](https://github.com/YUCONGGEN/springbootAI/tree/master/doc) | [变更日志](https://github.com/YUCONGGEN/springbootAI/blob/master/CHANGELOG.md) | [安全报告](https://github.com/YUCONGGEN/springbootAI/blob/master/SECURITY.md) | [发布检查](https://github.com/YUCONGGEN/springbootAI/blob/master/doc/RELEASE_CHECKLIST.md)
224
225
 
@@ -349,10 +350,10 @@ SpringBootAI 是一个 **Python Web 框架**。它把 Java Spring Boot 的"注
349
350
 
350
351
  | 组件 | 当前版本 |
351
352
  |------|----------|
352
- | `springbootai` 框架 API | 2.3.10 |
353
- | `springbootai.orm.pymybatis` | 2.3.10 |
354
- | `springbootai.ai` AI 模块 | 2.3.10 |
355
- | `springbootai.langchain` LangChain 模块 | 2.3.10 |
353
+ | `springbootai` 框架 API | 2.3.11 |
354
+ | `springbootai.orm.pymybatis` | 2.3.11 |
355
+ | `springbootai.ai` AI 模块 | 2.3.11 |
356
+ | `springbootai.langchain` LangChain 模块 | 2.3.11 |
356
357
  | Python | 3.10+ |
357
358
 
358
359
  ### 1.4 适合什么场景
@@ -18,6 +18,7 @@ springbootAI.egg-info/top_level.txt
18
18
  springbootai/__init__.py
19
19
  springbootai/devtools.py
20
20
  springbootai/main.py
21
+ springbootai/py.typed
21
22
  springbootai/ai/__init__.py
22
23
  springbootai/ai/advisors.py
23
24
  springbootai/ai/annotation_runtime.py
@@ -306,6 +307,8 @@ tests/test_devtools_lifecycle_hardening.py
306
307
  tests/test_di_config_event_full.py
307
308
  tests/test_enterprise_safety_regressions.py
308
309
  tests/test_excel_module.py
310
+ tests/test_final_enterprise_hardening.py
311
+ tests/test_followup_enterprise_fixes.py
309
312
  tests/test_hateoas.py
310
313
  tests/test_i18n_module.py
311
314
  tests/test_io_http_logging_hardening.py
@@ -317,6 +320,7 @@ tests/test_langchain_ext.py
317
320
  tests/test_langchain_module.py
318
321
  tests/test_langgraph_comprehensive.py
319
322
  tests/test_langgraph_module.py
323
+ tests/test_latest_enterprise_audit_fixes.py
320
324
  tests/test_logging_config.py
321
325
  tests/test_lombok_annotations.py
322
326
  tests/test_mcp_module.py
@@ -328,9 +332,11 @@ tests/test_new_features.py
328
332
  tests/test_oauth2.py
329
333
  tests/test_optional_component_timeouts.py
330
334
  tests/test_orm_pymybatis_full.py
335
+ tests/test_post_audit_enterprise_fixes.py
331
336
  tests/test_production_readiness.py
332
337
  tests/test_pymybatis_configuration_hardening.py
333
338
  tests/test_pymybatis_contract.py
339
+ tests/test_remaining_enterprise_hardening.py
334
340
  tests/test_request_metrics.py
335
341
  tests/test_retry.py
336
342
  tests/test_runtime_configuration_fixes.py
@@ -50,6 +50,7 @@ httpx==0.28.1
50
50
  [dev]
51
51
  pytest==9.1.1
52
52
  pytest-cov==7.1.0
53
+ mypy==1.18.2
53
54
  redis==8.1.0
54
55
  sqlglot==27.28.1
55
56
 
@@ -19,7 +19,7 @@ from .config import *
19
19
  from .utils import *
20
20
  from .main import create_app, run, SpringApplication, run_cli
21
21
 
22
- __version__ = "2.3.10"
22
+ __version__ = "2.3.11"
23
23
  __author__ = "yuconggen"
24
24
  __license__ = "MIT"
25
25
 
@@ -16,7 +16,8 @@ SpringBootAI AI 模块 - 对齐 Spring AI 的 ChatClient/Advisor/ETL 抽象,
16
16
  from springbootai.ai.core import (
17
17
  Advisor, AdvisorRequest, ChatClient, ChatClientBuilder, ChatModel,
18
18
  ChatResponse, EmbeddingModel, Generation, Message, MessageType,
19
- PromptSpec, TokenBudgetExceededError, ToolLoopLimitExceededError,
19
+ PromptSpec, AIConcurrencyLimitError, TokenBudgetExceededError,
20
+ ToolLoopLimitExceededError,
20
21
  )
21
22
  from springbootai.ai.annotations import (
22
23
  Agent, AiAdvisor, AiCache, AiClient, AiMemory, AiRetry, ContentModeration,
@@ -57,14 +58,14 @@ from springbootai.ai.observability import AIMetrics, ai_metrics
57
58
  from springbootai.ai.autoconfig import AIProperties, bind_ai_config, configure_ai
58
59
  from springbootai.ai.annotation_runtime import ContentModerationError
59
60
 
60
- __version__ = "2.3.10"
61
+ __version__ = "2.3.11"
61
62
 
62
63
  __all__ = [
63
64
  # core
64
65
  "Advisor", "AdvisorRequest", "ChatClient", "ChatClientBuilder",
65
66
  "ChatModel", "ChatResponse", "EmbeddingModel", "Generation", "Message",
66
67
  "MessageType", "PromptSpec", "TokenBudgetExceededError",
67
- "ToolLoopLimitExceededError",
68
+ "ToolLoopLimitExceededError", "AIConcurrencyLimitError",
68
69
  # annotations
69
70
  "AiAdvisor", "AiClient", "AiMemory", "Tool", "Prompt", "RAG",
70
71
  "StructuredOutput", "Agent", "Embedding", "VectorStore", "AiRetry",
@@ -2,6 +2,7 @@
2
2
  Advisor 实现 - QuestionAnswerAdvisor(RAG)与 MessageChatMemoryAdvisor(会话记忆)。
3
3
  """
4
4
  import inspect
5
+ import hashlib
5
6
  from urllib.parse import quote
6
7
  from typing import Any, Dict, List, Optional, Sequence
7
8
 
@@ -27,8 +28,14 @@ class MessageChatMemoryAdvisor(Advisor):
27
28
 
28
29
  @staticmethod
29
30
  def _build_namespace(context: dict) -> str:
30
- tenant = quote(str(context.get("tenant_id", "")).strip()[:128], safe="-_.~")
31
- user = quote(str(context.get("user_id", "")).strip()[:128], safe="-_.~")
31
+ def identity_part(value: Any) -> str:
32
+ raw = str(value or "").strip()
33
+ if len(raw) > 128:
34
+ raw = "sha256-" + hashlib.sha256(raw.encode("utf-8")).hexdigest()
35
+ return quote(raw, safe="-_.~")
36
+
37
+ tenant = identity_part(context.get("tenant_id", ""))
38
+ user = identity_part(context.get("user_id", ""))
32
39
  parts = [p for p in (tenant, user) if p]
33
40
  return ":".join(parts) if parts else ""
34
41
 
@@ -52,9 +59,17 @@ class MessageChatMemoryAdvisor(Advisor):
52
59
  kwargs["namespace"] = namespace
53
60
  return method(*args, **kwargs)
54
61
 
55
- def __init__(self, memory: ChatMemory, max_messages: int = 20):
62
+ def __init__(self, memory: ChatMemory, max_messages: int = 20,
63
+ allow_global_namespace: bool = False):
64
+ if isinstance(max_messages, bool) or not isinstance(max_messages, int):
65
+ raise TypeError("max_messages must be an integer")
66
+ if not 1 <= max_messages <= 100_000:
67
+ raise ValueError("max_messages must be in [1, 100000]")
68
+ if not isinstance(allow_global_namespace, bool):
69
+ raise TypeError("allow_global_namespace must be a boolean")
56
70
  self.memory = memory
57
71
  self.max_messages = max_messages
72
+ self.allow_global_namespace = allow_global_namespace
58
73
 
59
74
  def advise_request(self, request: AdvisorRequest) -> AdvisorRequest:
60
75
  conv_id = request.context.get("conversation_id")
@@ -69,6 +84,14 @@ class MessageChatMemoryAdvisor(Advisor):
69
84
  # Namespace is passed per operation. Never mutate a shared memory bean:
70
85
  # concurrent requests may belong to different tenants.
71
86
  ns = self._build_namespace(request.context)
87
+ if not ns and not self.allow_global_namespace:
88
+ request.context["memory_disabled"] = True
89
+ logger = __import__("logging").getLogger("Spring.AI")
90
+ logger.debug(
91
+ "MessageChatMemoryAdvisor: authenticated tenant/user identity "
92
+ "is missing; skipping global memory access")
93
+ return request
94
+ request.context.pop("memory_disabled", None)
72
95
  request.context["memory_namespace"] = ns
73
96
 
74
97
  history = self._call_memory(
@@ -82,7 +105,7 @@ class MessageChatMemoryAdvisor(Advisor):
82
105
  def advise_response(self, response: ChatResponse,
83
106
  request: AdvisorRequest) -> ChatResponse:
84
107
  conv_id = request.context.get("conversation_id")
85
- if not conv_id:
108
+ if not conv_id or request.context.get("memory_disabled"):
86
109
  return response
87
110
  ns = str(request.context.get("memory_namespace") or
88
111
  self._build_namespace(request.context))
@@ -120,7 +143,20 @@ class QuestionAnswerAdvisor(Advisor):
120
143
  embedding_model=None,
121
144
  harden_injection: bool = True,
122
145
  filter_metadata: Optional[Dict[str, Any]] = None,
123
- filter_context_keys: Sequence[str] = ("tenant_id",)):
146
+ filter_context_keys: Sequence[str] = ("tenant_id",),
147
+ max_context_chars: int = 100_000,
148
+ max_document_chars: int = 25_000):
149
+ if isinstance(top_k, bool) or not isinstance(top_k, int):
150
+ raise TypeError("top_k must be an integer")
151
+ if not 1 <= top_k <= 1000:
152
+ raise ValueError("top_k must be in [1, 1000]")
153
+ for name, value in (
154
+ ("max_context_chars", max_context_chars),
155
+ ("max_document_chars", max_document_chars)):
156
+ if isinstance(value, bool) or not isinstance(value, int):
157
+ raise TypeError(f"{name} must be an integer")
158
+ if not 1 <= value <= 10_000_000:
159
+ raise ValueError(f"{name} must be in [1, 10000000]")
124
160
  self.vector_store = vector_store
125
161
  self.prompt_template = prompt_template or self.DEFAULT_PROMPT_TEMPLATE
126
162
  self.top_k = top_k
@@ -128,6 +164,8 @@ class QuestionAnswerAdvisor(Advisor):
128
164
  self.harden_injection = harden_injection
129
165
  self.filter_metadata = dict(filter_metadata or {})
130
166
  self.filter_context_keys = tuple(filter_context_keys)
167
+ self.max_context_chars = max_context_chars
168
+ self.max_document_chars = max_document_chars
131
169
 
132
170
  def advise_request(self, request: AdvisorRequest) -> AdvisorRequest:
133
171
  # 取最后一条用户消息作为查询
@@ -160,10 +198,49 @@ class QuestionAnswerAdvisor(Advisor):
160
198
  filter_metadata=filters or None,
161
199
  )
162
200
  docs = self.vector_store.similarity_search(search_req)
201
+ # Missing identity must never become an implicit "all tenants" scope.
202
+ # Public documents (without tenant/user metadata) remain available for
203
+ # single-tenant and public-knowledge use cases.
204
+ identity_keys = set(self.filter_context_keys) | {"user_id"}
205
+ identity_scoped = any(key in filters for key in identity_keys)
206
+ if not identity_scoped:
207
+ docs = [
208
+ doc for doc in docs
209
+ if isinstance(doc.metadata, dict)
210
+ and not any(
211
+ doc.metadata.get(key) not in (None, "")
212
+ for key in identity_keys
213
+ )
214
+ ]
163
215
  if not docs:
164
216
  return request
165
217
 
166
- context = "\n---\n".join(d.content for d in docs)
218
+ selected_docs = []
219
+ context_parts: List[str] = []
220
+ remaining = self.max_context_chars
221
+ truncated = False
222
+ separator = "\n---\n"
223
+ for doc in docs:
224
+ content = str(doc.content or "")
225
+ if len(content) > self.max_document_chars:
226
+ content = content[:self.max_document_chars]
227
+ truncated = True
228
+ separator_cost = len(separator) if context_parts else 0
229
+ available = remaining - separator_cost
230
+ if available <= 0:
231
+ truncated = True
232
+ break
233
+ if len(content) > available:
234
+ content = content[:available]
235
+ truncated = True
236
+ if not content:
237
+ continue
238
+ context_parts.append(content)
239
+ selected_docs.append(doc)
240
+ remaining -= separator_cost + len(content)
241
+ if not context_parts:
242
+ return request
243
+ context = separator.join(context_parts)
167
244
  system_text = self.prompt_template.format(context=context)
168
245
  if self.harden_injection:
169
246
  # Prompt 注入加固:把外部文档与指令清晰隔离,并要求模型将上下文
@@ -179,8 +256,10 @@ class QuestionAnswerAdvisor(Advisor):
179
256
  request.messages = new_messages
180
257
  # 记录引用文档
181
258
  request.context["retrieved_documents"] = [
182
- {"id": d.id, "content": d.content[:200]} for d in docs
259
+ {"id": d.id, "content": str(d.content)[:200]}
260
+ for d in selected_docs
183
261
  ]
262
+ request.context["retrieval_truncated"] = truncated
184
263
  return request
185
264
 
186
265
 
@@ -190,11 +269,24 @@ class SimpleLoggerAdvisor(Advisor):
190
269
  """
191
270
  order = 0
192
271
 
193
- def __init__(self):
272
+ def __init__(self, max_events: int = 1000):
273
+ if isinstance(max_events, bool) or not isinstance(max_events, int) \
274
+ or max_events <= 0 or max_events > 100_000:
275
+ raise ValueError("max_events must be between 1 and 100000")
276
+ import threading
277
+ self.max_events = max_events
194
278
  self.events: List[Dict[str, Any]] = []
279
+ self._events_lock = threading.RLock()
280
+
281
+ def _record(self, event: Dict[str, Any]) -> None:
282
+ with self._events_lock:
283
+ self.events.append(event)
284
+ overflow = len(self.events) - self.max_events
285
+ if overflow > 0:
286
+ del self.events[:overflow]
195
287
 
196
288
  def advise_request(self, request: AdvisorRequest) -> AdvisorRequest:
197
- self.events.append({
289
+ self._record({
198
290
  "phase": "request",
199
291
  "message_count": len(request.messages),
200
292
  "tools": len(request.tool_registry.names())
@@ -204,7 +296,7 @@ class SimpleLoggerAdvisor(Advisor):
204
296
 
205
297
  def advise_response(self, response: ChatResponse,
206
298
  request: AdvisorRequest) -> ChatResponse:
207
- self.events.append({
299
+ self._record({
208
300
  "phase": "response",
209
301
  "content_length": len(response.content()),
210
302
  })