iatoolkit 2.54.2__tar.gz → 2.57.0__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 (258) hide show
  1. {iatoolkit-2.54.2/src/iatoolkit.egg-info → iatoolkit-2.57.0}/PKG-INFO +1 -1
  2. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/__init__.py +1 -1
  3. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/interfaces/signup_policy_resolver.py +17 -0
  4. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/routes.py +22 -0
  5. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_tools_pack.yaml +6 -0
  6. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/llm_providers/gemini_adapter.py +23 -12
  7. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/locales/en.yaml +25 -0
  8. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/locales/es.yaml +25 -0
  9. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/llm_query_repo.py +8 -0
  10. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/models.py +10 -0
  11. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/auth_service.py +78 -0
  12. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/configuration_service.py +8 -2
  13. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/history_manager_service.py +2 -1
  14. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/llm_client_service.py +356 -137
  15. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/profile_service.py +131 -10
  16. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/query_service.py +11 -0
  17. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/system_tools.py +5 -2
  18. iatoolkit-2.57.0/src/iatoolkit/static/images/favicon.ico +0 -0
  19. iatoolkit-2.57.0/src/iatoolkit/static/images/favicon.png +0 -0
  20. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/_login_widget.html +4 -0
  21. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/base.html +1 -0
  22. iatoolkit-2.57.0/src/iatoolkit/templates/login_global.html +76 -0
  23. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/signup.html +3 -1
  24. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/home_view.py +7 -0
  25. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/login_view.py +131 -0
  26. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/signup_view.py +48 -13
  27. {iatoolkit-2.54.2 → iatoolkit-2.57.0/src/iatoolkit.egg-info}/PKG-INFO +1 -1
  28. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit.egg-info/SOURCES.txt +3 -0
  29. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/LICENSE +0 -0
  30. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/LICENSE_COMMUNITY.md +0 -0
  31. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/pyproject.toml +0 -0
  32. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/readme.md +0 -0
  33. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/setup.cfg +0 -0
  34. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/base_company.py +0 -0
  35. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/cli_commands.py +0 -0
  36. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/__init__.py +0 -0
  37. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/bridge_validation.py +0 -0
  38. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/exceptions.py +0 -0
  39. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/interfaces/__init__.py +0 -0
  40. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/interfaces/asset_storage.py +0 -0
  41. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/interfaces/database_provider.py +0 -0
  42. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/interfaces/memory_compilation_trigger.py +0 -0
  43. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/interfaces/memory_lint_trigger.py +0 -0
  44. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/interfaces/secret_provider.py +0 -0
  45. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/interfaces/web_search_provider.py +0 -0
  46. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/model_registry.py +0 -0
  47. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/secret_resolver.py +0 -0
  48. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/session_manager.py +0 -0
  49. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/text_splitter.py +0 -0
  50. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/url_safety.py +0 -0
  51. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/common/util.py +0 -0
  52. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/company_registry.py +0 -0
  53. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/__init__.py +0 -0
  54. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/llm_capabilities.yaml +0 -0
  55. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/channel_business_identity.prompt +0 -0
  56. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/channel_conversation_continuity.prompt +0 -0
  57. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/channel_response_style.prompt +0 -0
  58. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/chat_state_rules.prompt +0 -0
  59. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/chat_user_profile.prompt +0 -0
  60. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/core_identity.prompt +0 -0
  61. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/email_output.prompt +0 -0
  62. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/file_download_output.prompt +0 -0
  63. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/format_styles.prompt +0 -0
  64. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/html_structures.prompt +0 -0
  65. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/links_documents.prompt +0 -0
  66. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/memory_usage.prompt +0 -0
  67. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/multimodal_basics.prompt +0 -0
  68. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/output_basics.prompt +0 -0
  69. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/presentation_formatting.prompt +0 -0
  70. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/query_main.prompt +0 -0
  71. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/sql_aggregation_scope.prompt +0 -0
  72. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/sql_casting.prompt +0 -0
  73. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/sql_core.prompt +0 -0
  74. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/sql_jsonb.prompt +0 -0
  75. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/sql_mysql_casting.prompt +0 -0
  76. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/sql_mysql_json.prompt +0 -0
  77. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/sql_redshift_basics.prompt +0 -0
  78. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/sql_redshift_types.prompt +0 -0
  79. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/sql_rules.prompt +0 -0
  80. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts/tool_html_passthrough.prompt +0 -0
  81. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/config/system_prompts_pack.yaml +0 -0
  82. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/core.py +0 -0
  83. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/__init__.py +0 -0
  84. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/brevo_mail_app.py +0 -0
  85. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/call_service.py +0 -0
  86. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/connectors/__init__.py +0 -0
  87. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
  88. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
  89. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
  90. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
  91. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
  92. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
  93. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/google_auth_client.py +0 -0
  94. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/google_chat_app.py +0 -0
  95. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/inference_embeddings_client.py +0 -0
  96. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/inference_handler.py +0 -0
  97. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/jina_embeddings_client.py +0 -0
  98. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/llm_gateway_resolver.py +0 -0
  99. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/llm_providers/__init__.py +0 -0
  100. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/llm_providers/anthropic_adapter.py +0 -0
  101. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/llm_providers/deepseek_adapter.py +0 -0
  102. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/llm_providers/openai_adapter.py +0 -0
  103. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/llm_providers/openai_compatible_chat_adapter.py +0 -0
  104. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/llm_providers/openrouter_adapter.py +0 -0
  105. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/llm_proxy.py +0 -0
  106. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/llm_response.py +0 -0
  107. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/infra/redis_session_manager.py +0 -0
  108. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/__init__.py +0 -0
  109. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/api_key_repo.py +0 -0
  110. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/bridge_repo.py +0 -0
  111. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/database_manager.py +0 -0
  112. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/document_repo.py +0 -0
  113. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/env_secret_provider.py +0 -0
  114. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/filesystem_asset_repository.py +0 -0
  115. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/knowledge_wiki_repo.py +0 -0
  116. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/mcp_token_repo.py +0 -0
  117. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/memory_repo.py +0 -0
  118. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/profile_repo.py +0 -0
  119. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/prompt_resource_repo.py +0 -0
  120. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/sql_dataset_repo.py +0 -0
  121. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/sql_source_repo.py +0 -0
  122. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/repositories/vs_repo.py +0 -0
  123. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/runtime_logging.py +0 -0
  124. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/__init__.py +0 -0
  125. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/api_key_service.py +0 -0
  126. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/attachment_policy_service.py +0 -0
  127. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/branding_service.py +0 -0
  128. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/company_context_service.py +0 -0
  129. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/context_builder_service.py +0 -0
  130. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/dispatcher_service.py +0 -0
  131. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/embedding_service.py +0 -0
  132. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/excel_service.py +0 -0
  133. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/file_processor_service.py +0 -0
  134. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/http_tool_service.py +0 -0
  135. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/i18n_service.py +0 -0
  136. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/inference_service.py +0 -0
  137. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/jwt_service.py +0 -0
  138. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/knowledge_base_service.py +0 -0
  139. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/language_service.py +0 -0
  140. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/license_service.py +0 -0
  141. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/mail_service.py +0 -0
  142. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/markdown_wiki_service.py +0 -0
  143. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/mcp_token_service.py +0 -0
  144. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/memory_compiler_service.py +0 -0
  145. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/memory_lint_service.py +0 -0
  146. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/memory_lookup_policy_service.py +0 -0
  147. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/memory_service.py +0 -0
  148. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/memory_wiki_service.py +0 -0
  149. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/noop_memory_compilation_trigger.py +0 -0
  150. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/noop_memory_lint_trigger.py +0 -0
  151. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/operator_identity_service.py +0 -0
  152. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/parsers/__init__.py +0 -0
  153. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/parsers/contracts.py +0 -0
  154. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/parsers/image_normalizer.py +0 -0
  155. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/parsers/parsing_service.py +0 -0
  156. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/parsers/pdf_ocr_detection.py +0 -0
  157. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/parsers/provider_factory.py +0 -0
  158. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/parsers/provider_resolver.py +0 -0
  159. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/parsers/providers/__init__.py +0 -0
  160. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/parsers/providers/basic_provider.py +0 -0
  161. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/parsers/providers/docling_provider.py +0 -0
  162. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/parsers/validator.py +0 -0
  163. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/pdf_service.py +0 -0
  164. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/prompt_resource_service.py +0 -0
  165. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/prompt_service.py +0 -0
  166. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/signup_policy_resolver.py +0 -0
  167. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/sql_dataset_service.py +0 -0
  168. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/sql_service.py +0 -0
  169. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/sql_source_service.py +0 -0
  170. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/storage_service.py +0 -0
  171. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/structured_output_service.py +0 -0
  172. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/system_prompt_catalog.py +0 -0
  173. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/telemetry_service.py +0 -0
  174. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/tenant_wiki_service.py +0 -0
  175. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/tool_output_contract.py +0 -0
  176. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/tool_service.py +0 -0
  177. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/user_feedback_service.py +0 -0
  178. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/user_session_context_service.py +0 -0
  179. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/visual_kb_service.py +0 -0
  180. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/visual_tool_service.py +0 -0
  181. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/warmup_service.py +0 -0
  182. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/web_search/__init__.py +0 -0
  183. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/web_search/provider_factory.py +0 -0
  184. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/web_search/providers/__init__.py +0 -0
  185. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/web_search/providers/brave_provider.py +0 -0
  186. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/services/web_search_service.py +0 -0
  187. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/images/fernando.jpeg +0 -0
  188. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/images/iatoolkit_core.png +0 -0
  189. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/images/iatoolkit_logo.png +0 -0
  190. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/js/chat_feedback_button.js +0 -0
  191. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/js/chat_filepond.js +0 -0
  192. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/js/chat_header_navigation.js +0 -0
  193. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/js/chat_help_content.js +0 -0
  194. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/js/chat_history_button.js +0 -0
  195. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/js/chat_logout_button.js +0 -0
  196. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/js/chat_main.js +0 -0
  197. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/js/chat_memory_button.js +0 -0
  198. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/js/chat_model_selector.js +0 -0
  199. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/js/chat_onboarding_button.js +0 -0
  200. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/js/chat_prompt_manager.js +0 -0
  201. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/js/chat_reload_button.js +0 -0
  202. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/styles/account.css +0 -0
  203. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/styles/chat_iatoolkit.css +0 -0
  204. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/styles/chat_modal.css +0 -0
  205. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/styles/chat_public.css +0 -0
  206. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/styles/documents.css +0 -0
  207. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/styles/landing_page.css +0 -0
  208. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/styles/llm_output.css +0 -0
  209. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/static/styles/onboarding.css +0 -0
  210. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/_chat_header.html +0 -0
  211. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/_company_header.html +0 -0
  212. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/account.html +0 -0
  213. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/change_password.html +0 -0
  214. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/chat.html +0 -0
  215. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/chat_memory_modal.html +0 -0
  216. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/chat_modals.html +0 -0
  217. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/error.html +0 -0
  218. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/forgot_password.html +0 -0
  219. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/home_hosted_default.html +0 -0
  220. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/memory/wiki_schema.md +0 -0
  221. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/onboarding_shell.html +0 -0
  222. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/pdf/base.html +0 -0
  223. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/pdf/letter.html +0 -0
  224. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/pdf/report.html +0 -0
  225. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/templates/pdf/simple.html +0 -0
  226. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/__init__.py +0 -0
  227. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/account_view.py +0 -0
  228. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/api_key_api_view.py +0 -0
  229. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/base_login_view.py +0 -0
  230. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/categories_api_view.py +0 -0
  231. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/change_password_view.py +0 -0
  232. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/chat_context_preview_api_view.py +0 -0
  233. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/chat_view.py +0 -0
  234. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/configuration_api_view.py +0 -0
  235. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/connectors_api_view.py +0 -0
  236. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/embedding_api_view.py +0 -0
  237. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/forgot_password_view.py +0 -0
  238. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/help_content_api_view.py +0 -0
  239. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/history_api_view.py +0 -0
  240. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/init_context_api_view.py +0 -0
  241. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/llmquery_api_view.py +0 -0
  242. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/load_document_api_view.py +0 -0
  243. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/logout_api_view.py +0 -0
  244. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/memory_api_view.py +0 -0
  245. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/profile_api_view.py +0 -0
  246. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/prompt_api_view.py +0 -0
  247. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/prompt_context_preview_api_view.py +0 -0
  248. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/prompt_resource_api_view.py +0 -0
  249. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/rag_api_view.py +0 -0
  250. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/root_redirect_view.py +0 -0
  251. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/static_page_view.py +0 -0
  252. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/tool_api_view.py +0 -0
  253. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/user_feedback_api_view.py +0 -0
  254. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/users_api_view.py +0 -0
  255. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit/views/verify_user_view.py +0 -0
  256. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
  257. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/src/iatoolkit.egg-info/requires.txt +0 -0
  258. {iatoolkit-2.54.2 → iatoolkit-2.57.0}/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.54.2
