iatoolkit 2.44.4__tar.gz → 2.45.1__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 (252) hide show
  1. {iatoolkit-2.44.4/src/iatoolkit.egg-info → iatoolkit-2.45.1}/PKG-INFO +1 -1
  2. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/__init__.py +1 -1
  3. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/llm_providers/openai_compatible_chat_adapter.py +64 -7
  4. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/llm_providers/openrouter_adapter.py +3 -30
  5. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/llm_proxy.py +36 -0
  6. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/llm_response.py +1 -1
  7. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/license_service.py +1 -14
  8. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/llm_client_service.py +10 -1
  9. iatoolkit-2.45.1/src/iatoolkit/services/operator_identity_service.py +104 -0
  10. {iatoolkit-2.44.4 → iatoolkit-2.45.1/src/iatoolkit.egg-info}/PKG-INFO +1 -1
  11. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit.egg-info/SOURCES.txt +1 -0
  12. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/LICENSE +0 -0
  13. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/LICENSE_COMMUNITY.md +0 -0
  14. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/pyproject.toml +0 -0
  15. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/readme.md +0 -0
  16. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/requirements.txt +0 -0
  17. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/setup.cfg +0 -0
  18. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/base_company.py +0 -0
  19. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/cli_commands.py +0 -0
  20. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/__init__.py +0 -0
  21. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/bridge_validation.py +0 -0
  22. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/exceptions.py +0 -0
  23. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/interfaces/__init__.py +0 -0
  24. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/interfaces/asset_storage.py +0 -0
  25. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/interfaces/database_provider.py +0 -0
  26. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/interfaces/memory_compilation_trigger.py +0 -0
  27. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/interfaces/memory_lint_trigger.py +0 -0
  28. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/interfaces/secret_provider.py +0 -0
  29. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/interfaces/signup_policy_resolver.py +0 -0
  30. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/interfaces/web_search_provider.py +0 -0
  31. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/model_registry.py +0 -0
  32. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/routes.py +0 -0
  33. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/secret_resolver.py +0 -0
  34. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/session_manager.py +0 -0
  35. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/common/util.py +0 -0
  36. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/company_registry.py +0 -0
  37. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/__init__.py +0 -0
  38. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/llm_capabilities.yaml +0 -0
  39. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/channel_business_identity.prompt +0 -0
  40. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/channel_conversation_continuity.prompt +0 -0
  41. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/channel_response_style.prompt +0 -0
  42. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/chat_state_rules.prompt +0 -0
  43. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/chat_user_profile.prompt +0 -0
  44. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/core_identity.prompt +0 -0
  45. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/email_output.prompt +0 -0
  46. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/file_download_output.prompt +0 -0
  47. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/format_styles.prompt +0 -0
  48. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/html_structures.prompt +0 -0
  49. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/links_documents.prompt +0 -0
  50. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/memory_usage.prompt +0 -0
  51. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/multimodal_basics.prompt +0 -0
  52. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/output_basics.prompt +0 -0
  53. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/presentation_formatting.prompt +0 -0
  54. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/query_main.prompt +0 -0
  55. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/sql_aggregation_scope.prompt +0 -0
  56. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/sql_casting.prompt +0 -0
  57. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/sql_core.prompt +0 -0
  58. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/sql_jsonb.prompt +0 -0
  59. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/sql_mysql_casting.prompt +0 -0
  60. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/sql_mysql_json.prompt +0 -0
  61. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/sql_redshift_basics.prompt +0 -0
  62. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/sql_redshift_types.prompt +0 -0
  63. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/sql_rules.prompt +0 -0
  64. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts/tool_html_passthrough.prompt +0 -0
  65. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_prompts_pack.yaml +0 -0
  66. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/config/system_tools_pack.yaml +0 -0
  67. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/core.py +0 -0
  68. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/__init__.py +0 -0
  69. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/brevo_mail_app.py +0 -0
  70. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/call_service.py +0 -0
  71. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/connectors/__init__.py +0 -0
  72. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
  73. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
  74. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
  75. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
  76. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
  77. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
  78. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/google_auth_client.py +0 -0
  79. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/google_chat_app.py +0 -0
  80. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/inference_embeddings_client.py +0 -0
  81. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/inference_handler.py +0 -0
  82. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/jina_embeddings_client.py +0 -0
  83. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/llm_gateway_resolver.py +0 -0
  84. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/llm_providers/__init__.py +0 -0
  85. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/llm_providers/anthropic_adapter.py +0 -0
  86. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/llm_providers/deepseek_adapter.py +0 -0
  87. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/llm_providers/gemini_adapter.py +0 -0
  88. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/llm_providers/openai_adapter.py +0 -0
  89. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/infra/redis_session_manager.py +0 -0
  90. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/locales/en.yaml +0 -0
  91. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/locales/es.yaml +0 -0
  92. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/__init__.py +0 -0
  93. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/api_key_repo.py +0 -0
  94. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/bridge_repo.py +0 -0
  95. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/database_manager.py +0 -0
  96. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/document_repo.py +0 -0
  97. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/env_secret_provider.py +0 -0
  98. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/filesystem_asset_repository.py +0 -0
  99. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/knowledge_wiki_repo.py +0 -0
  100. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/llm_query_repo.py +0 -0
  101. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/mcp_token_repo.py +0 -0
  102. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/memory_repo.py +0 -0
  103. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/models.py +0 -0
  104. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/profile_repo.py +0 -0
  105. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/prompt_resource_repo.py +0 -0
  106. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/sql_dataset_repo.py +0 -0
  107. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/sql_source_repo.py +0 -0
  108. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/repositories/vs_repo.py +0 -0
  109. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/runtime_logging.py +0 -0
  110. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/__init__.py +0 -0
  111. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/api_key_service.py +0 -0
  112. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/attachment_policy_service.py +0 -0
  113. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/auth_service.py +0 -0
  114. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/benchmark_service.py +0 -0
  115. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/branding_service.py +0 -0
  116. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/company_context_service.py +0 -0
  117. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/configuration_service.py +0 -0
  118. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/context_builder_service.py +0 -0
  119. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/dispatcher_service.py +0 -0
  120. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/embedding_service.py +0 -0
  121. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/excel_service.py +0 -0
  122. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/file_processor_service.py +0 -0
  123. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/history_manager_service.py +0 -0
  124. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/http_tool_service.py +0 -0
  125. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/i18n_service.py +0 -0
  126. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/inference_service.py +0 -0
  127. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/jwt_service.py +0 -0
  128. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/knowledge_base_service.py +0 -0
  129. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/language_service.py +0 -0
  130. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/mail_service.py +0 -0
  131. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/markdown_wiki_service.py +0 -0
  132. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/mcp_token_service.py +0 -0
  133. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/memory_compiler_service.py +0 -0
  134. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/memory_lint_service.py +0 -0
  135. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/memory_lookup_policy_service.py +0 -0
  136. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/memory_service.py +0 -0
  137. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/memory_wiki_service.py +0 -0
  138. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/noop_memory_compilation_trigger.py +0 -0
  139. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/noop_memory_lint_trigger.py +0 -0
  140. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/parsers/__init__.py +0 -0
  141. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/parsers/contracts.py +0 -0
  142. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/parsers/image_normalizer.py +0 -0
  143. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/parsers/parsing_service.py +0 -0
  144. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/parsers/pdf_ocr_detection.py +0 -0
  145. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/parsers/provider_factory.py +0 -0
  146. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/parsers/provider_resolver.py +0 -0
  147. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/parsers/providers/__init__.py +0 -0
  148. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/parsers/providers/basic_provider.py +0 -0
  149. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/parsers/providers/docling_provider.py +0 -0
  150. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/parsers/validator.py +0 -0
  151. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/pdf_service.py +0 -0
  152. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/profile_service.py +0 -0
  153. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/prompt_resource_service.py +0 -0
  154. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/prompt_service.py +0 -0
  155. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/query_service.py +0 -0
  156. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/signup_policy_resolver.py +0 -0
  157. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/sql_dataset_service.py +0 -0
  158. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/sql_service.py +0 -0
  159. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/sql_source_service.py +0 -0
  160. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/storage_service.py +0 -0
  161. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/structured_output_service.py +0 -0
  162. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/system_prompt_catalog.py +0 -0
  163. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/system_tools.py +0 -0
  164. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/telemetry_service.py +0 -0
  165. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/tenant_wiki_service.py +0 -0
  166. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/tool_output_contract.py +0 -0
  167. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/tool_service.py +0 -0
  168. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/user_feedback_service.py +0 -0
  169. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/user_session_context_service.py +0 -0
  170. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/visual_kb_service.py +0 -0
  171. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/visual_tool_service.py +0 -0
  172. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/warmup_service.py +0 -0
  173. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/web_search/__init__.py +0 -0
  174. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/web_search/provider_factory.py +0 -0
  175. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/web_search/providers/__init__.py +0 -0
  176. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/web_search/providers/brave_provider.py +0 -0
  177. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/services/web_search_service.py +0 -0
  178. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/images/fernando.jpeg +0 -0
  179. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/images/iatoolkit_core.png +0 -0
  180. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/images/iatoolkit_logo.png +0 -0
  181. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/js/chat_feedback_button.js +0 -0
  182. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/js/chat_filepond.js +0 -0
  183. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/js/chat_help_content.js +0 -0
  184. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/js/chat_history_button.js +0 -0
  185. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/js/chat_logout_button.js +0 -0
  186. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/js/chat_main.js +0 -0
  187. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/js/chat_memory_button.js +0 -0
  188. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/js/chat_model_selector.js +0 -0
  189. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/js/chat_onboarding_button.js +0 -0
  190. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/js/chat_prompt_manager.js +0 -0
  191. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/js/chat_reload_button.js +0 -0
  192. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/styles/chat_iatoolkit.css +0 -0
  193. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/styles/chat_modal.css +0 -0
  194. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/styles/chat_public.css +0 -0
  195. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/styles/documents.css +0 -0
  196. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/styles/landing_page.css +0 -0
  197. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/styles/llm_output.css +0 -0
  198. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/static/styles/onboarding.css +0 -0
  199. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/_company_header.html +0 -0
  200. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/_login_widget.html +0 -0
  201. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/account.html +0 -0
  202. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/base.html +0 -0
  203. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/change_password.html +0 -0
  204. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/chat.html +0 -0
  205. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/chat_memory_modal.html +0 -0
  206. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/chat_modals.html +0 -0
  207. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/error.html +0 -0
  208. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/forgot_password.html +0 -0
  209. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/home_hosted_default.html +0 -0
  210. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/memory/wiki_schema.md +0 -0
  211. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/onboarding_shell.html +0 -0
  212. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/pdf/base.html +0 -0
  213. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/pdf/letter.html +0 -0
  214. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/pdf/report.html +0 -0
  215. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/pdf/simple.html +0 -0
  216. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/templates/signup.html +0 -0
  217. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/__init__.py +0 -0
  218. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/account_view.py +0 -0
  219. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/api_key_api_view.py +0 -0
  220. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/base_login_view.py +0 -0
  221. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/categories_api_view.py +0 -0
  222. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/change_password_view.py +0 -0
  223. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/chat_context_preview_api_view.py +0 -0
  224. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/chat_view.py +0 -0
  225. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/configuration_api_view.py +0 -0
  226. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/connectors_api_view.py +0 -0
  227. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/embedding_api_view.py +0 -0
  228. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/forgot_password_view.py +0 -0
  229. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/help_content_api_view.py +0 -0
  230. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/history_api_view.py +0 -0
  231. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/home_view.py +0 -0
  232. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/init_context_api_view.py +0 -0
  233. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/llmquery_api_view.py +0 -0
  234. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/load_document_api_view.py +0 -0
  235. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/login_view.py +0 -0
  236. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/logout_api_view.py +0 -0
  237. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/memory_api_view.py +0 -0
  238. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/profile_api_view.py +0 -0
  239. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/prompt_api_view.py +0 -0
  240. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/prompt_context_preview_api_view.py +0 -0
  241. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/prompt_resource_api_view.py +0 -0
  242. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/rag_api_view.py +0 -0
  243. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/root_redirect_view.py +0 -0
  244. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/signup_view.py +0 -0
  245. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/static_page_view.py +0 -0
  246. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/tool_api_view.py +0 -0
  247. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/user_feedback_api_view.py +0 -0
  248. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/users_api_view.py +0 -0
  249. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit/views/verify_user_view.py +0 -0
  250. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
  251. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit.egg-info/requires.txt +0 -0
  252. {iatoolkit-2.44.4 → iatoolkit-2.45.1}/src/iatoolkit.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iatoolkit
