iatoolkit 2.5.0__tar.gz → 2.6.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 (236) hide show
  1. {iatoolkit-2.5.0/src/iatoolkit.egg-info → iatoolkit-2.6.1}/PKG-INFO +1 -1
  2. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/__init__.py +1 -1
  3. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/model_registry.py +41 -2
  4. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/routes.py +2 -2
  5. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/html_structures.prompt +1 -1
  6. iatoolkit-2.6.1/src/iatoolkit/config/system_prompts/sql_casting.prompt +23 -0
  7. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/core.py +12 -1
  8. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/llm_providers/anthropic_adapter.py +10 -1
  9. iatoolkit-2.6.1/src/iatoolkit/infra/llm_providers/deepseek_adapter.py +75 -0
  10. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/llm_providers/gemini_adapter.py +84 -6
  11. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/llm_providers/openai_adapter.py +11 -7
  12. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/llm_providers/openai_compatible_chat_adapter.py +244 -18
  13. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/llm_providers/openrouter_adapter.py +3 -3
  14. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/llm_proxy.py +127 -31
  15. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/redis_session_manager.py +30 -4
  16. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/locales/en.yaml +17 -3
  17. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/locales/es.yaml +17 -3
  18. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/repositories/llm_query_repo.py +4 -0
  19. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/attachment_policy_service.py +25 -2
  20. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/configuration_service.py +55 -4
  21. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/context_builder_service.py +30 -4
  22. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/history_manager_service.py +5 -2
  23. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/knowledge_base_service.py +67 -41
  24. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/llm_client_service.py +78 -1
  25. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/prompt_service.py +7 -0
  26. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/query_service.py +54 -12
  27. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/telemetry_service.py +66 -0
  28. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/user_session_context_service.py +6 -1
  29. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/js/chat_main.js +2 -1
  30. iatoolkit-2.6.1/src/iatoolkit/static/js/chat_model_selector.js +500 -0
  31. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/chat.html +17 -3
  32. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/base_login_view.py +5 -0
  33. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/categories_api_view.py +4 -2
  34. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/chat_view.py +5 -0
  35. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/home_view.py +4 -1
  36. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/llmquery_api_view.py +3 -0
  37. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/login_view.py +5 -0
  38. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/rag_api_view.py +59 -16
  39. {iatoolkit-2.5.0 → iatoolkit-2.6.1/src/iatoolkit.egg-info}/PKG-INFO +1 -1
  40. iatoolkit-2.5.0/src/iatoolkit/config/system_prompts/sql_casting.prompt +0 -14
  41. iatoolkit-2.5.0/src/iatoolkit/infra/llm_providers/deepseek_adapter.py +0 -13
  42. iatoolkit-2.5.0/src/iatoolkit/static/js/chat_model_selector.js +0 -240
  43. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/LICENSE +0 -0
  44. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/LICENSE_COMMUNITY.md +0 -0
  45. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/pyproject.toml +0 -0
  46. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/readme.md +0 -0
  47. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/requirements.txt +0 -0
  48. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/setup.cfg +0 -0
  49. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/base_company.py +0 -0
  50. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/cli_commands.py +0 -0
  51. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/__init__.py +0 -0
  52. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/exceptions.py +0 -0
  53. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/interfaces/__init__.py +0 -0
  54. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/interfaces/asset_storage.py +0 -0
  55. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/interfaces/database_provider.py +0 -0
  56. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/interfaces/memory_compilation_trigger.py +0 -0
  57. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/interfaces/memory_lint_trigger.py +0 -0
  58. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/interfaces/secret_provider.py +0 -0
  59. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/interfaces/signup_policy_resolver.py +0 -0
  60. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/interfaces/web_search_provider.py +0 -0
  61. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/secret_resolver.py +0 -0
  62. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/session_manager.py +0 -0
  63. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/common/util.py +0 -0
  64. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/company_registry.py +0 -0
  65. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/__init__.py +0 -0
  66. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/llm_capabilities.yaml +0 -0
  67. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/chat_state_rules.prompt +0 -0
  68. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/chat_user_profile.prompt +0 -0
  69. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/core_identity.prompt +0 -0
  70. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/email_output.prompt +0 -0
  71. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/file_download_output.prompt +0 -0
  72. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/format_styles.prompt +0 -0
  73. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/links_documents.prompt +0 -0
  74. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/memory_usage.prompt +0 -0
  75. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/multimodal_basics.prompt +0 -0
  76. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/output_basics.prompt +0 -0
  77. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/presentation_formatting.prompt +0 -0
  78. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/query_main.prompt +0 -0
  79. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/sql_aggregation_scope.prompt +0 -0
  80. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/sql_core.prompt +0 -0
  81. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/sql_jsonb.prompt +0 -0
  82. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/sql_rules.prompt +0 -0
  83. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts/tool_html_passthrough.prompt +0 -0
  84. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_prompts_pack.yaml +0 -0
  85. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/config/system_tools_pack.yaml +0 -0
  86. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/__init__.py +0 -0
  87. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/brevo_mail_app.py +0 -0
  88. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/call_service.py +0 -0
  89. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/connectors/__init__.py +0 -0
  90. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
  91. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
  92. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
  93. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
  94. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
  95. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
  96. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/google_auth_client.py +0 -0
  97. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/google_chat_app.py +0 -0
  98. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/inference_embeddings_client.py +0 -0
  99. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/inference_handler.py +0 -0
  100. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/jina_embeddings_client.py +0 -0
  101. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/llm_providers/__init__.py +0 -0
  102. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/infra/llm_response.py +0 -0
  103. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/repositories/__init__.py +0 -0
  104. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/repositories/api_key_repo.py +0 -0
  105. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/repositories/database_manager.py +0 -0
  106. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/repositories/document_repo.py +0 -0
  107. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/repositories/env_secret_provider.py +0 -0
  108. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/repositories/filesystem_asset_repository.py +0 -0
  109. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/repositories/memory_repo.py +0 -0
  110. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/repositories/models.py +0 -0
  111. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/repositories/profile_repo.py +0 -0
  112. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/repositories/prompt_resource_repo.py +0 -0
  113. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/repositories/sql_dataset_repo.py +0 -0
  114. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/repositories/sql_source_repo.py +0 -0
  115. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/repositories/vs_repo.py +0 -0
  116. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/__init__.py +0 -0
  117. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/api_key_service.py +0 -0
  118. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/auth_service.py +0 -0
  119. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/benchmark_service.py +0 -0
  120. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/branding_service.py +0 -0
  121. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/company_context_service.py +0 -0
  122. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/dispatcher_service.py +0 -0
  123. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/embedding_service.py +0 -0
  124. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/excel_service.py +0 -0
  125. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/file_processor_service.py +0 -0
  126. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/http_tool_service.py +0 -0
  127. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/i18n_service.py +0 -0
  128. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/inference_service.py +0 -0
  129. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/jwt_service.py +0 -0
  130. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/language_service.py +0 -0
  131. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/license_service.py +0 -0
  132. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/mail_service.py +0 -0
  133. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/memory_compiler_service.py +0 -0
  134. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/memory_lint_service.py +0 -0
  135. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/memory_lookup_policy_service.py +0 -0
  136. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/memory_service.py +0 -0
  137. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/memory_wiki_service.py +0 -0
  138. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/noop_memory_compilation_trigger.py +0 -0
  139. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/noop_memory_lint_trigger.py +0 -0
  140. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/parsers/__init__.py +0 -0
  141. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/parsers/contracts.py +0 -0
  142. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/parsers/image_normalizer.py +0 -0
  143. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/parsers/parsing_service.py +0 -0
  144. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/parsers/pdf_ocr_detection.py +0 -0
  145. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/parsers/provider_factory.py +0 -0
  146. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/parsers/provider_resolver.py +0 -0
  147. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/parsers/providers/__init__.py +0 -0
  148. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/parsers/providers/basic_provider.py +0 -0
  149. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/parsers/providers/docling_provider.py +0 -0
  150. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/parsers/validator.py +0 -0
  151. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/pdf_service.py +0 -0
  152. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/profile_service.py +0 -0
  153. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/prompt_resource_service.py +0 -0
  154. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/signup_policy_resolver.py +0 -0
  155. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/sql_dataset_service.py +0 -0
  156. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/sql_service.py +0 -0
  157. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/sql_source_service.py +0 -0
  158. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/storage_service.py +0 -0
  159. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/structured_output_service.py +0 -0
  160. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/system_prompt_catalog.py +0 -0
  161. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/system_tools.py +0 -0
  162. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/tool_service.py +0 -0
  163. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/user_feedback_service.py +0 -0
  164. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/visual_kb_service.py +0 -0
  165. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/visual_tool_service.py +0 -0
  166. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/warmup_service.py +0 -0
  167. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/web_search/__init__.py +0 -0
  168. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/web_search/provider_factory.py +0 -0
  169. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/web_search/providers/__init__.py +0 -0
  170. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/web_search/providers/brave_provider.py +0 -0
  171. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/services/web_search_service.py +0 -0
  172. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/images/fernando.jpeg +0 -0
  173. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/images/iatoolkit_core.png +0 -0
  174. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/images/iatoolkit_logo.png +0 -0
  175. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/js/chat_feedback_button.js +0 -0
  176. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/js/chat_filepond.js +0 -0
  177. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/js/chat_help_content.js +0 -0
  178. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/js/chat_history_button.js +0 -0
  179. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/js/chat_logout_button.js +0 -0
  180. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/js/chat_memory_button.js +0 -0
  181. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/js/chat_onboarding_button.js +0 -0
  182. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/js/chat_prompt_manager.js +0 -0
  183. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/js/chat_reload_button.js +0 -0
  184. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/styles/chat_iatoolkit.css +0 -0
  185. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/styles/chat_modal.css +0 -0
  186. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/styles/chat_public.css +0 -0
  187. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/styles/documents.css +0 -0
  188. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/styles/landing_page.css +0 -0
  189. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/styles/llm_output.css +0 -0
  190. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/static/styles/onboarding.css +0 -0
  191. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/system_prompts/__init__.py +0 -0
  192. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/_company_header.html +0 -0
  193. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/_login_widget.html +0 -0
  194. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/base.html +0 -0
  195. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/change_password.html +0 -0
  196. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/chat_memory_modal.html +0 -0
  197. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/chat_modals.html +0 -0
  198. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/error.html +0 -0
  199. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/forgot_password.html +0 -0
  200. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/home_hosted_default.html +0 -0
  201. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/memory/wiki_schema.md +0 -0
  202. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/onboarding_shell.html +0 -0
  203. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/pdf/base.html +0 -0
  204. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/pdf/letter.html +0 -0
  205. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/pdf/report.html +0 -0
  206. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/pdf/simple.html +0 -0
  207. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/templates/signup.html +0 -0
  208. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/__init__.py +0 -0
  209. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/api_key_api_view.py +0 -0
  210. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/change_password_view.py +0 -0
  211. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/chat_context_preview_api_view.py +0 -0
  212. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/configuration_api_view.py +0 -0
  213. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/connectors_api_view.py +0 -0
  214. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/embedding_api_view.py +0 -0
  215. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/forgot_password_view.py +0 -0
  216. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/help_content_api_view.py +0 -0
  217. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/history_api_view.py +0 -0
  218. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/init_context_api_view.py +0 -0
  219. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/load_document_api_view.py +0 -0
  220. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/logout_api_view.py +0 -0
  221. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/memory_api_view.py +0 -0
  222. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/profile_api_view.py +0 -0
  223. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/prompt_api_view.py +0 -0
  224. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/prompt_context_preview_api_view.py +0 -0
  225. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/prompt_resource_api_view.py +0 -0
  226. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/root_redirect_view.py +0 -0
  227. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/signup_view.py +0 -0
  228. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/static_page_view.py +0 -0
  229. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/tool_api_view.py +0 -0
  230. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/user_feedback_api_view.py +0 -0
  231. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/users_api_view.py +0 -0
  232. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit/views/verify_user_view.py +0 -0
  233. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit.egg-info/SOURCES.txt +0 -0
  234. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
  235. {iatoolkit-2.5.0 → iatoolkit-2.6.1}/src/iatoolkit.egg-info/requires.txt +0 -0
  236. {iatoolkit-2.5.0 → iatoolkit-2.6.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.5.0
3
+ Version: 2.6.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.5.0"
6
+ __version__ = "2.6.1"
7
7
 
8
8
  # Expose main classes and functions at the top level of the package
9
9
 
@@ -16,7 +16,7 @@ from typing import Literal
16
16
 
17
17
 
18
18
  HistoryType = Literal["server_side", "client_side"]
19
- ProviderType = Literal["openai", "gemini", "deepseek", "xai", "anthropic", "unknown"]
19
+ ProviderType = Literal["openai", "gemini", "deepseek", "xai", "anthropic", "openrouter", "openai_compatible", "unknown"]
20
20
 
21
21
 
22
22
  @dataclass(frozen=True)
@@ -47,7 +47,10 @@ class ModelRegistry:
47
47
  "deepseek": ("deepseek",),
48
48
  "xai": ("grok", "grok-1", "grok-beta"),
49
49
  "anthropic": ("claude", "claude-3", "claude-2"),
50
+ "openrouter": ("openrouter/",),
50
51
  }