3
+ Version: 2.57.0
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.54.2"
6
+ __version__ = "2.57.0"
7
7
 
8
8
  # Expose main classes and functions at the top level of the package
9
9
 
@@ -31,3 +31,20 @@ class SignupPolicyResolver(ABC):
31
31
  invite_token: str | None = None,
32
32
  ) -> SignupPolicyDecision:
33
33
  """Evaluates whether the email can sign up for the target company."""
34
+
35
+ def requires_invitation(self, company_short_name: str) -> bool:
36
+ return False
37
+
38
+ def invitation_email(self, company_short_name: str, invite_token: str | None) -> str | None:
39
+ return None
40
+
41
+ def claim_signup(
42
+ self,
43
+ company_short_name: str,
44
+ email: str,
45
+ invite_token: str | None = None,
46
+ *,
47
+ verified_email: bool = False,
48
+ ) -> bool:
49
+ """Claim an invitation in the same transaction that creates membership."""
50
+ return True
@@ -5,6 +5,7 @@
5
5
 
6
6
  from io import BytesIO
7
7
  import mimetypes
8
+ import os
8
9
  from flask import render_template, redirect, url_for, current_app, abort, send_file
9
10
  from flask import jsonify
10
11
  from iatoolkit.common.exceptions import IAToolkitException