3
- Version: 2.44.4
3
+ Version: 2.45.1
4
4
  Summary: IAToolkit
5
5
  Author: Fernando Libedinsky
6
6
  License-Expression: MIT
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # IAToolkit is open source software.
5
5
 
6
- __version__ = "2.44.4"
6
+ __version__ = "2.45.1"
7
7
 
8
8
  # Expose main classes and functions at the top level of the package
9
9
 
@@ -43,6 +43,8 @@ class OpenAICompatibleChatAdapter:
43
43
  #: what DeepseekAdapter does.
44
44
  supports_reasoning_effort = False
45
45
  supports_reasoning_content_messages = False
46
+ supports_reasoning_details_messages = False
47
+ reasoning_content_message_field = "reasoning_content"
46
48
  supports_metadata = False
47
49
  supports_parallel_tool_calls = False
48
50
  supports_thinking = False
@@ -375,10 +377,11 @@ class OpenAICompatibleChatAdapter:
375
377
  message["tool_calls"] = tool_calls
376
378
  seen_tool_call_ids.update(self._extract_tool_call_ids(tool_calls))
377
379
 
378
- if self.supports_reasoning_content_messages:
379
- reasoning_content = str(item.get("reasoning_content") or "").strip()
380
- if reasoning_content:
381
- message["reasoning_content"] = reasoning_content
380
+ self._attach_reasoning_to_message(
381
+ message,
382
+ reasoning_content=item.get("reasoning_content"),
383
+ reasoning_details=item.get("reasoning_details"),
384
+ )
382
385
 