52
+ self._reasoning_effort_options = ("minimal", "low", "medium", "high", "xhigh")
53
+ self._text_verbosity_options = ("low", "medium", "high")
51
54
 
52
55
  # ------------------------------------------------------------------
53
56
  # Public API
@@ -60,7 +63,7 @@ class ModelRegistry:
60
63
  Examples:
61
64
  "gpt-4o" -> "openai"
62
65
  "gemini-pro" -> "gemini"
63
- "deepseek-chat" -> "deepseek"
66
+ "deepseek-v4-pro" -> "deepseek"
64
67
  """
65
68
  if not model:
66
69
  return "unknown"
@@ -72,6 +75,42 @@ class ModelRegistry:
72
75
 
73
76
  return "unknown"
74
77
 
78
+ def normalize_provider(self, provider: str | None = None, model: str | None = None) -> ProviderType:
79
+ candidate = str(provider or "").strip().lower()
80
+ if candidate in {
81
+ "openai",
82
+ "gemini",
83
+ "deepseek",
84
+ "xai",
85
+ "anthropic",
86
+ "openrouter",
87
+ "openai_compatible",
88
+ }:
89
+ return candidate # type: ignore[return-value]
90
+ return self.get_provider(model or "")
91
+
92
+ def get_capabilities(self, model: str, provider: str | None = None) -> dict:
93
+ normalized_provider = self.normalize_provider(provider=provider, model=model)
94
+ supports_reasoning_effort = normalized_provider in {
95
+ "openai",
96
+ "xai",
97
+ "openrouter",
98
+ "deepseek",
99
+ "openai_compatible",
100
+ }
101
+ supports_text_verbosity = normalized_provider in {"openai", "xai", "openrouter"}
102
+ supports_store = normalized_provider in {"openai", "xai"}
103
+
104
+ return {
105
+ "provider": normalized_provider,
106
+ "history_type": self.get_history_type(model),
107
+ "supports_reasoning_effort": supports_reasoning_effort,
108
+ "allowed_reasoning_efforts": list(self._reasoning_effort_options) if supports_reasoning_effort else [],
109
+ "supports_text_verbosity": supports_text_verbosity,
110
+ "allowed_text_verbosity": list(self._text_verbosity_options) if supports_text_verbosity else [],
111
+ "supports_store": supports_store,
112
+ }
113
+
75
114
  def get_request_defaults(self, model: str) -> dict:
76
115
  """