@@ -33,6 +34,8 @@ def register_views(app):
33
34
  LoginView,
34
35
  GoogleLoginStartView,
35
36
  GoogleLoginCallbackView,
37
+ GlobalLoginView,
38
+ GlobalGoogleLoginStartView,
36
39
  FinalizeContextView,
37
40
  )
38
41
  from iatoolkit.views.configuration_api_view import ConfigurationApiView, ValidateConfigurationApiView
@@ -57,6 +60,18 @@ def register_views(app):
57
60
  # must stay reachable even if the company registry or DB is degraded.
58
61
  app.add_url_rule('/', endpoint='liveness', view_func=lambda: ("ok", 200))
59
62
 
63
+ # Browsers and MCP clients (Claude shows it as the connector icon) ask the
64
+ # host for /favicon.ico regardless of the page.
65
+ app.add_url_rule(
66
+ '/favicon.ico',
67
+ endpoint='favicon',
68
+ view_func=lambda: send_file(
69
+ os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'static', 'images', 'favicon.ico'),
70
+ mimetype='image/vnd.microsoft.icon',
71
+ max_age=86400,
72
+ ),
73
+ )
74
+
60
75
  # assign root '/' to our new redirect logic
61
76
  app.add_url_rule('/home', view_func=RootRedirectView.as_view('root_redirect'))
