django-cfg 1.3.11__py3-none-any.whl → 1.4.0__py3-none-any.whl

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 (439) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/admin/inlines.py +11 -5
  3. django_cfg/apps/accounts/admin/user_admin.py +39 -16
  4. django_cfg/apps/accounts/serializers/profile.py +1 -1
  5. django_cfg/apps/accounts/services/otp_service.py +18 -11
  6. django_cfg/apps/accounts/signals.py +15 -24
  7. django_cfg/apps/accounts/utils/notifications.py +217 -358
  8. django_cfg/apps/accounts/views/otp.py +2 -2
  9. django_cfg/apps/accounts/views/webhook.py +1 -1
  10. django_cfg/apps/agents/core/django_agent.py +1 -1
  11. django_cfg/apps/api/commands/views.py +66 -83
  12. django_cfg/apps/api/health/drf_views.py +269 -0
  13. django_cfg/apps/api/health/serializers.py +45 -0
  14. django_cfg/apps/api/health/urls.py +6 -1
  15. django_cfg/apps/knowbase/admin/actions/__init__.py +13 -0
  16. django_cfg/apps/knowbase/admin/actions/visibility_actions.py +56 -0
  17. django_cfg/apps/knowbase/admin/document_admin.py +136 -270
  18. django_cfg/apps/knowbase/admin/helpers/__init__.py +17 -0
  19. django_cfg/apps/knowbase/admin/helpers/configs.py +72 -0
  20. django_cfg/apps/knowbase/admin/helpers/display_helpers.py +156 -0
  21. django_cfg/apps/knowbase/admin/helpers/statistics.py +108 -0
  22. django_cfg/apps/knowbase/config/constance_fields.py +1 -1
  23. django_cfg/apps/knowbase/config/settings.py +2 -2
  24. django_cfg/apps/knowbase/mixins/__init__.py +19 -2
  25. django_cfg/apps/knowbase/mixins/config/__init__.py +14 -0
  26. django_cfg/apps/knowbase/mixins/config/defaults.py +75 -0
  27. django_cfg/apps/knowbase/mixins/config/meta_config.py +120 -0
  28. django_cfg/apps/knowbase/mixins/creator.py +10 -10
  29. django_cfg/apps/knowbase/mixins/external_data_mixin.py +105 -403
  30. django_cfg/apps/knowbase/mixins/generators/__init__.py +16 -0
  31. django_cfg/apps/knowbase/mixins/generators/content_generator.py +218 -0
  32. django_cfg/apps/knowbase/mixins/generators/field_analyzer.py +76 -0
  33. django_cfg/apps/knowbase/mixins/generators/metadata_generator.py +124 -0
  34. django_cfg/apps/knowbase/mixins/service.py +2 -2
  35. django_cfg/apps/knowbase/services/archive/__init__.py +1 -0
  36. django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +17 -0
  37. django_cfg/apps/knowbase/services/archive/analyzers/complexity_analyzer.py +33 -0
  38. django_cfg/apps/knowbase/services/archive/analyzers/purpose_detector.py +36 -0
  39. django_cfg/apps/knowbase/services/archive/analyzers/quality_analyzer.py +39 -0
  40. django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +103 -0
  41. django_cfg/apps/knowbase/services/archive/chunking/__init__.py +19 -0
  42. django_cfg/apps/knowbase/services/archive/chunking/base.py +81 -0
  43. django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +62 -0
  44. django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +107 -0
  45. django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +248 -0
  46. django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +70 -0
  47. django_cfg/apps/knowbase/services/archive/chunking_service.py +110 -729
  48. django_cfg/apps/knowbase/services/archive/context/__init__.py +14 -0
  49. django_cfg/apps/knowbase/services/archive/context/builders.py +220 -0
  50. django_cfg/apps/knowbase/services/archive/context/models.py +38 -0
  51. django_cfg/apps/knowbase/services/embedding/models.py +18 -14
  52. django_cfg/apps/knowbase/services/embedding/processors.py +6 -3
  53. django_cfg/apps/knowbase/tasks/document_processing.py +11 -3
  54. django_cfg/apps/leads/tests.py +1 -1
  55. django_cfg/apps/payments/admin/api_keys_admin.py +1 -1
  56. django_cfg/apps/payments/admin/balance_admin.py +1 -1
  57. django_cfg/apps/payments/admin/currencies_admin.py +1 -1
  58. django_cfg/apps/payments/admin/payments_admin.py +1 -1
  59. django_cfg/apps/payments/admin/subscriptions_admin.py +1 -1
  60. django_cfg/apps/payments/admin_interface/templates/payments/base.html +59 -126
  61. django_cfg/apps/payments/admin_interface/views/api/payments.py +1 -1
  62. django_cfg/apps/payments/admin_interface/views/api/stats.py +1 -1
  63. django_cfg/apps/payments/admin_interface/views/api/users.py +1 -1
  64. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +1 -1
  65. django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +1 -1
  66. django_cfg/apps/payments/admin_interface/views/base.py +29 -2
  67. django_cfg/apps/payments/apps.py +1 -1
  68. django_cfg/apps/payments/config/django_cfg_integration.py +2 -2
  69. django_cfg/apps/payments/config/helpers.py +3 -2
  70. django_cfg/apps/payments/management/commands/cleanup_expired_data.py +1 -1
  71. django_cfg/apps/payments/management/commands/currency_stats.py +1 -1
  72. django_cfg/apps/payments/management/commands/manage_currencies.py +1 -1
  73. django_cfg/apps/payments/management/commands/manage_providers.py +1 -1
  74. django_cfg/apps/payments/management/commands/process_pending_payments.py +1 -1
  75. django_cfg/apps/payments/management/commands/test_providers.py +1 -1
  76. django_cfg/apps/payments/middleware/api_access.py +1 -1
  77. django_cfg/apps/payments/middleware/rate_limiting.py +1 -1
  78. django_cfg/apps/payments/middleware/usage_tracking.py +1 -1
  79. django_cfg/apps/payments/models/balance.py +2 -2
  80. django_cfg/apps/payments/models/managers/api_key_managers.py +1 -1
  81. django_cfg/apps/payments/models/managers/balance_managers.py +1 -1
  82. django_cfg/apps/payments/models/managers/currency_managers.py +1 -1
  83. django_cfg/apps/payments/models/managers/payment_managers.py +1 -1
  84. django_cfg/apps/payments/models/managers/subscription_managers.py +1 -1
  85. django_cfg/apps/payments/models/payments.py +2 -2
  86. django_cfg/apps/payments/services/cache_service/__init__.py +1 -1
  87. django_cfg/apps/payments/services/cache_service/simple_cache.py +10 -5
  88. django_cfg/apps/payments/services/core/base.py +1 -1
  89. django_cfg/apps/payments/services/core/currency/__init__.py +13 -0
  90. django_cfg/apps/payments/services/core/currency/currency_converter.py +57 -0
  91. django_cfg/apps/payments/services/core/currency/currency_validator.py +61 -0
  92. django_cfg/apps/payments/services/core/operations/__init__.py +15 -0
  93. django_cfg/apps/payments/services/core/operations/payment_canceller.py +100 -0
  94. django_cfg/apps/payments/services/core/operations/payment_creator.py +196 -0
  95. django_cfg/apps/payments/services/core/operations/status_checker.py +100 -0
  96. django_cfg/apps/payments/services/core/payment_service.py +124 -612
  97. django_cfg/apps/payments/services/core/providers/__init__.py +13 -0
  98. django_cfg/apps/payments/services/core/providers/provider_client.py +132 -0
  99. django_cfg/apps/payments/services/core/providers/status_mapper.py +89 -0
  100. django_cfg/apps/payments/services/core/utils/__init__.py +13 -0
  101. django_cfg/apps/payments/services/core/utils/data_converter.py +48 -0
  102. django_cfg/apps/payments/services/core/utils/statistics_calculator.py +69 -0
  103. django_cfg/apps/payments/services/providers/base.py +1 -1
  104. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +3 -3
  105. django_cfg/apps/payments/services/providers/nowpayments/parsers/__init__.py +9 -0
  106. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +23 -0
  107. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/constants.py +23 -0
  108. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/currency_names.py +244 -0
  109. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +511 -0
  110. django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +168 -0
  111. django_cfg/apps/payments/services/providers/nowpayments/provider.py +1 -1
  112. django_cfg/apps/payments/services/providers/nowpayments/sync.py +1 -1
  113. django_cfg/apps/payments/services/providers/registry.py +1 -1
  114. django_cfg/apps/payments/services/providers/sync_service.py +1 -1
  115. django_cfg/apps/payments/signals/__init__.py +1 -1
  116. django_cfg/apps/payments/signals/api_key_signals.py +1 -1
  117. django_cfg/apps/payments/signals/balance_signals.py +1 -1
  118. django_cfg/apps/payments/signals/payment_signals.py +1 -1
  119. django_cfg/apps/payments/signals/subscription_signals.py +1 -1
  120. django_cfg/apps/payments/views/api/api_keys.py +1 -1
  121. django_cfg/apps/payments/views/api/balances.py +1 -1
  122. django_cfg/apps/payments/views/api/base.py +1 -1
  123. django_cfg/apps/payments/views/api/currencies.py +1 -1
  124. django_cfg/apps/payments/views/api/payments.py +1 -1
  125. django_cfg/apps/payments/views/api/subscriptions.py +1 -1
  126. django_cfg/apps/payments/views/api/webhooks.py +1 -1
  127. django_cfg/apps/payments/views/serializers/api_keys.py +1 -1
  128. django_cfg/apps/payments/views/serializers/balances.py +1 -1
  129. django_cfg/apps/payments/views/serializers/currencies.py +1 -1
  130. django_cfg/apps/payments/views/serializers/payments.py +1 -1
  131. django_cfg/apps/payments/views/serializers/subscriptions.py +1 -1
  132. django_cfg/apps/payments/views/serializers/webhooks.py +1 -1
  133. django_cfg/apps/support/admin/support_admin.py +21 -13
  134. django_cfg/apps/support/templates/support/chat/access_denied.html +21 -27
  135. django_cfg/apps/support/templates/support/chat/ticket_chat.html +183 -254
  136. django_cfg/apps/support/utils/support_email_service.py +1 -1
  137. django_cfg/apps/tasks/templates/tasks/layout/base.html +20 -115
  138. django_cfg/apps/tasks/utils/simulator.py +1 -1
  139. django_cfg/apps/tasks/views/dashboard.py +33 -3
  140. django_cfg/apps/urls.py +5 -1
  141. django_cfg/cli/README.md +57 -471
  142. django_cfg/cli/commands/create_project.py +140 -529
  143. django_cfg/cli/main.py +13 -10
  144. django_cfg/core/__init__.py +63 -6
  145. django_cfg/core/base/__init__.py +5 -0
  146. django_cfg/core/base/config_model.py +652 -0
  147. django_cfg/core/builders/__init__.py +11 -0
  148. django_cfg/core/builders/apps_builder.py +258 -0
  149. django_cfg/core/builders/middleware_builder.py +115 -0
  150. django_cfg/core/builders/security_builder.py +96 -0
  151. django_cfg/core/config.py +20 -892
  152. django_cfg/core/constants.py +69 -0
  153. django_cfg/core/environment/__init__.py +9 -0
  154. django_cfg/core/exceptions.py +45 -298
  155. django_cfg/core/generation/__init__.py +51 -0
  156. django_cfg/core/generation/core_generators/__init__.py +0 -0
  157. django_cfg/core/generation/core_generators/settings.py +90 -0
  158. django_cfg/core/generation/core_generators/static.py +82 -0
  159. django_cfg/core/generation/core_generators/templates.py +141 -0
  160. django_cfg/core/generation/data_generators/__init__.py +15 -0
  161. django_cfg/core/generation/data_generators/cache.py +132 -0
  162. django_cfg/core/generation/data_generators/database.py +117 -0
  163. django_cfg/core/generation/generation.py +92 -0
  164. django_cfg/core/generation/integration_generators/__init__.py +21 -0
  165. django_cfg/core/generation/integration_generators/api.py +237 -0
  166. django_cfg/core/generation/integration_generators/sessions.py +65 -0
  167. django_cfg/core/generation/integration_generators/tailwind.py +54 -0
  168. django_cfg/core/generation/integration_generators/tasks.py +92 -0
  169. django_cfg/core/generation/integration_generators/third_party.py +144 -0
  170. django_cfg/core/generation/orchestrator.py +285 -0
  171. django_cfg/core/generation/protocols.py +30 -0
  172. django_cfg/core/generation/security_generators/__init__.py +0 -0
  173. django_cfg/core/generation/utility_generators/__init__.py +24 -0
  174. django_cfg/core/generation/utility_generators/email.py +58 -0
  175. django_cfg/core/generation/utility_generators/i18n.py +66 -0
  176. django_cfg/core/generation/utility_generators/limits.py +58 -0
  177. django_cfg/core/generation/utility_generators/logging.py +66 -0
  178. django_cfg/core/generation/utility_generators/security.py +101 -0
  179. django_cfg/core/generation/utils/__init__.py +0 -0
  180. django_cfg/core/generation/utils/helpers.py +32 -0
  181. django_cfg/core/integration/__init__.py +18 -25
  182. django_cfg/core/integration/display/startup.py +146 -133
  183. django_cfg/core/integration/url_integration.py +13 -2
  184. django_cfg/core/services/__init__.py +5 -0
  185. django_cfg/core/services/config_service.py +121 -0
  186. django_cfg/core/state/__init__.py +9 -0
  187. django_cfg/core/state/registry.py +84 -0
  188. django_cfg/core/types/__init__.py +15 -0
  189. django_cfg/core/types/aliases.py +15 -0
  190. django_cfg/core/types/enums.py +49 -0
  191. django_cfg/dashboard/DEBUG_README.md +105 -0
  192. django_cfg/dashboard/REFACTORING_SUMMARY.md +237 -0
  193. django_cfg/dashboard/__init__.py +24 -0
  194. django_cfg/dashboard/components.py +308 -0
  195. django_cfg/dashboard/debug.py +176 -0
  196. django_cfg/dashboard/management/__init__.py +0 -0
  197. django_cfg/dashboard/management/commands/__init__.py +0 -0
  198. django_cfg/dashboard/management/commands/debug_dashboard.py +109 -0
  199. django_cfg/dashboard/sections/__init__.py +1 -0
  200. django_cfg/dashboard/sections/base.py +128 -0
  201. django_cfg/dashboard/sections/commands.py +32 -0
  202. django_cfg/dashboard/sections/overview.py +394 -0
  203. django_cfg/dashboard/sections/stats.py +48 -0
  204. django_cfg/dashboard/sections/system.py +73 -0
  205. django_cfg/management/commands/check_settings.py +6 -2
  206. django_cfg/management/commands/clear_constance.py +6 -1
  207. django_cfg/management/commands/create_token.py +5 -4
  208. django_cfg/management/commands/generate.py +5 -0
  209. django_cfg/management/commands/list_urls.py +7 -2
  210. django_cfg/management/commands/migrate_all.py +6 -2
  211. django_cfg/management/commands/migrator.py +6 -1
  212. django_cfg/management/commands/rundramatiq.py +6 -1
  213. django_cfg/management/commands/rundramatiq_simulator.py +11 -4
  214. django_cfg/management/commands/runserver_ngrok.py +9 -7
  215. django_cfg/management/commands/script.py +25 -21
  216. django_cfg/management/commands/show_config.py +6 -1
  217. django_cfg/management/commands/show_urls.py +8 -3
  218. django_cfg/management/commands/superuser.py +5 -4
  219. django_cfg/management/commands/task_clear.py +8 -3
  220. django_cfg/management/commands/task_status.py +8 -3
  221. django_cfg/management/commands/test_email.py +6 -1
  222. django_cfg/management/commands/test_telegram.py +6 -1
  223. django_cfg/management/commands/test_twilio.py +6 -1
  224. django_cfg/management/commands/tree.py +7 -4
  225. django_cfg/models/__init__.py +88 -3
  226. django_cfg/models/api/__init__.py +27 -0
  227. django_cfg/models/{api.py → api/config.py} +1 -1
  228. django_cfg/models/api/drf/__init__.py +21 -0
  229. django_cfg/models/api/drf/config.py +101 -0
  230. django_cfg/models/api/drf/redoc.py +31 -0
  231. django_cfg/models/api/drf/spectacular.py +129 -0
  232. django_cfg/models/api/drf/swagger.py +59 -0
  233. django_cfg/models/{api_keys.py → api/keys.py} +16 -6
  234. django_cfg/models/{limits.py → api/limits.py} +0 -1
  235. django_cfg/models/base/__init__.py +14 -0
  236. django_cfg/models/django/__init__.py +16 -0
  237. django_cfg/models/{constance.py → django/constance.py} +1 -1
  238. django_cfg/models/{environment.py → django/environment.py} +1 -1
  239. django_cfg/models/infrastructure/__init__.py +17 -0
  240. django_cfg/models/{cache.py → infrastructure/cache.py} +3 -2
  241. django_cfg/models/infrastructure/database/__init__.py +22 -0
  242. django_cfg/models/infrastructure/database/config.py +265 -0
  243. django_cfg/models/infrastructure/database/converters.py +91 -0
  244. django_cfg/models/infrastructure/database/parsers.py +96 -0
  245. django_cfg/models/infrastructure/database/routing.py +85 -0
  246. django_cfg/models/infrastructure/database/validators.py +170 -0
  247. django_cfg/models/{logging.py → infrastructure/logging.py} +1 -1
  248. django_cfg/models/{security.py → infrastructure/security.py} +2 -2
  249. django_cfg/models/ngrok/__init__.py +11 -0
  250. django_cfg/models/ngrok/auth.py +37 -0
  251. django_cfg/models/ngrok/config.py +77 -0
  252. django_cfg/models/ngrok/tunnel.py +35 -0
  253. django_cfg/models/payments/__init__.py +20 -0
  254. django_cfg/models/payments/api_keys.py +57 -0
  255. django_cfg/models/{payments.py → payments/config.py} +56 -154
  256. django_cfg/models/payments/providers/__init__.py +15 -0
  257. django_cfg/models/payments/providers/base.py +25 -0
  258. django_cfg/models/payments/providers/nowpayments.py +48 -0
  259. django_cfg/models/services/__init__.py +18 -0
  260. django_cfg/models/services/base.py +65 -0
  261. django_cfg/models/{email.py → services/email.py} +1 -1
  262. django_cfg/models/services/telegram.py +172 -0
  263. django_cfg/models/tasks/__init__.py +51 -0
  264. django_cfg/models/tasks/backends.py +250 -0
  265. django_cfg/models/tasks/config.py +314 -0
  266. django_cfg/models/tasks/utils.py +174 -0
  267. django_cfg/modules/base.py +18 -3
  268. django_cfg/modules/django_admin/decorators/actions.py +1 -1
  269. django_cfg/modules/django_admin/decorators/display.py +1 -1
  270. django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +1 -1
  271. django_cfg/modules/django_cfg_rpc_client/README.md +346 -0
  272. django_cfg/modules/django_cfg_rpc_client/__init__.py +51 -0
  273. django_cfg/modules/django_cfg_rpc_client/client.py +540 -0
  274. django_cfg/modules/django_cfg_rpc_client/config.py +207 -0
  275. django_cfg/modules/django_cfg_rpc_client/dashboard/README.md +517 -0
  276. django_cfg/modules/django_cfg_rpc_client/dashboard/UNFOLD_INTEGRATION.md +439 -0
  277. django_cfg/modules/django_cfg_rpc_client/dashboard/__init__.py +11 -0
  278. django_cfg/modules/django_cfg_rpc_client/dashboard/apps.py +22 -0
  279. django_cfg/modules/django_cfg_rpc_client/dashboard/monitor.py +435 -0
  280. django_cfg/modules/django_cfg_rpc_client/dashboard/static/django_cfg_rpc_dashboard/js/dashboard.js +373 -0
  281. django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/base.html +76 -0
  282. django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/dashboard.html +200 -0
  283. django_cfg/modules/django_cfg_rpc_client/dashboard/urls.py +22 -0
  284. django_cfg/modules/django_cfg_rpc_client/dashboard/urls_admin.py +9 -0
  285. django_cfg/modules/django_cfg_rpc_client/dashboard/views.py +251 -0
  286. django_cfg/modules/django_cfg_rpc_client/exceptions.py +201 -0
  287. django_cfg/modules/django_drf_theme/CHANGELOG.md +210 -0
  288. django_cfg/modules/django_drf_theme/EXAMPLE.md +465 -0
  289. django_cfg/modules/django_drf_theme/IMPLEMENTATION.md +232 -0
  290. django_cfg/modules/django_drf_theme/README.md +207 -0
  291. django_cfg/modules/django_drf_theme/TAILWIND_CDN_GUIDE.md +274 -0
  292. django_cfg/modules/django_drf_theme/__init__.py +23 -0
  293. django_cfg/modules/django_drf_theme/apps.py +15 -0
  294. django_cfg/modules/django_drf_theme/renderers.py +58 -0
  295. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/api.html +375 -0
  296. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/base.html +938 -0
  297. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/filter_form.html +132 -0
  298. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/raw_data_form.html +123 -0
  299. django_cfg/modules/django_drf_theme/templatetags/__init__.py +1 -0
  300. django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +57 -0
  301. django_cfg/modules/django_email/__init__.py +14 -0
  302. django_cfg/modules/{django_email.py → django_email/service.py} +78 -113
  303. django_cfg/modules/django_email/utils.py +40 -0
  304. django_cfg/modules/django_health/__init__.py +9 -0
  305. django_cfg/modules/{django_health.py → django_health/service.py} +23 -21
  306. django_cfg/modules/django_llm/llm/client.py +155 -550
  307. django_cfg/modules/django_llm/llm/embeddings/__init__.py +13 -0
  308. django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +106 -0
  309. django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +79 -0
  310. django_cfg/modules/django_llm/llm/models_api/__init__.py +9 -0
  311. django_cfg/modules/django_llm/llm/models_api/models_query.py +163 -0
  312. django_cfg/modules/django_llm/llm/providers/__init__.py +15 -0
  313. django_cfg/modules/django_llm/llm/providers/config_builder.py +103 -0
  314. django_cfg/modules/django_llm/llm/providers/provider_manager.py +148 -0
  315. django_cfg/modules/django_llm/llm/providers/provider_selector.py +60 -0
  316. django_cfg/modules/django_llm/llm/requests/__init__.py +15 -0
  317. django_cfg/modules/django_llm/llm/requests/cache_manager.py +170 -0
  318. django_cfg/modules/django_llm/llm/requests/chat_handler.py +199 -0
  319. django_cfg/modules/django_llm/llm/requests/embedding_handler.py +113 -0
  320. django_cfg/modules/django_llm/llm/responses/__init__.py +9 -0
  321. django_cfg/modules/django_llm/llm/responses/response_builder.py +131 -0
  322. django_cfg/modules/django_llm/llm/stats/__init__.py +9 -0
  323. django_cfg/modules/django_llm/llm/stats/stats_manager.py +107 -0
  324. django_cfg/modules/django_llm/translator/detectors/__init__.py +13 -0
  325. django_cfg/modules/django_llm/translator/detectors/language_detector.py +90 -0
  326. django_cfg/modules/django_llm/translator/detectors/script_detector.py +153 -0
  327. django_cfg/modules/django_llm/translator/stats/__init__.py +11 -0
  328. django_cfg/modules/django_llm/translator/stats/stats_tracker.py +85 -0
  329. django_cfg/modules/django_llm/translator/translator.py +150 -603
  330. django_cfg/modules/django_llm/translator/translators/__init__.py +15 -0
  331. django_cfg/modules/django_llm/translator/translators/json_translator.py +316 -0
  332. django_cfg/modules/django_llm/translator/translators/text_translator.py +139 -0
  333. django_cfg/modules/django_llm/translator/utils/__init__.py +13 -0
  334. django_cfg/modules/django_llm/translator/utils/prompt_builder.py +110 -0
  335. django_cfg/modules/django_llm/translator/utils/text_utils.py +114 -0
  336. django_cfg/modules/django_logging/FIXES_SUMMARY.md +276 -0
  337. django_cfg/modules/django_logging/LOGGING_GUIDE.md +504 -0
  338. django_cfg/modules/django_logging/__init__.py +14 -0
  339. django_cfg/modules/{django_logger.py → django_logging/django_logger.py} +13 -13
  340. django_cfg/modules/{logger.py → django_logging/logger.py} +14 -4
  341. django_cfg/modules/django_ngrok/__init__.py +39 -0
  342. django_cfg/modules/{django_ngrok.py → django_ngrok/service.py} +14 -42
  343. django_cfg/modules/django_rpc_old/POETRY.md +344 -0
  344. django_cfg/modules/django_rpc_old/README.md +397 -0
  345. django_cfg/modules/django_rpc_old/TESTING.md +358 -0
  346. django_cfg/modules/django_rpc_old/__init__.py +39 -0
  347. django_cfg/modules/django_rpc_old/client.py +531 -0
  348. django_cfg/modules/django_rpc_old/config.py +279 -0
  349. django_cfg/modules/django_rpc_old/exceptions.py +172 -0
  350. django_cfg/modules/django_tailwind/README.md +478 -0
  351. django_cfg/modules/django_tailwind/__init__.py +7 -0
  352. django_cfg/modules/django_tailwind/apps.py +10 -0
  353. django_cfg/modules/django_tailwind/templates/django_tailwind/app.html +5 -0
  354. django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +117 -0
  355. django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +124 -0
  356. django_cfg/modules/django_tailwind/templates/django_tailwind/components/theme_toggle.html +54 -0
  357. django_cfg/modules/django_tailwind/templates/django_tailwind/components/user_menu.html +116 -0
  358. django_cfg/modules/django_tailwind/templates/django_tailwind/simple.html +46 -0
  359. django_cfg/modules/django_tailwind/templatetags/__init__.py +1 -0
  360. django_cfg/modules/django_tailwind/templatetags/tailwind_info.py +185 -0
  361. django_cfg/modules/django_tasks/__init__.py +29 -0
  362. django_cfg/modules/django_tasks/factory.py +127 -0
  363. django_cfg/modules/{django_tasks.py → django_tasks/service.py} +45 -274
  364. django_cfg/modules/django_tasks/settings.py +107 -0
  365. django_cfg/modules/django_telegram/__init__.py +29 -0
  366. django_cfg/modules/{django_telegram.py → django_telegram/service.py} +45 -113
  367. django_cfg/modules/django_telegram/utils.py +62 -0
  368. django_cfg/modules/django_twilio/__init__.py +54 -107
  369. django_cfg/modules/django_twilio/_imports.py +30 -0
  370. django_cfg/modules/django_twilio/base.py +192 -0
  371. django_cfg/modules/django_twilio/email_otp.py +227 -0
  372. django_cfg/modules/django_twilio/sendgrid_service.py +1 -1
  373. django_cfg/modules/django_twilio/simple_service.py +1 -2
  374. django_cfg/modules/django_twilio/sms.py +94 -0
  375. django_cfg/modules/django_twilio/twilio_service.py +2 -3
  376. django_cfg/modules/django_twilio/unified.py +310 -0
  377. django_cfg/modules/django_twilio/utils.py +190 -0
  378. django_cfg/modules/django_twilio/whatsapp.py +137 -0
  379. django_cfg/modules/django_unfold/callbacks/base.py +198 -7
  380. django_cfg/modules/django_unfold/callbacks/main.py +102 -10
  381. django_cfg/modules/django_unfold/dashboard.py +65 -43
  382. django_cfg/modules/django_unfold/models/config.py +13 -12
  383. django_cfg/modules/django_unfold/models/navigation.py +8 -3
  384. django_cfg/modules/django_unfold/models/tabs.py +2 -2
  385. django_cfg/modules/django_unfold/templates/unfold/helpers/app_list.html +102 -0
  386. django_cfg/registry/core.py +24 -26
  387. django_cfg/registry/modules.py +5 -2
  388. django_cfg/registry/services.py +20 -3
  389. django_cfg/registry/third_party.py +8 -8
  390. django_cfg/static/admin/css/dashboard.css +260 -0
  391. django_cfg/static/admin/js/commands.js +171 -0
  392. django_cfg/static/admin/js/dashboard.js +126 -0
  393. django_cfg/templates/admin/components/management_commands.js +375 -0
  394. django_cfg/templates/admin/components/progress_bar.html +18 -23
  395. django_cfg/templates/admin/index.html +48 -20
  396. django_cfg/templates/admin/index_new.html +106 -0
  397. django_cfg/templates/admin/layouts/base_dashboard.html +60 -0
  398. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +1 -20
  399. django_cfg/templates/admin/sections/commands_section.html +626 -0
  400. django_cfg/templates/admin/sections/overview_section.html +112 -0
  401. django_cfg/templates/admin/sections/stats_section.html +35 -0
  402. django_cfg/templates/admin/sections/system_section.html +99 -0
  403. django_cfg/templates/admin/snippets/components/CHARTS_GUIDE.md +322 -0
  404. django_cfg/templates/admin/snippets/components/activity_tracker.html +85 -47
  405. django_cfg/templates/admin/snippets/components/charts_section.html +154 -64
  406. django_cfg/templates/admin/snippets/components/django_commands.html +3 -3
  407. django_cfg/templates/admin/snippets/components/recent_activity_improved.html +25 -0
  408. django_cfg/templates/admin/snippets/components/recent_users_table.html +1 -1
  409. django_cfg/templates/admin/snippets/components/system_metrics.html +179 -93
  410. django_cfg/templates/admin/snippets/zones/zones_table.html +2 -2
  411. django_cfg/templatetags/django_cfg.py +7 -1
  412. django_cfg/utils/smart_defaults.py +4 -4
  413. django_cfg-1.4.0.dist-info/METADATA +920 -0
  414. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/RECORD +425 -196
  415. django_cfg/apps/accounts/utils/auth_email_service.py +0 -84
  416. django_cfg/apps/payments/services/providers/nowpayments/parsers.py +0 -879
  417. django_cfg/core/generation.py +0 -621
  418. django_cfg/management/commands/validate_config.py +0 -189
  419. django_cfg/models/database.py +0 -480
  420. django_cfg/models/drf.py +0 -272
  421. django_cfg/models/ngrok.py +0 -122
  422. django_cfg/models/services.py +0 -440
  423. django_cfg/models/tasks.py +0 -550
  424. django_cfg/modules/django_twilio/service.py +0 -942
  425. django_cfg/template_archive/django_sample.zip +0 -0
  426. django_cfg/templates/rest_framework/api.html +0 -12
  427. django_cfg/utils/toolkit.py +0 -703
  428. django_cfg-1.3.11.dist-info/METADATA +0 -1029
  429. /django_cfg/apps/accounts/management/commands/{test_otp.py → otp_test.py} +0 -0
  430. /django_cfg/core/{environment.py → environment/detector.py} +0 -0
  431. /django_cfg/models/{cors.py → api/cors.py} +0 -0
  432. /django_cfg/models/{jwt.py → api/jwt.py} +0 -0
  433. /django_cfg/models/{base.py → base/config.py} +0 -0
  434. /django_cfg/models/{cfg.py → base/module.py} +0 -0
  435. /django_cfg/models/{revolution.py → django/revolution.py} +0 -0
  436. /django_cfg/modules/{dramatiq_setup.py → django_tasks/dramatiq_setup.py} +0 -0
  437. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/WHEEL +0 -0
  438. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/entry_points.txt +0 -0
  439. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,15 @@