383
386
  tool_call_id = str(item.get("tool_call_id") or "").strip()
384
387
  if role == "tool" and tool_call_id:
@@ -677,7 +680,7 @@ class OpenAICompatibleChatAdapter:
677
680
  total_tokens=getattr(getattr(response, "usage", None), "total_tokens", 0) or 0,
678
681
  )
679
682
 
680
- reasoning_content = getattr(message, "reasoning_content", "") or ""
683
+ reasoning_content, reasoning_details = self._extract_reasoning_from_message(message)
681
684
 
682
685
  tool_calls_out: List[ToolCall] = []
683
686
  content_parts: List[Dict] = []
@@ -701,6 +704,7 @@ class OpenAICompatibleChatAdapter:
701
704
  message=message,
702
705
  normalized_tool_calls=normalized_tool_calls,
703
706
  reasoning_content=reasoning_content,
707
+ reasoning_details=reasoning_details,
704
708
  )
705
709
 
706
710
  for tc in tool_calls:
@@ -738,6 +742,7 @@ class OpenAICompatibleChatAdapter:
738
742
  output=tool_calls_out,
739
743
  usage=usage,
740
744
  reasoning_content=reasoning_content,
745
+ reasoning_details=reasoning_details,
741
746
  content_parts=content_parts,
742
747
  )