62
77
 
@@ -74,6 +89,13 @@ def register_views(app):
74
89
  view_func=GoogleLoginCallbackView.as_view('login_google_callback')
75
90
  )
76
91
 
92
+ # company-less login: identifies the person, the caller picks the company
93
+ app.add_url_rule('/auth/login', view_func=GlobalLoginView.as_view('global_login'))
94
+ app.add_url_rule(
95
+ '/auth/login/google',
96
+ view_func=GlobalGoogleLoginStartView.as_view('global_login_google_start')
97
+ )
98
+
77
99
  # Chat Route (Direct Access)
78
100
  app.add_url_rule('/<company_short_name>/chat',
79
101
  view_func=ChatView.as_view('chat'))
@@ -129,8 +129,11 @@ tools:
129
129
  - function_name: iat_send_email
130
130
  description: iatoolkit mail system. envia mails cuando un usuario lo solicita.
131
131
  # Sends a real email: simulated, never sent, when an evaluation replays an agent.
132
+ # Not destructive (it changes nothing that existed) and not open-world for MCP
133
+ # annotations: it goes through the tenant's own mail service.
132
134
  execution_config:
133
135
  side_effects: true
136
+ destructive: false
134
137
  routing_profile:
135
138
  tags:
136
139
  - email
@@ -559,6 +562,9 @@ tools:
559
562
  - metadata_filter