1
+ """
2
+ Request handling for LLM client.
3
+
4
+ Handles chat completion and embedding requests with caching.
5
+ """
6
+
7
+ from .cache_manager import RequestCacheManager
8
+ from .chat_handler import ChatRequestHandler
9
+ from .embedding_handler import EmbeddingRequestHandler
10
+
11
+ __all__ = [
12
+ 'RequestCacheManager',
13
+ 'ChatRequestHandler',
14
+ 'EmbeddingRequestHandler',
15
+ ]
@@ -0,0 +1,170 @@
1
+ """
2
+ Cache manager for LLM requests.
3
+
4
+ Manages caching of chat and embedding requests.
5
+ """
6
+
7
+ import logging
8
+ from typing import Optional, Dict, Any, List
9
+ from pathlib import Path
10
+
11
+ from ..cache import LLMCache
12
+ from ..models import ChatCompletionResponse, EmbeddingResponse
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class RequestCacheManager:
18
+ """Manages caching for LLM requests."""
19
+
20
+ def __init__(
21
+ self,
22
+ cache_dir: Optional[Path] = None,
23
+ cache_ttl: int = 3600,
24
+ max_cache_size: int = 1000
25
+ ):
26
+ """
27
+ Initialize cache manager.
28
+
29
+ Args:
30
+ cache_dir: Cache directory path
31
+ cache_ttl: Cache TTL in seconds
32
+ max_cache_size: Maximum cache size
33
+ """
34
+ self.cache = LLMCache(
35
+ cache_dir=cache_dir,
36
+ ttl=cache_ttl,
37
+ max_size=max_cache_size
38
+ )
39
+
40
+ def get_cached_chat(
41
+ self,
42
+ messages: List[Dict[str, str]],
43
+ model: str,
44
+ max_tokens: Optional[int] = None,
45
+ temperature: Optional[float] = None,
46
+ response_format: Optional[str] = None,
47
+ **kwargs
48
+ ) -> Optional[ChatCompletionResponse]:
49
+ """
50
+ Get cached chat completion response.
51
+
52
+ Args:
53
+ messages: Chat messages
54
+ model: Model used
55
+ max_tokens: Max tokens
56
+ temperature: Temperature
57
+ response_format: Response format
58
+ **kwargs: Additional parameters
59
+
60
+ Returns:
61
+ Cached response or None
62
+ """
63
+ request_hash = self.cache.generate_request_hash(
64
+ messages=messages,
65
+ model=model,
66
+ max_tokens=max_tokens,
67
+ temperature=temperature,
68
+ response_format=response_format,
69
+ **kwargs
70
+ )
71
+
72
+ cached_response = self.cache.get_response(request_hash)
73
+ if cached_response:
74
+ logger.debug("Cache hit for chat completion")
75
+ return ChatCompletionResponse(**cached_response)
76
+
77
+ return None
78
+
79
+ def cache_chat_response(
80
+ self,
81
+ response: ChatCompletionResponse,
82
+ messages: List[Dict[str, str]],
83
+ model: str,
84
+ max_tokens: Optional[int] = None,
85
+ temperature: Optional[float] = None,
86
+ response_format: Optional[str] = None,
87
+ **kwargs
88
+ ):
89
+ """
90
+ Cache chat completion response.
91
+
92
+ Args:
93
+ response: Response to cache
94
+ messages: Chat messages
95
+ model: Model used
96
+ max_tokens: Max tokens
97
+ temperature: Temperature
98
+ response_format: Response format
99
+ **kwargs: Additional parameters
100
+ """
101
+ request_hash = self.cache.generate_request_hash(
102
+ messages=messages,
103
+ model=model,
104
+ max_tokens=max_tokens,
105
+ temperature=temperature,
106
+ response_format=response_format,
107
+ **kwargs
108
+ )
109
+
110
+ self.cache.set_response(request_hash, response.model_dump(), model)
111
+ logger.debug("Cached chat completion response")
112
+
113
+ def get_cached_embedding(
114
+ self,
115
+ text: str,
116
+ model: str
117
+ ) -> Optional[EmbeddingResponse]:
118
+ """
119
+ Get cached embedding response.
120
+
121
+ Args:
122
+ text: Input text
123
+ model: Model used
124
+
125
+ Returns:
126
+ Cached response or None
127
+ """
128
+ request_hash = self.cache.generate_request_hash(
129
+ messages=[{"role": "user", "content": text}],
130
+ model=model,
131
+ task="embedding"
132
+ )
133
+
134
+ cached_response = self.cache.get_response(request_hash)
135
+ if cached_response:
136
+ logger.debug("Cache hit for embedding generation")
137
+ return EmbeddingResponse(**cached_response)
138
+
139
+ return None
140
+
141
+ def cache_embedding_response(
142
+ self,
143
+ response: EmbeddingResponse,
144
+ text: str,
145
+ model: str
146
+ ):
147
+ """
148
+ Cache embedding response.
149
+
150
+ Args:
151
+ response: Response to cache
152
+ text: Input text
153
+ model: Model used
154
+ """
155
+ request_hash = self.cache.generate_request_hash(
156
+ messages=[{"role": "user", "content": text}],
157
+ model=model,
158
+ task="embedding"
159
+ )
160
+
161
+ self.cache.set_response(request_hash, response.model_dump(), model)
162
+ logger.debug("Cached embedding response")
163
+
164
+ def get_cache_info(self) -> Dict[str, Any]:
165
+ """Get cache information."""
166
+ return self.cache.get_cache_info()
167
+
168
+ def clear_cache(self):
169
+ """Clear the cache."""
170
+ self.cache.clear_cache()
@@ -0,0 +1,199 @@
1
+ """
2
+ Chat request handler for LLM client.
3
+
4
+ Handles chat completion requests with caching and response building.
5
+ """
6
+
7
+ import time
8
+ import logging
9
+ from typing import List, Dict, Optional, TYPE_CHECKING
10
+
11
+ from ..models import ChatCompletionResponse
12
+ from ..providers import ConfigBuilder
13
+
14
+ if TYPE_CHECKING:
15
+ from ..providers import ProviderManager
16
+ from ..responses import ResponseBuilder
17
+ from ..stats import StatsManager
18
+ from .cache_manager import RequestCacheManager
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ class ChatRequestHandler:
24
+ """Handles chat completion requests with caching."""
25
+
26
+ def __init__(
27
+ self,
28
+ provider_manager: 'ProviderManager',
29
+ cache_manager: 'RequestCacheManager',
30
+ stats_manager: 'StatsManager',
31
+ response_builder: 'ResponseBuilder',
32
+ tokenizer
33
+ ):
34
+ """
35
+ Initialize chat request handler.
36
+
37
+ Args:
38
+ provider_manager: Provider manager instance
39
+ cache_manager: Cache manager instance
40
+ stats_manager: Stats manager instance
41
+ response_builder: Response builder instance
42
+ tokenizer: Tokenizer instance
43
+ """
44
+ self.provider_manager = provider_manager
45
+ self.cache_manager = cache_manager
46
+ self.stats_manager = stats_manager
47
+ self.response_builder = response_builder
48
+ self.tokenizer = tokenizer
49
+
50
+ def chat_completion(
51
+ self,
52
+ messages: List[Dict[str, str]],
53
+ model: Optional[str] = None,
54
+ max_tokens: Optional[int] = None,
55
+ temperature: Optional[float] = None,
56
+ response_format: Optional[str] = None,
57
+ **kwargs
58
+ ) -> ChatCompletionResponse:
59
+ """
60
+ Execute chat completion with caching.
61
+
62
+ Args:
63
+ messages: List of chat messages
64
+ model: Model to use
65
+ max_tokens: Maximum tokens
66
+ temperature: Temperature for generation
67
+ response_format: Response format (e.g., "json")
68
+ **kwargs: Additional parameters
69
+
70
+ Returns:
71
+ Chat completion response
72
+
73
+ Raises:
74
+ RuntimeError: If client is not initialized or request fails
75
+ """
76
+ # Get client and provider
77
+ client = self.provider_manager.primary_client
78
+ provider = self.provider_manager.primary_provider
79
+
80
+ if not client:
81
+ raise RuntimeError("OpenAI client not initialized")
82
+
83
+ # Use default model if needed
84
+ if model is None:
85
+ model = ConfigBuilder.get_default_model(provider)
86
+
87
+ # Prepare API model (remove prefix for OpenAI)
88
+ api_model = self._prepare_api_model(model, provider)
89
+
90
+ # Check cache
91
+ cached_response = self.cache_manager.get_cached_chat(
92
+ messages, model, max_tokens, temperature, response_format, **kwargs
93
+ )
94
+ if cached_response:
95
+ self.stats_manager.record_cache_hit()
96
+ return cached_response
97
+
98
+ self.stats_manager.record_cache_miss()
99
+ self.stats_manager.record_request()
100
+
101
+ # Estimate tokens
102
+ estimated_tokens = self.tokenizer.count_messages_tokens(messages, model)
103
+ logger.debug(f"Estimated input tokens: {estimated_tokens}")
104
+
105
+ # Make API call
106
+ start_time = time.time()
107
+ try:
108
+ api_response = self._make_api_call(
109
+ client, api_model, messages, max_tokens, temperature, response_format, **kwargs
110
+ )
111
+ processing_time = time.time() - start_time
112
+
113
+ # Build response object
114
+ completion_response = self.response_builder.build_chat_response(
115
+ api_response, model, provider, response_format, processing_time
116
+ )
117
+
118
+ # Cache response
119
+ self.cache_manager.cache_chat_response(
120
+ completion_response, messages, model, max_tokens, temperature, response_format, **kwargs
121
+ )
122
+
123
+ # Update stats
124
+ self.stats_manager.record_success(
125
+ tokens=completion_response.tokens_used,
126
+ cost=completion_response.cost_usd,
127
+ model=model,
128
+ provider=provider
129
+ )
130
+
131
+ return completion_response
132
+
133
+ except Exception as e:
134
+ self.stats_manager.record_failure()
135
+ logger.error(f"Chat completion failed: {e}")
136
+ raise
137
+
138
+ def _prepare_api_model(self, model: str, provider: str) -> str:
139
+ """
140
+ Prepare model name for API call.
141
+
142
+ For OpenAI, remove provider prefix if present.
143
+
144
+ Args:
145
+ model: Model name
146
+ provider: Provider name
147
+
148
+ Returns:
149
+ API-ready model name
150
+ """
151
+ api_model = model
152
+ if provider == "openai" and model.startswith("openai/"):
153
+ api_model = model.replace("openai/", "")
154
+ return api_model
155
+
156
+ def _make_api_call(
157
+ self,
158
+ client,
159
+ model: str,
160
+ messages: List[Dict[str, str]],
161
+ max_tokens: Optional[int],
162
+ temperature: Optional[float],
163
+ response_format: Optional[str],
164
+ **kwargs
165
+ ):
166
+ """
167
+ Make actual API call.
168
+
169
+ Args:
170
+ client: OpenAI client
171
+ model: Model to use
172
+ messages: Chat messages
173
+ max_tokens: Max tokens
174
+ temperature: Temperature
175
+ response_format: Response format
176
+ **kwargs: Additional parameters
177
+
178
+ Returns:
179
+ API response
180
+ """
181
+ params = {
182
+ "model": model,
183
+ "messages": messages,
184
+ "stream": False
185
+ }
186
+
187
+ # Add optional parameters
188
+ if max_tokens is not None:
189
+ params["max_tokens"] = max_tokens
190
+ if temperature is not None:
191
+ params["temperature"] = temperature
192
+ if response_format:
193
+ params["response_format"] = {"type": response_format}
194
+
195
+ # Add any additional kwargs
196
+ params.update(kwargs)
197
+
198
+ logger.debug(f"Making chat completion request with model: {model}")
199
+ return client.chat.completions.create(**params)
@@ -0,0 +1,113 @@
1
+ """
2
+ Embedding request handler for LLM client.
3
+
4
+ Handles embedding generation requests with provider-specific strategies.
5
+ """
6
+
7
+ import logging
8
+ from typing import TYPE_CHECKING
9
+
10
+ from ..models import EmbeddingResponse
11
+
12
+ if TYPE_CHECKING:
13
+ from ..providers import ProviderManager, ProviderSelector
14
+ from ..embeddings import OpenAIEmbedder, MockEmbedder
15
+ from ..stats import StatsManager
16
+ from .cache_manager import RequestCacheManager
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ class EmbeddingRequestHandler:
22
+ """Handles embedding generation requests."""
23
+
24
+ def __init__(
25
+ self,
26
+ provider_manager: 'ProviderManager',
27
+ provider_selector: 'ProviderSelector',
28
+ cache_manager: 'RequestCacheManager',
29
+ stats_manager: 'StatsManager',
30
+ openai_embedder: 'OpenAIEmbedder',
31
+ mock_embedder: 'MockEmbedder'
32
+ ):
33
+ """
34
+ Initialize embedding request handler.
35
+
36
+ Args:
37
+ provider_manager: Provider manager instance
38
+ provider_selector: Provider selector instance
39
+ cache_manager: Cache manager instance
40
+ stats_manager: Stats manager instance
41
+ openai_embedder: OpenAI embedder instance
42
+ mock_embedder: Mock embedder instance
43
+ """
44
+ self.provider_manager = provider_manager
45
+ self.provider_selector = provider_selector
46
+ self.cache_manager = cache_manager
47
+ self.stats_manager = stats_manager
48
+ self.openai_embedder = openai_embedder
49
+ self.mock_embedder = mock_embedder
50
+
51
+ def generate_embedding(
52
+ self,
53
+ text: str,
54
+ model: str = "text-embedding-ada-002"
55
+ ) -> EmbeddingResponse:
56
+ """
57
+ Generate embedding with provider-specific logic.
58
+
59
+ Uses real OpenAI embeddings when available, falls back to mock
60
+ embeddings for providers without embedding support.
61
+
62
+ Args:
63
+ text: Text to generate embedding for
64
+ model: Embedding model to use
65
+
66
+ Returns:
67
+ Embedding response with vector and metadata
68
+
69
+ Raises:
70
+ RuntimeError: If embedding generation fails
71
+ """
72
+ # Check cache
73
+ cached_response = self.cache_manager.get_cached_embedding(text, model)
74
+ if cached_response:
75
+ self.stats_manager.record_cache_hit()
76
+ return cached_response
77
+
78
+ self.stats_manager.record_cache_miss()
79
+ self.stats_manager.record_request()
80
+
81
+ # Get best provider for embedding
82
+ provider = self.provider_selector.get_provider_for_task("embedding")
83
+
84
+ try:
85
+ # Generate embedding using appropriate strategy
86
+ if self.provider_selector.should_use_mock_embedding(provider):
87
+ # Use mock embedder for OpenRouter
88
+ logger.debug(f"Using mock embedder for provider: {provider}")
89
+ result = self.mock_embedder.generate(text, model)
90
+ else:
91
+ # Use real OpenAI embeddings
92
+ logger.debug(f"Using OpenAI embedder for provider: {provider}")
93
+ client = self.provider_manager.get_client(provider)
94
+ result = self.openai_embedder.generate(client, text, model)
95
+
96
+ # Cache response
97
+ self.cache_manager.cache_embedding_response(result, text, model)
98
+
99
+ # Update stats
100
+ self.stats_manager.record_success(
101
+ tokens=result.tokens,
102
+ cost=result.cost,
103
+ model=model,
104
+ provider=provider
105
+ )
106
+
107
+ return result
108
+
109
+ except Exception as e:
110
+ self.stats_manager.record_failure()
111
+ error_msg = f"Embedding generation failed: {e}"
112
+ logger.error(error_msg)
113
+ raise RuntimeError(error_msg) from e
@@ -0,0 +1,9 @@
1
+ """
2
+ Response handling for LLM client.
3
+
4
+ Builds Pydantic response objects from API responses.
5
+ """
6
+
7
+ from .response_builder import ResponseBuilder
8
+
9
+ __all__ = ['ResponseBuilder']
@@ -0,0 +1,131 @@
1
+ """
2
+ Response builder for LLM client.
3
+
4
+ Builds Pydantic response objects from API responses.
5
+ """
6
+
7
+ import time
8
+ import logging
9
+ from datetime import datetime
10
+ from typing import Optional
11
+ from openai.types.chat import ChatCompletion
12
+
13
+ from ..costs import calculate_chat_cost
14
+ from ..models import ChatCompletionResponse, ChatChoice, TokenUsage
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class ResponseBuilder:
20
+ """Builds Pydantic response objects from API responses."""
21
+
22
+ def __init__(self, models_cache=None, json_extractor=None):
23
+ """
24
+ Initialize response builder.
25
+
26
+ Args:
27
+ models_cache: Optional models cache for cost calculation
28
+ json_extractor: Optional JSON extractor for parsing JSON responses
29
+ """
30
+ self.models_cache = models_cache
31
+ self.json_extractor = json_extractor
32
+
33
+ def build_chat_response(
34
+ self,
35
+ api_response: ChatCompletion,
36
+ model: str,
37
+ provider: str,
38
+ response_format: Optional[str] = None,
39
+ processing_time: float = 0.0
40
+ ) -> ChatCompletionResponse:
41
+ """
42
+ Build ChatCompletionResponse from API response.
43
+
44
+ Args:
45
+ api_response: Raw API response from OpenAI
46
+ model: Model used for generation
47
+ provider: Provider used
48
+ response_format: Response format (e.g., "json")
49
+ processing_time: Time taken to process request
50
+
51
+ Returns:
52
+ ChatCompletionResponse Pydantic model
53
+ """
54
+ # Calculate cost
55
+ usage_dict = self._extract_usage(api_response)
56
+ cost_usd = calculate_chat_cost(usage_dict, model, self.models_cache)
57
+
58
+ # Extract content
59
+ content = self._extract_content(api_response)
60
+
61
+ # Try to extract JSON if requested
62
+ extracted_json = None
63
+ if response_format == "json" and content and self.json_extractor:
64
+ try:
65
+ extracted_json = self.json_extractor.extract_json_from_response(content)
66
+ except Exception as e:
67
+ logger.warning(f"Failed to extract JSON from response: {e}")
68
+
69
+ # Build response object
70
+ return ChatCompletionResponse(
71
+ id=api_response.id,
72
+ model=api_response.model,
73
+ created=datetime.fromtimestamp(api_response.created).isoformat(),
74
+ choices=self._build_choices(api_response),
75
+ usage=self._build_token_usage(api_response.usage),
76
+ finish_reason=self._extract_finish_reason(api_response),
77
+ content=content,
78
+ tokens_used=usage_dict['total_tokens'],
79
+ cost_usd=cost_usd,
80
+ processing_time=processing_time,
81
+ extracted_json=extracted_json
82
+ )
83
+
84
+ def _extract_usage(self, api_response: ChatCompletion) -> dict:
85
+ """Extract usage dictionary from API response."""
86
+ if api_response.usage:
87
+ return api_response.usage.model_dump()
88
+ return {
89
+ 'total_tokens': 0,
90
+ 'prompt_tokens': 0,
91
+ 'completion_tokens': 0
92
+ }
93
+
94
+ def _extract_content(self, api_response: ChatCompletion) -> str:
95
+ """Extract content from API response."""
96
+ if api_response.choices and len(api_response.choices) > 0:
97
+ return api_response.choices[0].message.content or ""
98
+ return ""
99
+
100
+ def _extract_finish_reason(self, api_response: ChatCompletion) -> Optional[str]:
101
+ """Extract finish reason from API response."""
102
+ if api_response.choices and len(api_response.choices) > 0:
103
+ return api_response.choices[0].finish_reason
104
+ return None
105
+
106
+ def _build_choices(self, api_response: ChatCompletion) -> list:
107
+ """Build list of ChatChoice objects from API response."""
108
+ if not api_response.choices:
109
+ return []
110
+
111
+ return [
112
+ ChatChoice(
113
+ index=choice.index,
114
+ message=choice.message.model_dump() if hasattr(choice.message, 'model_dump') else choice.message,
115
+ finish_reason=choice.finish_reason
116
+ ) for choice in api_response.choices
117
+ ]
118
+
119
+ def _build_token_usage(self, usage) -> TokenUsage:
120
+ """Build TokenUsage object from API response usage."""
121
+ if usage:
122
+ return TokenUsage(
123
+ prompt_tokens=usage.prompt_tokens,
124
+ completion_tokens=usage.completion_tokens,
125
+ total_tokens=usage.total_tokens
126
+ )
127
+ return TokenUsage(
128
+ prompt_tokens=0,
129
+ completion_tokens=0,
130
+ total_tokens=0
131
+ )
@@ -0,0 +1,9 @@
1
+ """
2
+ Statistics management for LLM client.
3
+
4
+ Tracks usage, costs, and performance metrics.
5
+ """
6
+
7
+ from .stats_manager import StatsManager
8
+
9
+ __all__ = ['StatsManager']