743
748
 
@@ -752,6 +757,7 @@ class OpenAICompatibleChatAdapter:
752
757
  message: Any,
753
758
  normalized_tool_calls: List[Dict[str, Any]],
754
759
  reasoning_content: str,
760
+ reasoning_details: Any = None,
755
761
  ) -> None:
756
762
  if not normalized_tool_calls:
757
763
  return
@@ -761,8 +767,11 @@ class OpenAICompatibleChatAdapter:
761
767
  "content": getattr(message, "content", "") or "",
762
768
  "tool_calls": normalized_tool_calls,
763
769
  }
764
- if self.supports_reasoning_content_messages and reasoning_content:
765
- assistant_message["reasoning_content"] = reasoning_content
770
+ self._attach_reasoning_to_message(
771
+ assistant_message,
772
+ reasoning_content=reasoning_content,
773
+ reasoning_details=reasoning_details,
774
+ )
766
775
 
767
776
  group_id = str(getattr(response, "id", "") or normalized_tool_calls[0]["id"]).strip()
768
777
  pending_entry = {
@@ -774,3 +783,51 @@ class OpenAICompatibleChatAdapter:
774
783
  with self._pending_assistant_tool_messages_lock:
775
784
  for tool_call in normalized_tool_calls:
776
785
  self._pending_assistant_tool_messages[tool_call["id"]] = pending_entry
786
+
787
+ def _extract_reasoning_from_message(self, message: Any) -> tuple[str, Any]:
788
+ reasoning_content = self._coerce_optional_text(
789
+ self._get_message_value(message, "reasoning_content")
790
+ )
791
+ reasoning_details = self._get_message_value(message, "reasoning_details")
792
+
793
+ if not reasoning_content:
794
+ reasoning_content = self._coerce_optional_text(
795
+ self._get_message_value(message, "reasoning")
796
+ )
797
+
798
+ return reasoning_content, reasoning_details
799
+
800
+ def _attach_reasoning_to_message(
801
+ self,
802
+ message: Dict[str, Any],
803
+ reasoning_content: Any = None,
804
+ reasoning_details: Any = None,
805
+ ) -> None:
806
+ if self.supports_reasoning_details_messages and reasoning_details:
807
+ message["reasoning_details"] = reasoning_details
808
+ return
809
+
810
+ if not self.supports_reasoning_content_messages:
811
+ return
812
+
813
+ normalized_reasoning = self._coerce_optional_text(reasoning_content)
814
+ if normalized_reasoning:
815
+ message[self.reasoning_content_message_field] = normalized_reasoning
816
+
817
+ @staticmethod
818
+ def _get_message_value(message: Any, key: str) -> Any:
819
+ if isinstance(message, dict):
820
+ return message.get(key)
821
+
822
+ value = getattr(message, key, None)
823
+ if type(value).__module__.startswith("unittest.mock"):
824
+ return None
825
+ return value
826
+
827
+ @staticmethod
828
+ def _coerce_optional_text(value: Any) -> str:
829
+ if value is None:
830
+ return ""
831
+ if type(value).__module__.startswith("unittest.mock"):
832
+ return ""
833
+ return str(value or "").strip()
@@ -13,25 +13,12 @@ class OpenRouterAdapter(OpenAICompatibleChatAdapter):
13
13
 
14
14
  supports_multimodal = True
15
15
  supports_reasoning = False
16
+ supports_reasoning_content_messages = True
17
+ supports_reasoning_details_messages = True
18
+ reasoning_content_message_field = "reasoning"
16
19
  supports_metadata = True
17
20
  supports_parallel_tool_calls = True
18
21
 
19
- # llm_capabilities.yaml marks `application/pdf` as natively supported for
20
- # every OpenRouter model, but that flag isn't verified per-model the way
21
- # native images are (see AttachmentPolicyService._get_openrouter_native_image_error).
22
- # Models with no native PDF support (e.g. some Qwen models) reject the raw
23
- # file part and OpenRouter answers with no `choices`. Always routing PDFs
24
- # through OpenRouter's own `file-parser` plugin sidesteps that per-model gap
25
- # instead of trying to track which routed model does or doesn't accept PDFs.
26
- #
27
- # engine="native": let the routed model read the PDF with its own
28
- # multimodal capability, falling back to OpenRouter's own extraction only
29
- # when the model doesn't support that. engine="mistral-ocr" used to be the
30
- # default here, but it forces every PDF - regardless of model support -
31
- # through OpenRouter's shared OCR pipeline, which is what produced the
32
- # "document parsing engine is currently rate limited" failures.
33
- _PDF_FILE_PARSER_PLUGIN = [{"id": "file-parser", "pdf": {"engine": "native"}}]
34
-
35
22
  def __init__(self, openrouter_client):
36
23
  super().__init__(openai_compatible_client=openrouter_client, provider_label="OpenRouter")
37
24
 
@@ -74,19 +61,5 @@ class OpenRouterAdapter(OpenAICompatibleChatAdapter):
74
61
  if kwargs.get(key) is not None:
75
62
  extra_body[key] = kwargs.get(key)
76
63
 
77
- if "plugins" not in extra_body and self._has_pdf_attachment(kwargs.get("attachments")):
78
- extra_body["plugins"] = self._PDF_FILE_PARSER_PLUGIN
79
-
80
64
  if extra_body:
81
65
  call_kwargs["extra_body"] = extra_body
82
-
83
- @staticmethod
84
- def _has_pdf_attachment(attachments: Any) -> bool:
85
- for attachment in attachments or []:
86
- if not isinstance(attachment, dict):
87
- continue
88
- mime_type = str(attachment.get("mime_type") or attachment.get("type") or "").strip().lower()
89
- filename = str(attachment.get("name") or attachment.get("filename") or "").strip().lower()
90
- if mime_type == "application/pdf" or filename.endswith(".pdf"):
91
- return True
92
- return False
@@ -132,6 +132,11 @@ class LLMProxy:
132
132
  model_config=model_config,
133
133
  request_kwargs=request_kwargs,
134
134
  )