560
563
  - function_name: iat_web_search
561
564
  description: Realiza una búsqueda web externa para obtener información pública actualizada.
565
+ # Reaches the public internet: openWorldHint in MCP annotations.
566
+ execution_config:
567
+ open_world: true
562
568
  routing_profile:
563
569
  tags:
564
570
  - web
@@ -700,23 +700,34 @@ class GeminiAdapter:
700
700
  return {}
701
701
 
702
702
  def _extract_usage_metadata(self, gemini_response) -> Usage:
703
- """Extraer información de uso de tokens de manera segura"""
703
+ """Extraer información de uso de tokens de manera segura.
704
+
705
+ Gemini reports the tokens it bills in four counters. `candidates_token_count`
706
+ excludes the model's reasoning (`thoughts_token_count`), which Google bills as
707
+ output, and `prompt_token_count` excludes the results of its built-in tools
708
+ (`tool_use_prompt_token_count`), billed as input. Reading only the first two
709
+ priced every thinking model's reasoning at zero.
710
+ """
704
711
  input_tokens = 0
705
712
  output_tokens = 0
706
713
  total_tokens = 0
707
714
 
715
+ def _count(metadata, name: str) -> int:
716
+ value = getattr(metadata, name, None)
717
+ return value if isinstance(value, int) and value > 0 else 0
718
+
708
719
  try:
709
- # Verificar si existe usage_metadata
710
- if hasattr(gemini_response, 'usage_metadata') and gemini_response.usage_metadata:
711
- usage_metadata = gemini_response.usage_metadata
712
-
713
- # Acceder a los atributos directamente, no con .get()
714
- if hasattr(usage_metadata, 'prompt_token_count'):
715
- input_tokens = usage_metadata.prompt_token_count
716
- if hasattr(usage_metadata, 'candidates_token_count'):
717
- output_tokens = usage_metadata.candidates_token_count
718
- if hasattr(usage_metadata, 'total_token_count'):
719
- total_tokens = usage_metadata.total_token_count
720
+ usage_metadata = getattr(gemini_response, 'usage_metadata', None)
721
+ if usage_metadata:
722
+ input_tokens = (
723
+ _count(usage_metadata, 'prompt_token_count')
724
+ + _count(usage_metadata, 'tool_use_prompt_token_count')
725
+ )
726
+ output_tokens = (
727
+ _count(usage_metadata, 'candidates_token_count')
728
+ + _count(usage_metadata, 'thoughts_token_count')
729
+ )
730
+ total_tokens = _count(usage_metadata, 'total_token_count')
720
731
 
721
732
  except Exception as e:
722
733
  logging.warning(f"No se pudo extraer usage_metadata de Gemini: {e}")
@@ -274,6 +274,10 @@ ui:
274
274
  pending_review: "Pending review"
275
275
  revoked: "Revoked"
276
276
 
277
+ global_login:
278
+ title: "Sign in to IAToolkit"
279
+ intro: "Sign in with the account you use in IAToolkit. You will choose the company next."
280
+
277
281
  login_widget:
278
282
  title: "Sign In"
279
283
  welcome_message: "Enter your credentials or register to access this platform."
@@ -287,6 +291,7 @@ ui:
287
291
  forgot_password_link: "Forgot your password?"
288
292
  no_account_prompt: "Don't have an account?"
289
293
  signup_link: "Sign Up"
294
+ invitation_prompt: "Need access? Ask your administrator for an invitation."
290
295
 
291
296
  signup:
292
297
  title: "Create an Account"
@@ -607,6 +612,25 @@ ui:
607
612
  status_closed: "Closed"
608
613
  admin:
609
614
  workspace: "Workspace"