77
116
  Return per-model request defaults to keep model-specific policy centralized.
@@ -184,10 +184,10 @@ def register_views(app):
184
184
  # --- RAG API Routes ---
185
185
  rag_view = RagApiView.as_view('rag_api')
186
186
 
187
- # 1. List Files (POST for filters)
187
+ # 1. List Files (GET/POST for filters + pagination)
188
188
  app.add_url_rule('/api/rag/<company_short_name>/files',
189
189
  view_func=rag_view,
190
- methods=['POST'],
190
+ methods=['GET', 'POST'],
191
191
  defaults={'action': 'list_files'})
192
192
 
193
193
  # 2. Delete File
@@ -1,7 +1,7 @@
1
1
  ### HTML estructurado
2
2
 
3
3
  #### Tablas
4
- - Usa como base `table table-striped table-hover` de Bootstrap como mínimo.
4
+ - Siempre utiliza tablas con estilos de bootstrap, ejemplo: `table table-striped table-hover`.
5
5
  - Si una columna contiene RUT, fecha, id certificado o valores similares, usa
6
6
  clase `nowrap` en el `<th>` y en el `<td>` correspondiente cuando aplique.
7
7
  - Si una columna debe ir centrada o alineada a la derecha, agrega
@@ -0,0 +1,23 @@
1
+ ### SQL: casting y tipos
2
+
3
+ - Si un numero puede venir con decimales, usa `NUMERIC`, no `INTEGER`.
4
+ - Para numeros extraidos desde JSONB que pueden venir vacios, usa
5
+ `COALESCE(NULLIF(jsonb_col->>'campo', '')::NUMERIC, 0)`.
6
+ - Si agregas numeros extraidos desde JSONB, aplica ese cast dentro de la
7
+ agregacion, no despues.
8
+ - No uses `NULLIF(..., '')` sobre resultados ya agregados ni sobre columnas que
9
+ ya son numericas.
10
+ - Usa `TO_DATE(...)` solo cuando la fecha viene como texto o desde `jsonb->>'campo'`.
11
+ No lo uses sobre columnas que ya son `DATE` o `TIMESTAMP`.
12
+ - Antes de comparar fechas de texto con `CURRENT_DATE`, castealas explicitamente.
13
+ - Los booleanos dentro de JSONB llegan como texto: evalualos con cast explicito,
14
+ por ejemplo `(jsonb_col->>'flag')::BOOLEAN IS TRUE`.
15
+ - La función ROUND(double precision, integer) NO EXISTE en PostgreSQL.
16
+ Todo ROUND() que lleve segundo argumento (cantidad de decimales) debe aplicarsesobre NUMERIC, no sobre DOUBLE PRECISION.
17
+
18
+ Si la expresión a redondear viene de AVG(), MIN(), MAX(), SUM() sobre unacolumna de tipo float/double precision, casteala siempre antes del ROUND:
19
+ ROUND(AVG(columna)::NUMERIC, decimales)ROUND(MIN(columna)::NUMERIC, decimales)ROUND(MAX(columna)::NUMERIC, decimales)ROUND(SUM(columna)::NUMERIC, decimales)
20
+ Esto aplica incluso si la subexpresión ya fue casteada antes: el cast debeestar dentro del ROUND, no afuera.
21
+ Si usás ROUND sin segundo argumento, no hace falta el cast:
22
+ ROUND(AVG(columna)) -- esto sí funciona, devuelve double precision redondeado a entero
23
+ Antes de entregar la consulta SQL final, revisá cada ocurrencia de ROUND(..., N)y verificá que su primer argumento sea NUMERIC. Si no lo es, agregale ::NUMERIC.```
@@ -152,6 +152,16 @@ class IAToolkit:
152
152
  # get a value from the config dict or the environment variable
153
153
  return self.config.get(key, os.getenv(key, default))
154
154
 
155
+ def _get_redis_max_connections(self) -> int:
156
+ raw_value = self._get_config_value("REDIS_MAX_CONNECTIONS", "30")
157
+ try:
158
+ parsed = int(raw_value)
159
+ if parsed > 0:
160
+ return parsed
161
+ except (TypeError, ValueError):
162
+ pass
163
+ return 30
164
+
155
165
  def _setup_request_globals(self):
156
166
  """
157
167
  Configures functions to run before each request to set up
@@ -271,7 +281,8 @@ class IAToolkit:
271
281
  port=url.port,
272
282
  password=url.password,
273
283
  ssl=(url.scheme == "rediss"),
274
- ssl_cert_reqs=None
284
+ ssl_cert_reqs=None,
285
+ max_connections=self._get_redis_max_connections(),
275
286
  )
276
287
 
277
288
  self.app.config.update({
@@ -33,7 +33,8 @@ class AnthropicAdapter:
33
33
  images: Optional[List[Dict]] = None,
34
34
  attachments: Optional[List[Dict]] = None,
35
35
  store: Optional[bool] = None,
36
- metadata: Optional[Dict[str, str]] = None) -> LLMResponse:
36
+ metadata: Optional[Dict[str, str]] = None,
37
+ telemetry_execution: Any = None) -> LLMResponse:
37
38
  """
38
39
  Calls Anthropic Messages API and maps the response to common LLMResponse.
39
40
 
@@ -76,6 +77,8 @@ class AnthropicAdapter:
76
77
  if tool_choice_payload:
77
78
  params["tool_choice"] = tool_choice_payload
78
79
 
80
+ self._record_telemetry_input(telemetry_execution, params)
81
+
79
82
  anthropic_response = self.client.messages.create(**params)
80
83
  return self._map_anthropic_response(anthropic_response, model)
81
84
 
@@ -87,6 +90,12 @@ class AnthropicAdapter:
87
90
  error_message
88
91
  ) from e
89
92
 
93
+ @staticmethod
94
+ def _record_telemetry_input(telemetry_execution: Any, payload: Dict[str, Any]) -> None:
95
+ record_input = getattr(telemetry_execution, "record_input", None)
96
+ if callable(record_input):
97
+ record_input(payload)
98
+
90
99
  def _prepare_messages(self, input_items: List[Dict], images: List[Dict]) -> tuple[Optional[str], List[Dict]]:
91
100
  system_parts: List[str] = []
92
101
  messages: List[Dict] = []
@@ -0,0 +1,75 @@
1
+ # Copyright (c) 2024 Fernando Libedinsky
2
+ # Product: IAToolkit
3
+ #
4
+ # IAToolkit is open source software.
5
+
6
+ from iatoolkit.common.exceptions import IAToolkitException
7
+ from iatoolkit.infra.llm_providers.openai_compatible_chat_adapter import OpenAICompatibleChatAdapter
8
+
9
+
10
+ class DeepseekAdapter(OpenAICompatibleChatAdapter):
11
+ """DeepSeek V4 adapter."""
12
+
13
+ supports_reasoning = False
14
+ supports_reasoning_effort = True
15
+ supports_reasoning_content_messages = True
16
+ supports_thinking = True
17
+ model_capabilities = {
18
+ "deepseek-v4-flash": {
19
+ "supports_thinking": True,
20
+ "supports_tool_choice_required": True,
21
+ },
22
+ "deepseek-v4-pro": {
23
+ "supports_thinking": True,
24
+ "supports_tool_choice_required": True,
25
+ },
26
+ }
27
+ supported_models = frozenset(model_capabilities)
28
+
29
+ def __init__(self, deepseek_client):
30
+ super().__init__(openai_compatible_client=deepseek_client, provider_label="DeepSeek")
31
+
32
+ def create_response(self, model: str, input: list[dict], **kwargs):
33
+ self._validate_model(model)
34
+ return super().create_response(model=model, input=input, **kwargs)
35
+
36
+ @classmethod
37
+ def _validate_model(cls, model: str) -> None:
38
+ normalized_model = str(model or "").strip().lower()
39
+ if normalized_model in cls.supported_models:
40
+ return
41
+
42
+ raise IAToolkitException(
43
+ IAToolkitException.ErrorType.MODEL,
44
+ (
45
+ f"Unsupported DeepSeek model '{model}'. "
46
+ f"Supported models: {sorted(cls.supported_models)}"
47
+ ),
48
+ )
49
+
50
+ def _map_reasoning_effort(self, model: str, effort: str, kwargs: dict) -> str | None:
51
+ _ = model
52
+ _ = kwargs
53
+
54
+ candidate = str(effort or "").strip().lower()
55
+ if candidate in {"low", "medium", "high"}:
56
+ return "high"
57
+ if candidate in {"xhigh", "max"}:
58
+ return "max"
59
+ return None
60
+
61
+ def _build_thinking_payload(self, model: str, reasoning: dict | None, kwargs: dict) -> dict | None:
62
+ explicit_thinking = self._normalize_thinking_payload(kwargs.get("thinking"))
63
+ if explicit_thinking is not None:
64
+ return explicit_thinking
65
+
66
+ reasoning_effort = self._extract_reasoning_effort(reasoning, kwargs)
67
+
68
+ if reasoning_effort == "minimal":
69
+ return {"type": "disabled"}
70
+ if reasoning_effort:
71
+ return {"type": "enabled"}
72
+
73
+ # Keep the default deterministic: unless a prompt explicitly asks for
74
+ # reasoning, use non-thinking mode.
75
+ return {"type": "disabled"}
@@ -53,6 +53,7 @@ class GeminiAdapter:
53
53
  attachments: Optional[List[Dict]] = None,
54
54
  store: Optional[bool] = None,
55
55
  metadata: Optional[Dict[str, str]] = None,
56
+ telemetry_execution: Any = None,
56
57
  ) -> LLMResponse:
57
58
  try:
58
59
  _ = store
@@ -81,6 +82,10 @@ class GeminiAdapter:
81
82
  # "response_modalities": ['TEXT', 'IMAGE']
82
83
  }
83
84
 
85
+ tool_config = self._prepare_gemini_tool_config(tool_choice, tools)
86
+ if tool_config is not None:
87
+ config_kwargs["tool_config"] = tool_config
88
+
84
89
  if isinstance(text, dict):
85
90
  response_schema = text.get("response_schema")
86
91
  if response_schema is not None:
@@ -93,9 +98,12 @@ class GeminiAdapter:
93
98
  config = types.GenerateContentConfig(**config_kwargs)
94
99
  except TypeError as e:
95
100
  # Backward compatibility with older google-genai SDK versions.
96
- if "response_schema" in config_kwargs or "response_mime_type" in config_kwargs:
101
+ if (
102
+ "response_schema" in config_kwargs
103
+ or "response_mime_type" in config_kwargs
104
+ ):
97
105
  logging.warning(
98
- "Gemini SDK doesn't support response_schema fields in GenerateContentConfig. "
106
+ "Gemini SDK doesn't support one or more advanced GenerateContentConfig fields. "
99
107
  "Falling back to prompt-instruction-only mode: %s",
100
108
  e
101
109
  )
@@ -105,6 +113,15 @@ class GeminiAdapter:
105
113
  else:
106
114
  raise
107
115
 
116
+ self._record_telemetry_input(
117
+ telemetry_execution,
118
+ {
119
+ "model": model,
120
+ "contents": contents,
121
+ "config": dict(config_kwargs),
122
+ },
123
+ )
124
+
108
125
  # call the new SDK
109
126
  response = self.client.models.generate_content(
110
127
  model=model,
@@ -144,6 +161,12 @@ class GeminiAdapter:
144
161
 
145
162
  raise IAToolkitException(IAToolkitException.ErrorType.LLM_ERROR, error_message)
146
163
 
164
+ @staticmethod
165
+ def _record_telemetry_input(telemetry_execution: Any, payload: Dict[str, Any]) -> None:
166
+ record_input = getattr(telemetry_execution, "record_input", None)
167
+ if callable(record_input):
168
+ record_input(payload)
169
+
147
170
  def _extract_system_and_filter_input(self, input_list: List[Dict]) -> tuple[Optional[str], List[Dict]]:
148
171
  """Extrae el mensaje de sistema para usarlo en system_instruction."""
149
172
  system_parts = []
@@ -219,10 +242,10 @@ class GeminiAdapter:
219
242
  # Reconstruir llamadas a herramientas si existen
220
243
  if "tool_calls" in message:
221
244
  for tc in message["tool_calls"]:
222
- args = tc["arguments"]
223
- if isinstance(args, str):
224
- args = json.loads(args)
225
- parts.append(types.Part.from_function_call(name=tc["name"], args=args))
245
+ function_name, args = self._extract_history_tool_call(tc)
246
+ if not function_name:
247
+ continue
248
+ parts.append(types.Part.from_function_call(name=function_name, args=args))
226
249
 
227
250
  content = message.get("context") or message.get("content", "")
228
251
  if content:
@@ -294,6 +317,34 @@ class GeminiAdapter:
294
317
 
295
318
  return None
296
319
 
320
+ def _prepare_gemini_tool_config(self, tool_choice: str, tools: List[Dict] | None) -> Optional[Any]:
321
+ tool_names = [
322
+ str(tool.get("name") or "").strip()
323
+ for tool in (tools or [])
324
+ if isinstance(tool, dict) and str(tool.get("name") or "").strip()
325
+ ]
326
+ if not tool_names:
327
+ return None
328
+
329
+ normalized_choice = str(tool_choice or "auto").strip().lower() or "auto"
330
+ function_calling_kwargs: Dict[str, Any] = {}
331
+
332
+ if normalized_choice == "auto":
333
+ function_calling_kwargs["mode"] = "AUTO"
334
+ elif normalized_choice == "none":
335
+ function_calling_kwargs["mode"] = "NONE"
336
+ elif normalized_choice == "required":
337
+ function_calling_kwargs["mode"] = "ANY"
338
+ elif normalized_choice in set(tool_names):
339
+ function_calling_kwargs["mode"] = "ANY"
340
+ function_calling_kwargs["allowed_function_names"] = [normalized_choice]
341
+ else:
342
+ function_calling_kwargs["mode"] = "AUTO"
343
+
344
+ return types.ToolConfig(
345
+ function_calling_config=types.FunctionCallingConfig(**function_calling_kwargs)
346
+ )
347
+
297
348
  def _prepare_response_schema(self, schema: Any) -> Any:
298
349
  """Normalize OpenAI-style JSON schema into a Gemini-compatible schema subset."""
299
350
  if isinstance(schema, dict):
@@ -680,3 +731,30 @@ class GeminiAdapter:
680
731
  output_tokens=output_tokens,
681
732
  total_tokens=total_tokens
682
733
  )
734
+
735
+ @staticmethod
736
+ def _extract_history_tool_call(tool_call: Dict[str, Any]) -> tuple[str, Dict[str, Any]]:
737
+ if not isinstance(tool_call, dict):
738
+ return "", {}
739
+
740
+ function_payload = tool_call.get("function")
741
+ if isinstance(function_payload, dict):
742
+ function_name = str(function_payload.get("name") or "").strip()
743
+ arguments = function_payload.get("arguments", {})
744
+ else:
745
+ function_name = str(tool_call.get("name") or "").strip()
746
+ arguments = tool_call.get("arguments", {})
747
+
748
+ if isinstance(arguments, str):
749
+ try:
750
+ parsed_arguments = json.loads(arguments)
751
+ if isinstance(parsed_arguments, dict):
752
+ arguments = parsed_arguments
753
+ else:
754
+ arguments = {"value": parsed_arguments}
755
+ except Exception:
756
+ arguments = {"value": arguments}
757
+ elif not isinstance(arguments, dict):
758
+ arguments = {}
759
+
760
+ return function_name, arguments
@@ -4,10 +4,9 @@
4
4
  # IAToolkit is open source software.
5
5
 
6
6
  import logging
7
- from typing import Dict, List, Optional
7
+ from typing import Any, Dict, List, Optional
8
8
  from iatoolkit.infra.llm_response import LLMResponse, ToolCall, Usage
9
9
  from iatoolkit.common.exceptions import IAToolkitException
10
- from typing import List
11
10
  import mimetypes
12
11
  import re
13
12
  import base64
@@ -31,7 +30,8 @@ class OpenAIAdapter:
31
30
  images: Optional[List[Dict]] = None,
32
31
  attachments: Optional[List[Dict]] = None,
33
32
  store: Optional[bool] = None,
34
- metadata: Optional[Dict[str, str]] = None) -> LLMResponse:
33
+ metadata: Optional[Dict[str, str]] = None,
34
+ telemetry_execution: Any = None) -> LLMResponse:
35
35
  """Llamada a la API de OpenAI y mapeo a estructura común"""
36
36
  try:
37
37
  # Handle multimodal input if images are present
@@ -44,10 +44,6 @@ class OpenAIAdapter:
44
44
  'input': input
45
45
  }
46
46
 
47
- # add image generation tool
48
- if tools:
49
- tools.append({"type": "image_generation"})
50
-
51
47
  if previous_response_id:
52
48
  params['previous_response_id'] = previous_response_id
53
49
  if tools:
@@ -64,6 +60,8 @@ class OpenAIAdapter:
64
60
  if tool_choice_payload is not None:
65
61
  params['tool_choice'] = tool_choice_payload
66
62
 
63
+ self._record_telemetry_input(telemetry_execution, params)
64
+
67
65
  # Llamar a la API de OpenAI
68
66
  openai_response = self.client.responses.create(**params)
69
67
 
@@ -76,6 +74,12 @@ class OpenAIAdapter:
76
74
 
77
75
  raise IAToolkitException(IAToolkitException.ErrorType.LLM_ERROR, error_message)
78
76
 
77
+ @staticmethod
78
+ def _record_telemetry_input(telemetry_execution: Any, payload: Dict[str, Any]) -> None:
79
+ record_input = getattr(telemetry_execution, "record_input", None)
80
+ if callable(record_input):
81
+ record_input(payload)
82
+
79
83
  @staticmethod
80
84
  def _map_tool_choice(tool_choice: str, tools_payload: List[Dict]) -> Optional[Dict | str]:
81
85
  if tool_choice in ("", None, "auto"):