135
+ request_kwargs = self._apply_provider_default_routing(
136
+ provider=provider,
137
+ provider_config=provider_config,
138
+ request_kwargs=request_kwargs,
139
+ )
135
140
  request_kwargs = self._apply_company_request_defaults(
136
141
  company_short_name=company_short_name,
137
142
  model=model,
@@ -330,6 +335,37 @@ class LLMProxy:
330
335
 
331
336
  return effective_kwargs
332
337
 
338
+ def _apply_provider_default_routing(
339
+ self,
340
+ provider: str,
341
+ provider_config: Dict[str, Any],
342
+ request_kwargs: Dict[str, Any],
343
+ ) -> Dict[str, Any]:
344
+ """
345
+ Company-wide OpenRouter routing default, configured once under
346
+ `llm.openrouter.routing` instead of repeated on every model.
347
+ Applied after model-level routing so precedence stays
348
+ caller-explicit > per-model routing > this provider-wide default.
349
+ """
350
+ effective_kwargs = dict(request_kwargs or {})
351
+
352
+ if provider != self.PROVIDER_OPENROUTER or not isinstance(provider_config, dict):
353
+ return effective_kwargs
354
+
355
+ default_routing = provider_config.get("routing")
356
+ if not isinstance(default_routing, dict) or not default_routing:
357
+ return effective_kwargs
358
+
359
+ existing_provider = effective_kwargs.get("provider")
360
+ if isinstance(existing_provider, dict):
361
+ merged_provider = dict(default_routing)
362
+ merged_provider.update(existing_provider)
363
+ effective_kwargs["provider"] = merged_provider
364
+ elif existing_provider is None:
365
+ effective_kwargs["provider"] = dict(default_routing)
366
+
367
+ return effective_kwargs
368
+
333
369
  def _apply_company_request_defaults(
334
370
  self,
335
371
  company_short_name: str,
@@ -33,6 +33,7 @@ class LLMResponse:
33
33
  output: List[ToolCall] # lista de tool calls
34
34
  usage: Usage
35
35
  reasoning_content: str = None # campo opcional para Chain of Thought
36
+ reasoning_details: Any = None # provider-native reasoning blocks, when available
36
37
 
37
38
  # ordered list of content blocks (text and image mixed)
38
39
  # Example: [{"type": "text", "text": "..."}, {"type": "image", "source": {"type": "base64", "data": "..."}}]
@@ -55,4 +56,3 @@ class LLMResponse:
55
56
  "type": "text",
56
57
  "text": self.output_text
57
58
  })