615
+ team_invitations: "Invitations"
616
+ team_invite_user: "Invite user"
617
+ team_invite_none: "No invitations yet."
618
+ team_invite_loading: "Loading invitations..."
619
+ team_invite_email: "Email"
620
+ team_invite_pending: "Pending"
621
+ team_invite_accepted: "Accepted"
622
+ team_invite_expired: "Expired"
623
+ team_invite_revoked_status: "Revoked"
624
+ team_invite_status: "Status"
625
+ team_invite_invited_by: "Invited by"
626
+ team_invite_expires: "Expires"
627
+ team_invite_revoke: "Revoke"
628
+ team_invite_revoked: "Invitation revoked."
629
+ team_invite_load_error: "Could not load invitations."
630
+ team_invite_revoke_error: "Could not revoke invitation."
631
+ team_policy_note: "Choose domain access or require an invitation for each new member."
632
+ team_policy_static_note: "Signup policies are enforced when the company runs in hosted mode."
633
+ team_policy_invite_only: "Invitation only"
610
634
  configuration: "Configuration"
611
635
  error: "Error"
612
636
  company_config: "Company Configuration (company.yaml)"
@@ -2582,6 +2606,7 @@ errors:
2582
2606
  user_already_registered: "The user with email '{email}' already exists in this company."
2583
2607
  password_mismatch: "The passwords do not match. Please try again."
2584
2608
  signup_not_allowed: "Signup is not allowed for this company. Please contact an administrator."
2609
+ invitation_required: "A valid invitation is required to join this company. Ask your administrator for a new link."
2585
2610
  change_password:
2586
2611
  token_expired: "The password change link has expired. Please request a new one."
2587
2612
  password_mismatch: "The passwords do not match. Please try again."
@@ -288,6 +288,10 @@ ui:
288
288
  revoked: "Revocado"
289
289
 
290
290
 
291
+ global_login:
292
+ title: "Iniciar sesión en IAToolkit"
293
+ intro: "Ingresa con la cuenta que usas en IAToolkit. Después podrás elegir la empresa."
294
+
291
295
  login_widget:
292
296
  title: "Iniciar Sesión"
293
297
  welcome_message: "Ingresa tus credenciales o registrate para acceder a la plataforma."
@@ -301,6 +305,7 @@ ui:
301
305
  forgot_password_link: "¿Olvidaste tu contraseña?"
302
306
  no_account_prompt: "¿No tienes una cuenta?"
303
307
  signup_link: "Regístrate"
308
+ invitation_prompt: "¿Necesitas acceso? Solicita una invitación al administrador."
304
309
 
305
310
  signup:
306
311
  title: "Crear una Cuenta"
@@ -621,6 +626,25 @@ ui:
621
626
  status_closed: "Cerrada"
622
627
  admin:
623
628
  workspace: "Recursos"
629
+ team_invitations: "Invitaciones"
630
+ team_invite_user: "Invitar usuario"
631
+ team_invite_none: "Todavía no hay invitaciones."
632
+ team_invite_loading: "Cargando invitaciones..."
633
+ team_invite_email: "Correo"
634
+ team_invite_pending: "Pendiente"
635
+ team_invite_accepted: "Aceptada"
636
+ team_invite_expired: "Vencida"
637
+ team_invite_revoked_status: "Revocada"
638
+ team_invite_status: "Estado"
639
+ team_invite_invited_by: "Invitado por"
640
+ team_invite_expires: "Vence"
641
+ team_invite_revoke: "Revocar"
642
+ team_invite_revoked: "Invitación revocada."
643
+ team_invite_load_error: "No se pudieron cargar las invitaciones."
644
+ team_invite_revoke_error: "No se pudo revocar la invitación."
645
+ team_policy_note: "Permite el acceso por dominio o exige una invitación para cada nuevo miembro."
646
+ team_policy_static_note: "Las políticas de registro se aplican cuando la empresa funciona en modo alojado."
647
+ team_policy_invite_only: "Solo con invitación"
624
648
  configuration: "Configuración"
625
649
  error: "Error"
626
650
  company_config: "Configuración Empresa (company.yaml)"
@@ -2601,6 +2625,7 @@ errors:
2601
2625
  user_already_registered: "El usuario con email '{email}' ya existe en esta empresa."
2602
2626
  password_mismatch: "Las contraseñas no coinciden. Por favor, inténtalo de nuevo."
2603
2627
  signup_not_allowed: "El registro no está habilitado para esta empresa. Contacta a un administrador."