58
-
@@ -27,7 +27,6 @@ class LicenseService:
27
27
  "license_type": "Community Edition",
28
28
  "plan": "Open Source (Community Edition)",
29
29
  "max_companies": 1,
30
- "max_tools": 3,
31
30
  "features": {
32
31
  "multi_tenant": False,
33
32
  "rag_advanced": False,
@@ -46,11 +45,8 @@ class LicenseService:
46
45
  def get_max_companies(self) -> int:
47
46
  return self.limits.get("max_companies", 1)
48
47
 
49
- def get_max_tools_per_company(self) -> int:
50
- return self.limits.get("max_tools", 3)
51
-
52
48
  def get_license_info(self) -> str:
53
- return f"Plan: {self.get_plan_name()}, Companies: {self.get_max_companies()}, Tools: {self.get_max_tools_per_company()}"
49
+ return f"Plan: {self.get_plan_name()}, Companies: {self.get_max_companies()}"
54
50
 
55
51
  # --- Restriction Validators ---
56
52
 
@@ -65,15 +61,6 @@ class LicenseService:
65
61
  )
66
62
 
67
63
 
68
- def validate_tool_config_limit(self, tools_config: list):
69
- """Validates a configuration list before processing it."""
70
- limit = self.get_max_tools_per_company()
71
- if limit != -1 and len(tools_config) > limit:
72
- raise IAToolkitException(
73
- IAToolkitException.ErrorType.PERMISSION,
74
- f"Configuration defines {len(tools_config)} tools, but limit is {limit}."
75
- )
76
-
77
64
  # --- Feature Gating Validators ---
78
65
 
79
66
  def has_feature(self, feature_key: str) -> bool:
@@ -758,7 +758,16 @@ class llmClient:
758
758
  if reasoning_content:
759
759
  assistant_message["reasoning_content"] = reasoning_content
760
760
 
761
- has_assistant_payload = bool(assistant_message.get("content")) or bool(tool_calls) or bool(reasoning_content)
761
+ reasoning_details = getattr(response, "reasoning_details", None)
762
+ if reasoning_details:
763
+ assistant_message["reasoning_details"] = reasoning_details
764
+
765
+ has_assistant_payload = (
766
+ bool(assistant_message.get("content"))
767
+ or bool(tool_calls)
768
+ or bool(reasoning_content)
769
+ or bool(reasoning_details)
770
+ )
762
771
  if not has_assistant_payload:
763
772
  return []
764
773
 
@@ -0,0 +1,104 @@
1
+ # Copyright (c) 2024 Fernando Libedinsky
2
+ # Product: IAToolkit
3
+ #
4
+ # IAToolkit is open source software.
5
+
6
+ import logging
7
+ import os
8
+
9
+ from injector import inject, singleton
10
+
11
+ from iatoolkit.common.exceptions import IAToolkitException
12
+ from iatoolkit.repositories.profile_repo import ProfileRepo
13
+
14
+
15
+ @singleton
16
+ class OperatorIdentityService:
17
+ """Which company operates this deployment.
18
+
19
+ One question that four places used to answer with the same typed string: where
20
+ the operator's own accounts live, which company you must be signed into to
21
+ reach the control center, whose portfolio the console lists, and — the one that
22
+ handles money — whose merchant account collects invoices.
23
+
24
+ Lives in the core because the core, Enterprise and the website all ask it, and
25
+ a rule restated in three repositories drifts. Same reason ``ServiceModel`` is
26
+ here.
27
+ """
28
+
29
+ #: The name this deployment used before the question was a setting. Kept as a
30
+ #: fallback so nothing has to be configured here, but only honoured when the
31
+ #: company actually exists: on any other deployment the name is meaningless,
32
+ #: and silently accepting it is what made a monthly close resolve the payment
33
+ #: configuration of a company that was not there and mark every invoice failed.
34
+ LEGACY_COMPANY_SHORT_NAME = "iat_store"
35
+
36
+ #: In order. The second name predates this service and is honoured by the
37
+ #: Stripe webhook, so a deployment that already set it keeps working without
38
+ #: being asked to set a second variable for the same fact.
39
+ SETTING_NAMES = ("IAT_OPERATOR_COMPANY", "IAT_BILLING_COMPANY_SHORT_NAME")
40
+ SETTING_NAME = SETTING_NAMES[0]
41
+
42
+ @classmethod
43
+ def stated_name(cls) -> str:
44
+ """What this deployment calls its operator, without checking it exists.
45
+
46
+ For callers with no database at hand. The verification belongs on the
47
+ money path — see ``company_short_name`` — and skipping it here is safe
48
+ because those callers fail in the open: a company that does not exist
49
+ cannot authenticate anyone and holds no payment configuration.
50
+ """
51
+ for setting in cls.SETTING_NAMES:
52
+ value = (os.getenv(setting) or "").strip().lower()
53
+ if value:
54
+ return value
55
+ return cls.LEGACY_COMPANY_SHORT_NAME
56
+
57
+ @inject
58
+ def __init__(self, profile_repo: ProfileRepo):
59
+ self.profile_repo = profile_repo
60
+ self._resolved: str | None = None
61
+
62
+ def company_short_name(self) -> str:
63
+ """The operator company, resolved once per process.
64
+
65
+ Cached because the answer cannot change without a deployment, and this is
66
+ read on paths that run per request and per invoice.
67
+ """
68
+ if self._resolved:
69
+ return self._resolved
70
+
71
+ for setting in self.SETTING_NAMES:
72
+ configured = (os.getenv(setting) or "").strip().lower()
73
+ if configured:
74
+ self._resolved = configured
75
+ logging.info("Operator company: '%s' (from %s).", configured, setting)
76
+ return self._resolved
77
+
78
+ if self._company_exists(self.LEGACY_COMPANY_SHORT_NAME):
79
+ self._resolved = self.LEGACY_COMPANY_SHORT_NAME
80
+ logging.info(
81
+ "Operator company: '%s' (default). Set %s to name it explicitly.",
82
+ self._resolved,
83
+ self.SETTING_NAME,
84
+ )
85
+ return self._resolved
86
+
87
+ # Deliberately loud. The alternative is what used to happen: a name from
88
+ # another deployment travels down to the payment configuration and the
89
+ # close writes failed invoices, which reads as a collection problem.
90
+ raise IAToolkitException(
91
+ IAToolkitException.ErrorType.CONFIG_ERROR,
92
+ f"This deployment has no operator company. Set {self.SETTING_NAME} to the "
93
+ f"short name of the company that operates it (there is no "
94
+ f"'{self.LEGACY_COMPANY_SHORT_NAME}' company in this database).",
95
+ )
96
+
97
+ def _company_exists(self, short_name: str) -> bool:
98
+ try:
99
+ return self.profile_repo.get_company_by_short_name(short_name) is not None
100
+ except Exception as exc:
101
+ # Unreadable is not the same as absent, and guessing either way here is
102
+ # worse than saying so: the caller gets the explicit error below.
103
+ logging.warning("Could not check whether company '%s' exists: %s", short_name, exc)
104
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iatoolkit
3
- Version: 2.44.4
3
+ Version: 2.45.1
4
4
  Summary: IAToolkit
5
5
  Author: Fernando Libedinsky
6
6
  License-Expression: MIT
@@ -137,6 +137,7 @@ src/iatoolkit/services/memory_service.py
137
137
  src/iatoolkit/services/memory_wiki_service.py
138
138
  src/iatoolkit/services/noop_memory_compilation_trigger.py
139
139
  src/iatoolkit/services/noop_memory_lint_trigger.py
140
+ src/iatoolkit/services/operator_identity_service.py
140
141
  src/iatoolkit/services/pdf_service.py
141
142
  src/iatoolkit/services/profile_service.py
142
143
  src/iatoolkit/services/prompt_resource_service.py
File without changes
File without changes
File without changes
File without changes
File without changes