2628
+ invitation_required: "Necesitas una invitación vigente para unirte a esta empresa. Solicita un nuevo enlace al administrador."
2604
2629
  change_password:
2605
2630
  token_expired: "El enlace de cambio de contraseña ha expirado. Por favor, solicita uno nuevo."
2606
2631
  password_mismatch: "Las contraseñas no coinciden. Por favor, inténtalo nuevamente."
@@ -14,6 +14,7 @@ from iatoolkit.repositories.models import (
14
14
  from injector import inject
15
15
  from iatoolkit.repositories.database_manager import DatabaseManager
16
16
  from sqlalchemy import or_, and_
17
+ from iatoolkit.repositories.models import CONTEXT_INIT_REQUEST_SOURCE
17
18
  from typing import List
18
19
 
19
20
 
@@ -34,10 +35,17 @@ class LLMQueryRepo:
34
35
  self.session.commit()
35
36
  return query
36
37
 
38
+ @staticmethod
39
+ def not_context_init():
40
+ """Filter for rows that are a conversation turn, not a context initialization."""
41
+ request_source = LLMQuery.stats["request_source"].as_string()
42
+ return or_(request_source.is_(None), request_source != CONTEXT_INIT_REQUEST_SOURCE)
43
+
37
44
  # get user query history
38
45
  def get_history(self, company: Company, user_identifier: str, limit: int = 100) -> list[LLMQuery]:
39
46
  return self.session.query(LLMQuery).filter(
40
47
  LLMQuery.user_identifier == user_identifier,
48
+ self.not_context_init(),
41
49
  ).filter_by(company_id=company.id).order_by(LLMQuery.created_at.desc()).limit(limit).all()
42
50
 
43
51
 
@@ -593,6 +593,12 @@ class MemoryPageSource(Base):
593
593
  return {column.key: getattr(self, column.key) for column in class_mapper(self.__class__).columns}
594
594
 
595
595
 
596
+ #: request_source of the iat_queries row that records a context initialization:
597
+ #: the company context sent once to start a server-side conversation. Its tokens
598
+ #: are billed, but it is not a question, so conversation readers skip it.
599
+ CONTEXT_INIT_REQUEST_SOURCE = "context_init"
600
+
601
+
596
602
  class LLMQuery(Base):
597
603
  """Logs a query made to the LLM, including input, output, and metadata."""
598
604
  __tablename__ = 'iat_queries'
@@ -622,6 +628,10 @@ class LLMQuery(Base):
622
628
 
623
629
  __table_args__ = (
624
630
  Index('ix_iat_queries_company_prompt_created', 'company_id', 'prompt_name', 'created_at'),
631
+ # Executions that did not run as a task (synchronous agent calls). They are a
632
+ # tiny fraction of the table, which the Agents monitor would otherwise scan whole.
633
+ Index('ix_iat_queries_company_created_untasked', company_id, created_at.desc(),
634
+ postgresql_where=task_id.is_(None)),
625
635
  )
626
636
 
627
637
  company = relationship("Company", back_populates="llm_queries")
@@ -22,6 +22,8 @@ class AuthService:
22
22
  Centralized service for handling authentication for all incoming requests.
23
23
  It determines the user's identity based on either a Flask session cookie or an API Key.
24
24
  """
25
+ # access-log scope for logins that are not tied to a company
26
+ GLOBAL_ACCESS_SCOPE = '*'
25
27
 
26
28
  @inject
27
29
  def __init__(self, profile_service: ProfileService,
@@ -186,6 +188,82 @@ class AuthService:
186
188
 
187
189
  return auth_response
188
190
 
191
+ def login_global_local_user(self, email: str, password: str) -> dict:
192
+ # company-less login: authenticates the person, the company is chosen later
193
+ auth_response = self.profile_service.authenticate_local_credentials(email=email, password=password)
194
+ if not auth_response.get('success'):
195
+ self.log_access(
196
+ company_short_name=self.GLOBAL_ACCESS_SCOPE,
197
+ user_identifier=email,
198
+ auth_type='local',
199
+ outcome='failure',
200
+ reason_code='INVALID_CREDENTIALS',
201
+ )
202
+ return auth_response
203
+
204
+ self.profile_service.set_global_identity(auth_response['user_identifier'], 'local')
205
+ self.log_access(
206
+ company_short_name=self.GLOBAL_ACCESS_SCOPE,
207
+ auth_type='local',
208
+ outcome='success',
209
+ user_identifier=auth_response['user_identifier'],
210
+ )
211
+ return auth_response
212
+
213
+ def login_global_google_user(self, code: str, state: str, nonce: str, redirect_uri: str) -> dict:
214
+ try:
215
+ google_identity = self.google_auth_client.exchange_code_for_identity(
216
+ code=code,
217
+ state=state,
218
+ nonce=nonce,
219
+ redirect_uri=redirect_uri,
220
+ )
221
+ except GoogleAuthError as exc:
222
+ self.log_access(
223
+ company_short_name=self.GLOBAL_ACCESS_SCOPE,
224
+ auth_type='google',
225
+ outcome='failure',
226
+ reason_code=exc.reason_code,
227
+ )
228
+ return {
229
+ 'success': False,
230
+ 'reason_code': exc.reason_code,
231
+ 'message': self.i18n_service.t(exc.message_key),
232
+ }
233
+ except Exception:
234
+ logging.exception("Unexpected Google auth client failure in company-less login.")
235
+ self.log_access(
236
+ company_short_name=self.GLOBAL_ACCESS_SCOPE,
237
+ auth_type='google',
238
+ outcome='failure',
239
+ reason_code='GOOGLE_AUTH_UNEXPECTED_ERROR',
240
+ )
241
+ return {
242
+ 'success': False,
243
+ 'reason_code': 'GOOGLE_AUTH_UNEXPECTED_ERROR',
244
+ 'message': self.i18n_service.t('errors.auth.google_login_failed'),
245
+ }
246
+
247
+ auth_response = self.profile_service.identify_google_user(google_identity)
248
+ if not auth_response.get('success'):
249
+ self.log_access(
250
+ company_short_name=self.GLOBAL_ACCESS_SCOPE,
251
+ auth_type='google',
252
+ outcome='failure',
253
+ reason_code=auth_response.get('reason_code', 'GOOGLE_LOGIN_FAILED'),
254
+ user_identifier=google_identity.email,
255
+ )
256
+ return auth_response
257
+
258
+ self.profile_service.set_global_identity(auth_response['user_identifier'], 'google')
259
+ self.log_access(
260
+ company_short_name=self.GLOBAL_ACCESS_SCOPE,
261
+ auth_type='google',
262
+ outcome='success',
263
+ user_identifier=auth_response['user_identifier'],
264
+ )
265
+ return auth_response
266
+
189
267
  def verify(self, anonymous: bool = False, company_short_name: str = None) -> dict:
190
268
  """
191
269
  Verifies the current request and identifies the user.
@@ -794,8 +794,14 @@ class ConfigurationService:
794
794
  if execution_config is not None:
795
795
  if not isinstance(execution_config, dict):
796
796
  add_error(f"tools[{i}].execution_config", "Must be a dictionary.")
797
- elif "side_effects" in execution_config and not isinstance(execution_config["side_effects"], bool):
798
- add_error(f"tools[{i}].execution_config.side_effects", "Must be true or false.")
797
+ else:
798
+ # side_effects drives evaluations; destructive / open_world / title
799
+ # feed the MCP tool annotations.
800
+ for flag in ("side_effects", "destructive", "open_world"):
801
+ if flag in execution_config and not isinstance(execution_config[flag], bool):
802
+ add_error(f"tools[{i}].execution_config.{flag}", "Must be true or false.")
803
+ if "title" in execution_config and not isinstance(execution_config["title"], str):
804
+ add_error(f"tools[{i}].execution_config.title", "Must be a string.")
799
805
 
800
806
  # 6. Prompts
801
807
  prompt_list, categories_config = self._get_prompt_config(config)
@@ -60,7 +60,8 @@ class HistoryManagerService:
60
60
  response_id = self.llm_client.set_company_context(
61
61
  company=company,
62
62
  company_base_context=prepared_context,
63
- model=model
63
+ model=model,
64
+ user_identifier=user_identifier,
64
65
  )
65
66
  self.session_context.save_last_response_id(company_short_name, user_identifier, response_id, model=model)
66
67
  self.session_context.save_initial_response_id(company_short_name, user_identifier, response_id, model=model)