iatoolkit 2.68.0__tar.gz → 2.69.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 (277) hide show
  1. {iatoolkit-2.68.0/src/iatoolkit.egg-info → iatoolkit-2.69.0}/PKG-INFO +1 -1
  2. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/__init__.py +1 -1
  3. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_agents/memory_document_ingest.prompt +1 -0
  4. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_agents/memory_meeting_ingest.prompt +1 -0
  5. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/memory_compiler_service.py +101 -56
  6. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/memory_service.py +12 -6
  7. iatoolkit-2.69.0/src/iatoolkit/services/memory_sources.py +102 -0
  8. {iatoolkit-2.68.0 → iatoolkit-2.69.0/src/iatoolkit.egg-info}/PKG-INFO +1 -1
  9. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit.egg-info/SOURCES.txt +1 -0
  10. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/LICENSE +0 -0
  11. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/LICENSE_COMMUNITY.md +0 -0
  12. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/pyproject.toml +0 -0
  13. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/readme.md +0 -0
  14. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/setup.cfg +0 -0
  15. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/base_company.py +0 -0
  16. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/cli_commands.py +0 -0
  17. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/__init__.py +0 -0
  18. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/bridge_validation.py +0 -0
  19. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/company_paths.py +0 -0
  20. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/exceptions.py +0 -0
  21. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/interfaces/__init__.py +0 -0
  22. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/interfaces/asset_storage.py +0 -0
  23. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/interfaces/database_provider.py +0 -0
  24. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/interfaces/memory_compilation_trigger.py +0 -0
  25. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/interfaces/secret_provider.py +0 -0
  26. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/interfaces/signup_policy_resolver.py +0 -0
  27. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/interfaces/web_search_provider.py +0 -0
  28. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/memory_tools.py +0 -0
  29. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/model_registry.py +0 -0
  30. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/routes.py +0 -0
  31. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/search_terms.py +0 -0
  32. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/secret_resolver.py +0 -0
  33. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/session_manager.py +0 -0
  34. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/text_splitter.py +0 -0
  35. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/url_safety.py +0 -0
  36. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/common/util.py +0 -0
  37. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/company_registry.py +0 -0
  38. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/__init__.py +0 -0
  39. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/llm_capabilities.yaml +0 -0
  40. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_agents/memory_compiler.prompt +0 -0
  41. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_agents/memory_correction.prompt +0 -0
  42. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_agents/memory_image_ingest.prompt +0 -0
  43. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_agents/memory_question_review.prompt +0 -0
  44. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_agents_pack.yaml +0 -0
  45. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/channel_business_identity.prompt +0 -0
  46. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/channel_conversation_continuity.prompt +0 -0
  47. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/channel_response_style.prompt +0 -0
  48. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/chat_state_rules.prompt +0 -0
  49. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/chat_user_profile.prompt +0 -0
  50. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/core_identity.prompt +0 -0
  51. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/email_output.prompt +0 -0
  52. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/file_download_output.prompt +0 -0
  53. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/format_styles.prompt +0 -0
  54. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/html_structures.prompt +0 -0
  55. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/links_documents.prompt +0 -0
  56. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/memory_usage.prompt +0 -0
  57. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/multimodal_basics.prompt +0 -0
  58. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/output_basics.prompt +0 -0
  59. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/presentation_formatting.prompt +0 -0
  60. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/query_main.prompt +0 -0
  61. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/sql_aggregation_scope.prompt +0 -0
  62. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/sql_casting.prompt +0 -0
  63. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/sql_core.prompt +0 -0
  64. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/sql_jsonb.prompt +0 -0
  65. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/sql_mysql_casting.prompt +0 -0
  66. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/sql_mysql_json.prompt +0 -0
  67. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/sql_redshift_basics.prompt +0 -0
  68. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/sql_redshift_types.prompt +0 -0
  69. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/sql_rules.prompt +0 -0
  70. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts/tool_html_passthrough.prompt +0 -0
  71. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_prompts_pack.yaml +0 -0
  72. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/config/system_tools_pack.yaml +0 -0
  73. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/core.py +0 -0
  74. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/__init__.py +0 -0
  75. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/brevo_mail_app.py +0 -0
  76. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/call_service.py +0 -0
  77. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/connectors/__init__.py +0 -0
  78. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
  79. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
  80. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
  81. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
  82. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
  83. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
  84. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/google_auth_client.py +0 -0
  85. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/google_chat_app.py +0 -0
  86. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/inference_embeddings_client.py +0 -0
  87. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/inference_handler.py +0 -0
  88. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/jina_embeddings_client.py +0 -0
  89. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/llm_gateway_resolver.py +0 -0
  90. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/llm_providers/__init__.py +0 -0
  91. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/llm_providers/anthropic_adapter.py +0 -0
  92. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/llm_providers/deepseek_adapter.py +0 -0
  93. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/llm_providers/gemini_adapter.py +0 -0
  94. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/llm_providers/openai_adapter.py +0 -0
  95. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/llm_providers/openai_compatible_chat_adapter.py +0 -0
  96. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/llm_providers/openrouter_adapter.py +0 -0
  97. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/llm_proxy.py +0 -0
  98. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/llm_response.py +0 -0
  99. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/infra/redis_session_manager.py +0 -0
  100. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/locales/en.yaml +0 -0
  101. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/locales/es.yaml +0 -0
  102. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/__init__.py +0 -0
  103. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/advisory_lock.py +0 -0
  104. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/api_key_repo.py +0 -0
  105. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/bridge_repo.py +0 -0
  106. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/database_manager.py +0 -0
  107. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/document_repo.py +0 -0
  108. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/env_secret_provider.py +0 -0
  109. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/filesystem_asset_repository.py +0 -0
  110. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/knowledge_wiki_repo.py +0 -0
  111. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/llm_query_repo.py +0 -0
  112. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/mcp_token_repo.py +0 -0
  113. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/memory_question_repo.py +0 -0
  114. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/memory_repo.py +0 -0
  115. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/memory_usage_repo.py +0 -0
  116. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/models.py +0 -0
  117. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/profile_repo.py +0 -0
  118. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/prompt_resource_repo.py +0 -0
  119. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/sql_dataset_repo.py +0 -0
  120. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/sql_source_repo.py +0 -0
  121. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/repositories/vs_repo.py +0 -0
  122. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/runtime_logging.py +0 -0
  123. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/__init__.py +0 -0
  124. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/api_key_service.py +0 -0
  125. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/attachment_policy_service.py +0 -0
  126. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/auth_service.py +0 -0
  127. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/branding_service.py +0 -0
  128. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/company_context_service.py +0 -0
  129. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/configuration_service.py +0 -0
  130. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/context_builder_service.py +0 -0
  131. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/dispatcher_service.py +0 -0
  132. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/embedding_service.py +0 -0
  133. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/excel_service.py +0 -0
  134. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/file_processor_service.py +0 -0
  135. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/history_manager_service.py +0 -0
  136. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/http_tool_service.py +0 -0
  137. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/i18n_service.py +0 -0
  138. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/inference_service.py +0 -0
  139. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/jwt_service.py +0 -0
  140. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/knowledge_base_service.py +0 -0
  141. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/language_service.py +0 -0
  142. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/license_service.py +0 -0
  143. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/llm_client_service.py +0 -0
  144. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/mail_service.py +0 -0
  145. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/markdown_wiki_service.py +0 -0
  146. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/mcp_token_service.py +0 -0
  147. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/memory_lookup_policy_service.py +0 -0
  148. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/memory_question_service.py +0 -0
  149. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/memory_usage_service.py +0 -0
  150. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/memory_wiki_service.py +0 -0
  151. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/noop_memory_compilation_trigger.py +0 -0
  152. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/operator_identity_service.py +0 -0
  153. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/parsers/__init__.py +0 -0
  154. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/parsers/contracts.py +0 -0
  155. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/parsers/image_normalizer.py +0 -0
  156. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/parsers/parsing_service.py +0 -0
  157. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/parsers/pdf_ocr_detection.py +0 -0
  158. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/parsers/provider_factory.py +0 -0
  159. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/parsers/provider_resolver.py +0 -0
  160. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/parsers/providers/__init__.py +0 -0
  161. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/parsers/providers/basic_provider.py +0 -0
  162. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/parsers/providers/docling_provider.py +0 -0
  163. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/parsers/validator.py +0 -0
  164. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/pdf_service.py +0 -0
  165. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/profile_service.py +0 -0
  166. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/prompt_resource_service.py +0 -0
  167. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/prompt_service.py +0 -0
  168. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/query_service.py +0 -0
  169. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/signup_policy_resolver.py +0 -0
  170. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/sql_dataset_service.py +0 -0
  171. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/sql_service.py +0 -0
  172. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/sql_source_service.py +0 -0
  173. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/storage_service.py +0 -0
  174. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/structured_output_service.py +0 -0
  175. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/system_agent_catalog.py +0 -0
  176. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/system_agent_runner.py +0 -0
  177. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/system_prompt_catalog.py +0 -0
  178. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/system_tools.py +0 -0
  179. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/telemetry_service.py +0 -0
  180. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/tenant_wiki_service.py +0 -0
  181. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/tool_output_contract.py +0 -0
  182. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/tool_service.py +0 -0
  183. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/user_feedback_service.py +0 -0
  184. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/user_session_context_service.py +0 -0
  185. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/visual_kb_service.py +0 -0
  186. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/visual_tool_service.py +0 -0
  187. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/warmup_service.py +0 -0
  188. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/web_search/__init__.py +0 -0
  189. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/web_search/provider_factory.py +0 -0
  190. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/web_search/providers/__init__.py +0 -0
  191. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/web_search/providers/brave_provider.py +0 -0
  192. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/web_search_service.py +0 -0
  193. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/services/wiki_page_index_service.py +0 -0
  194. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/images/favicon.ico +0 -0
  195. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/images/favicon.png +0 -0
  196. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/images/fernando.jpeg +0 -0
  197. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/images/iatoolkit_core.png +0 -0
  198. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/images/iatoolkit_logo.png +0 -0
  199. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/js/chat_feedback_button.js +0 -0
  200. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/js/chat_filepond.js +0 -0
  201. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/js/chat_header_navigation.js +0 -0
  202. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/js/chat_help_content.js +0 -0
  203. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/js/chat_history_button.js +0 -0
  204. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/js/chat_logout_button.js +0 -0
  205. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/js/chat_main.js +0 -0
  206. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/js/chat_memory_button.js +0 -0
  207. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/js/chat_model_selector.js +0 -0
  208. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/js/chat_onboarding_button.js +0 -0
  209. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/js/chat_prompt_manager.js +0 -0
  210. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/js/chat_reload_button.js +0 -0
  211. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/styles/account.css +0 -0
  212. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/styles/chat_iatoolkit.css +0 -0
  213. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/styles/chat_modal.css +0 -0
  214. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/styles/chat_public.css +0 -0
  215. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/styles/documents.css +0 -0
  216. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/styles/landing_page.css +0 -0
  217. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/styles/llm_output.css +0 -0
  218. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/styles/onboarding.css +0 -0
  219. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/static/styles/wiki_page.css +0 -0
  220. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/_chat_header.html +0 -0
  221. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/_company_header.html +0 -0
  222. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/_login_widget.html +0 -0
  223. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/account.html +0 -0
  224. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/base.html +0 -0
  225. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/change_password.html +0 -0
  226. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/chat.html +0 -0
  227. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/chat_memory_modal.html +0 -0
  228. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/chat_modals.html +0 -0
  229. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/error.html +0 -0
  230. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/forgot_password.html +0 -0
  231. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/home_hosted_default.html +0 -0
  232. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/login_global.html +0 -0
  233. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/memory/wiki_schema.md +0 -0
  234. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/onboarding_shell.html +0 -0
  235. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/pdf/base.html +0 -0
  236. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/pdf/letter.html +0 -0
  237. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/pdf/report.html +0 -0
  238. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/pdf/simple.html +0 -0
  239. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/signup.html +0 -0
  240. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/templates/wiki_page.html +0 -0
  241. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/__init__.py +0 -0
  242. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/account_view.py +0 -0
  243. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/api_key_api_view.py +0 -0
  244. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/base_login_view.py +0 -0
  245. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/categories_api_view.py +0 -0
  246. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/change_password_view.py +0 -0
  247. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/chat_context_preview_api_view.py +0 -0
  248. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/chat_view.py +0 -0
  249. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/configuration_api_view.py +0 -0
  250. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/connectors_api_view.py +0 -0
  251. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/embedding_api_view.py +0 -0
  252. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/forgot_password_view.py +0 -0
  253. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/help_content_api_view.py +0 -0
  254. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/history_api_view.py +0 -0
  255. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/home_view.py +0 -0
  256. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/init_context_api_view.py +0 -0
  257. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/llmquery_api_view.py +0 -0
  258. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/load_document_api_view.py +0 -0
  259. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/login_view.py +0 -0
  260. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/logout_api_view.py +0 -0
  261. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/memory_api_view.py +0 -0
  262. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/profile_api_view.py +0 -0
  263. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/prompt_api_view.py +0 -0
  264. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/prompt_context_preview_api_view.py +0 -0
  265. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/prompt_resource_api_view.py +0 -0
  266. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/rag_api_view.py +0 -0
  267. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/root_redirect_view.py +0 -0
  268. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/signup_view.py +0 -0
  269. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/static_page_view.py +0 -0
  270. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/tool_api_view.py +0 -0
  271. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/user_feedback_api_view.py +0 -0
  272. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/users_api_view.py +0 -0
  273. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/verify_user_view.py +0 -0
  274. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit/views/wiki_page_view.py +0 -0
  275. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
  276. {iatoolkit-2.68.0 → iatoolkit-2.69.0}/src/iatoolkit.egg-info/requires.txt +0 -0
  277. {iatoolkit-2.68.0 → iatoolkit-2.69.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.68.0
3
+ Version: 2.69.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.68.0"
6
+ __version__ = "2.69.0"
7
7
 
8
8
  # Expose main classes and functions at the top level of the package
9
9
 
@@ -13,6 +13,7 @@ How to write the pages:
13
13
  - Update one of the CANDIDATE_PAGES when the part belongs to its subject; create a new page when none covers it (check PAGE_INDEX first so you do not duplicate a page). One part may touch several pages; return each one.
14
14
  - When you update, return the COMPLETE new page: keep everything already on it, word for word, including people's attributions. Add the new facts in the section where they belong.
15
15
  - When this part says something different from what the page already says, keep both statements with their attributions and make the difference explicit; never delete what someone else said. Also list each contradiction in `conflicts`.
16
+ - A line marked **[obsoleto: …]** is no longer valid: it stays on the page as it is, but it is not a contradiction. Neither is a line attributed to an earlier version of this same document ({{ source.label }} with an earlier date): the new version replaces it, so write the current fact and do not list a conflict for it. Contradictions are only with other sources (people, other documents).
16
17
  - Attribute every fact you add as ({{ source.label }}, {{ captured_on }}).
17
18
  - Follow the WIKI_SCHEMA. Write in the language of the page, or of the document for a new page.
18
19
  - If this part has nothing worth keeping, return an empty `pages` list.
@@ -16,6 +16,7 @@ How to write the pages:
16
16
  - Update one of the CANDIDATE_PAGES when the part belongs to its subject; create a new page when none covers it (check PAGE_INDEX first so you do not duplicate a page). One part may touch several pages; return each one.
17
17
  - When you update, return the COMPLETE new page: keep everything already on it, word for word, including people's attributions. Add the new facts in the section where they belong.
18
18
  - When this part says something different from what the page already says, keep both statements with their attributions and make the difference explicit; never delete what someone else said. Also list each contradiction in `conflicts`. A meeting that changes a rule is a contradiction worth showing.
19
+ - A line marked **[obsoleto: …]** is no longer valid: it stays on the page as it is, but it is not a contradiction. Neither is a line attributed to an earlier version of this same document ({{ source.label }} with an earlier date): the new version replaces it, so write the current fact and do not list a conflict for it. Contradictions are only with other sources (people, other documents).
19
20
  - Attribute every fact you add to the meeting: ({{ source.label }}, {{ captured_on }}).
20
21
  - Follow the WIKI_SCHEMA. Write in the language of the page, or of the transcript for a new page.
21
22
  - If this part decided or taught nothing worth keeping, return an empty `pages` list.
@@ -9,6 +9,7 @@ import base64
9
9
  import logging
10
10
  import mimetypes
11
11
  import re
12
+ import time
12
13
  from contextlib import contextmanager
13
14
  from datetime import datetime
14
15
  from html import unescape
@@ -25,6 +26,7 @@ from iatoolkit.repositories.models import (
25
26
  Company, MemoryCapture, MemoryCaptureStatus, MemoryConflict, MemoryItem, MemoryItemStatus, MemoryItemType, VSDoc,
26
27
  )
27
28
  from iatoolkit.repositories.profile_repo import ProfileRepo
29
+ from iatoolkit.services.memory_sources import MemorySourceRegistry, register_core_sources
28
30
  from iatoolkit.services.memory_wiki_service import MemoryWikiService
29
31
  from iatoolkit.services.storage_service import StorageService
30
32
  from iatoolkit.services.system_agent_runner import SystemAgentDisabled, SystemAgentRunner
@@ -50,6 +52,10 @@ class MemoryCompilerService:
50
52
  MAX_CANDIDATE_PAGES = 3
51
53
  MAX_INDEX_ENTRIES_IN_PROMPT = 80
52
54
  MAX_BATCHES_PER_RUN = 20
55
+ # A run gives its worker back after this long and the rest goes to a new task.
56
+ MAX_RUN_SECONDS = 15 * 60
57
+ # Times a run takes the lock again for captures saved as it was releasing it.
58
+ MAX_LOCK_ROUNDS = 3
53
59
  MAX_SAVE_ATTEMPTS = 3
54
60
  COMPILER_SOURCE = "memory_compiler"
55
61
  # A capture that asks to change one page (Memoria → "¿Qué hay que corregir?").
@@ -79,6 +85,10 @@ class MemoryCompilerService:
79
85
  # A document that fed the wiki was deleted: its facts are marked, never erased.
80
86
  DOCUMENT_REMOVED_MODE = "document_removed"
81
87
  OBSOLETE_MARK = "obsoleto: se eliminó el documento"
88
+ # A new version of the document replaced the one these lines came from (BL-016, Fase 3).
89
+ OBSOLETE_REPLACED_MARK = "obsoleto: hay una versión nueva del documento"
90
+ # Any obsolete mark, whatever its reason: a line is marked once.
91
+ OBSOLETE_PREFIX = "**[obsoleto"
82
92
  CORRECTION_AGENT = "memory_correction"
83
93
 
84
94
  @inject
@@ -109,31 +119,48 @@ class MemoryCompilerService:
109
119
  compiled_count = 0
110
120
  processed_count = 0
111
121
  waiting_count = 0
112
- with self._company_lock(company.id):
113
- # Keep draining: a capture saved while this run held the lock waited
114
- # for it instead of compiling concurrently, and must not be left behind.
115
- for _ in range(self.MAX_BATCHES_PER_RUN):
116
- pending_captures = self.memory_repo.get_pending_captures(company.id, limit=limit)
117
- if not pending_captures:
118
- break
119
- batch_waiting = 0
120
- for capture in pending_captures:
121
- agent_key = self._agent_for(capture)
122
- if agent_key and not SystemAgentRunner.is_enabled(agent_key):
123
- # Its agent is turned off by the platform: the capture stays
124
- # pending and is compiled when the agent is turned on again.
125
- batch_waiting += 1
126
- continue
127
- processed_count += 1
128
- compiled = self._compile_capture_safely(company, capture)
129
- if compiled is None:
130
- batch_waiting += 1
131
- elif compiled:
132
- compiled_count += 1
133
- waiting_count += batch_waiting
134
- if batch_waiting == len(pending_captures):
135
- # Nothing in this batch could move; reading it again would only repeat that.
136
- break
122
+ stopped = None
123
+ started = time.monotonic()
124
+ for _ in range(self.MAX_LOCK_ROUNDS):
125
+ with self._company_lock(company.id) as held:
126
+ if not held:
127
+ # Another run of this company holds the lock and drains every
128
+ # pending capture, including this one; this task ends now
129
+ # instead of keeping a worker waiting (BL-016, Fase 3).
130
+ return {"status": "success", "absorbed": True, "compiled_count": 0, "processed_count": 0,
131
+ "waiting_count": 0, "pending_count": None}
132
+ waiting_count = 0
133
+ for _batch in range(self.MAX_BATCHES_PER_RUN):
134
+ pending_captures = self.memory_repo.get_pending_captures(company.id, limit=limit)
135
+ if not pending_captures:
136
+ break
137
+ batch_waiting = 0
138
+ for capture in pending_captures:
139
+ agent_key = self._agent_for(capture)
140
+ if agent_key and not SystemAgentRunner.is_enabled(agent_key):
141
+ # Its agent is turned off by the platform: the capture stays
142
+ # pending and is compiled when the agent is turned on again.
143
+ batch_waiting += 1
144
+ continue
145
+ processed_count += 1
146
+ compiled = self._compile_capture_safely(company, capture)
147
+ if compiled is None:
148
+ batch_waiting += 1
149
+ elif compiled:
150
+ compiled_count += 1
151
+ if time.monotonic() - started > self.MAX_RUN_SECONDS:
152
+ stopped = "time_limit"
153
+ break
154
+ waiting_count += batch_waiting
155
+ if stopped or batch_waiting == len(pending_captures):
156
+ # Out of time, or nothing in this batch could move.
157
+ break
158
+ if stopped:
159
+ break
160
+ # A capture saved just as the lock was released found it taken and was
161
+ # absorbed: it is pending now, and this run takes it.
162
+ if len(self.memory_repo.get_pending_captures(company.id, limit=limit)) <= waiting_count:
163
+ break
137
164
 
138
165
  return {
139
166
  "status": "success",
@@ -141,6 +168,8 @@ class MemoryCompilerService:
141
168
  "processed_count": processed_count,
142
169
  "waiting_count": waiting_count,
143
170
  "pending_count": len(self.memory_repo.get_pending_captures(company.id, limit=limit)),
171
+ # The task stopped to free its worker; the caller queues the rest.
172
+ "stopped": stopped,
144
173
  }
145
174
 
146
175
  def compile_pending_for_user(self, company_short_name: str, user_identifier: str | None = None, limit: int = 12) -> dict:
@@ -150,26 +179,19 @@ class MemoryCompilerService:
150
179
  @contextmanager
151
180
  def _company_lock(self, company_id: int):
152
181
  """
153
- Serializes compilation per company across workers and web processes.
154
-
155
- Uses a session-level Postgres advisory lock on a dedicated connection,
156
- so the many commits made while compiling cannot release it early. Other
157
- databases (SQLite in tests and local runs) have no concurrent compilers.
182
+ One compilation run per company at a time, across workers and web
183
+ processes; yields whether this run holds it. It does not wait: a run that
184
+ finds it taken leaves (the holder drains what is pending), so no worker
185
+ is kept waiting (BL-016, Fase 3). Postgres advisory lock on a dedicated
186
+ connection; on SQLite (tests) it is always held.
158
187
  """
159
- with advisory_lock(self.db_manager, self.ADVISORY_LOCK_NAMESPACE, company_id):
160
- yield
161
-
162
- def _agent_for(self, capture: MemoryCapture) -> str:
163
- mode = dict(capture.meta or {}).get("mode")
164
- if mode == self.CORRECTION_MODE:
165
- return self.CORRECTION_AGENT
166
- if mode == self.DOCUMENT_MODE:
167
- if dict(capture.meta or {}).get("kind") == self.MEETING_KIND:
168
- return self.MEETING_AGENT
169
- return self.DOCUMENT_AGENT
170
- if mode == self.DOCUMENT_REMOVED_MODE:
171
- return None # marked without the model
172
- return self.COMPILER_AGENT
188
+ with advisory_lock(self.db_manager, self.ADVISORY_LOCK_NAMESPACE, company_id, wait=False) as held:
189
+ yield held
190
+
191
+ def _agent_for(self, capture: MemoryCapture) -> str | None:
192
+ """The system agent that reads the capture, as its source declares (memory_sources)."""
193
+ meta = dict(capture.meta or {})
194
+ return MemorySourceRegistry.for_capture(meta).agent_for(meta)
173
195
 
174
196
  def _compile_capture_safely(self, company: Company, capture: MemoryCapture) -> bool | None:
175
197
  """Whether the capture became a page; None when it stays pending (its agent was turned off)."""
@@ -198,12 +220,12 @@ class MemoryCompilerService:
198
220
  return False
199
221
 
200
222
  def _compile_single_capture(self, company: Company, capture: MemoryCapture, items: list[MemoryItem]) -> bool:
201
- if dict(capture.meta or {}).get("mode") == self.CORRECTION_MODE:
202
- return self._apply_correction(company, capture, items)
203
- if dict(capture.meta or {}).get("mode") == self.DOCUMENT_MODE:
204
- return self._ingest_document(company, capture, items)
205
- if dict(capture.meta or {}).get("mode") == self.DOCUMENT_REMOVED_MODE:
206
- return self._mark_document_obsolete(company, capture, items)
223
+ """Reads the capture with the step its source declares (memory_sources)."""
224
+ source = MemorySourceRegistry.for_capture(dict(capture.meta or {}))
225
+ return getattr(self, source.handler)(company, capture, items)
226
+
227
+ def _compile_person_capture(self, company: Company, capture: MemoryCapture, items: list[MemoryItem]) -> bool:
228
+ """What a person explained, filed into the pages it belongs to."""
207
229
  author = self._author_label(capture.user_identifier)
208
230
  captured_on = (capture.created_at or datetime.now()).date().isoformat()
209
231
 
@@ -389,6 +411,12 @@ class MemoryCompilerService:
389
411
  meta = dict(capture.meta or {})
390
412
  document_id = self._as_int(meta.get("document_id"))
391
413
  today = (capture.created_at or datetime.now()).date().isoformat()
414
+ replaced = meta.get("reason") == "replaced"
415
+ mark = self.OBSOLETE_REPLACED_MARK if replaced else self.OBSOLETE_MARK
416
+ why = "hay una versión nueva del documento" if replaced else "se eliminó el documento"
417
+ # A replaced version marks only lines from before this capture: if the new
418
+ # version was already read (a retry that ran late), its lines stay.
419
+ before = today if replaced else None
392
420
  marked_pages = []
393
421
  for link in self.memory_repo.list_document_links(company.id, document_id):
394
422
  labels = {label for label in (link.label, meta.get("label")) if label}
@@ -397,7 +425,7 @@ class MemoryCompilerService:
397
425
  if not page:
398
426
  break
399
427
  body = self.memory_wiki_service.page_body(page)
400
- marked = self._mark_obsolete_lines(body, labels, today)
428
+ marked = self._mark_obsolete_lines(body, labels, today, mark=mark, before=before)
401
429
  if marked == body:
402
430
  break
403
431
  response = self.memory_wiki_service.update_page(
@@ -407,7 +435,7 @@ class MemoryCompilerService:
407
435
  summary=str(page.get("summary") or "").strip(),
408
436
  body=marked,
409
437
  edited_by=capture.user_identifier,
410
- change_summary=f"Datos de «{sorted(labels)[0] if labels else document_id}» marcados como obsoletos: se eliminó el documento.",
438
+ change_summary=f"Datos de «{sorted(labels)[0] if labels else document_id}» marcados como obsoletos: {why}.",
411
439
  revision_metadata={
412
440
  "source": self.COMPILER_SOURCE,
413
441
  "capture_id": capture.id,
@@ -428,12 +456,17 @@ class MemoryCompilerService:
428
456
  return bool(marked_pages)
429
457
 
430
458
  @classmethod
431
- def _mark_obsolete_lines(cls, body: str, labels: set[str], day: str) -> str:
432
- patterns = [re.compile(r"\(\s*" + re.escape(label) + r"\s*,\s*\d{4}-\d{2}-\d{2}\s*\)") for label in labels]
459
+ def _mark_obsolete_lines(cls, body: str, labels: set[str], day: str, *, mark: str | None = None,
460
+ before: str | None = None) -> str:
461
+ """Marks each line attributed to the document; with `before`, only those dated earlier."""
462
+ mark = mark or cls.OBSOLETE_MARK
463
+ patterns = [re.compile(r"\(\s*" + re.escape(label) + r"\s*,\s*(\d{4}-\d{2}-\d{2})\s*\)") for label in labels]
433
464
  lines = []
434
465
  for line in str(body or "").split("\n"):
435
- if cls.OBSOLETE_MARK not in line and any(pattern.search(line) for pattern in patterns):
436
- line = f"{line.rstrip()} **[{cls.OBSOLETE_MARK}, {day}]**"
466
+ if cls.OBSOLETE_PREFIX not in line:
467
+ dates = [match.group(1) for pattern in patterns for match in pattern.finditer(line)]
468
+ if dates and (before is None or min(dates) < before):
469
+ line = f"{line.rstrip()} **[{mark}, {day}]**"
437
470
  lines.append(line)
438
471
  return "\n".join(lines)
439
472
 
@@ -1067,3 +1100,15 @@ class MemoryCompilerService:
1067
1100
  return f"Archivo: {item.filename}"
1068
1101
  item = items[0]
1069
1102
  return f"{item.item_type.value if hasattr(item.item_type, 'value') else item.item_type}"
1103
+
1104
+
1105
+ register_core_sources(
1106
+ compiler_agent=MemoryCompilerService.COMPILER_AGENT,
1107
+ correction_agent=MemoryCompilerService.CORRECTION_AGENT,
1108
+ document_agent=MemoryCompilerService.DOCUMENT_AGENT,
1109
+ meeting_agent=MemoryCompilerService.MEETING_AGENT,
1110
+ correction_mode=MemoryCompilerService.CORRECTION_MODE,
1111
+ document_mode=MemoryCompilerService.DOCUMENT_MODE,
1112
+ document_removed_mode=MemoryCompilerService.DOCUMENT_REMOVED_MODE,
1113
+ meeting_kind=MemoryCompilerService.MEETING_KIND,
1114
+ )
@@ -203,11 +203,15 @@ class MemoryService:
203
203
  *,
204
204
  document_id: int,
205
205
  label: str,
206
- removed_by: str | None = None) -> dict:
206
+ removed_by: str | None = None,
207
+ reason: str = "removed") -> dict:
207
208
  """
208
- A document that fed the wiki was deleted (BL-014): queued so the compiler
209
- marks its facts as obsolete on the pages that cite it. Nothing is erased.
210
- Does nothing when no page cites the document.
209
+ A document that fed the wiki was deleted (BL-014), or a new version of it
210
+ replaced this one (`reason="replaced"`, BL-016 Fase 3): queued so the
211
+ compiler marks its facts as obsolete on the pages that cite it. Nothing is
212
+ erased. Queue it before the new version: captures compile in order, so the
213
+ new version is read with the old lines already marked. Does nothing when
214
+ no page cites the document.
211
215
  """
212
216
  company = self.profile_repo.get_company_by_short_name(company_short_name)
213
217
  if not company:
@@ -222,10 +226,12 @@ class MemoryService:
222
226
  new_items=[{
223
227
  "item_type": "note",
224
228
  "title": label,
225
- "content_text": f"Se eliminó el documento «{label}».",
229
+ "content_text": (f"Hay una versión nueva del documento «{label}»." if reason == "replaced"
230
+ else f"Se eliminó el documento «{label}»."),
226
231
  "source_meta": {"origin": "memory_document_removed", "rag_document_id": document_id},
227
232
  }],
228
- meta={"mode": MemoryCompilerService.DOCUMENT_REMOVED_MODE, "document_id": document_id, "label": label},
233
+ meta={"mode": MemoryCompilerService.DOCUMENT_REMOVED_MODE, "document_id": document_id, "label": label,
234
+ "reason": "replaced" if reason == "replaced" else "removed"},
229
235
  )
230
236
 
231
237
  # Fase 0 (R4): a capture whose compilation failed (the model was down, a
@@ -0,0 +1,102 @@
1
+ # Copyright (c) 2024 Fernando Libedinsky
2
+ # Product: IAToolkit
3
+ #
4
+ # IAToolkit is open source software.
5
+
6
+ """The contract of a Memoria source (BL-016, Fase 3).
7
+
8
+ Everything enters Memoria as a capture; what kind of source a capture comes
9
+ from is its `meta.mode` (and, for a document, its `meta.kind`). Before, each
10
+ kind was a string in `meta` plus an `if` in the compiler, with its rules spread
11
+ over three services. A source now declares, in one place:
12
+
13
+ - `mode`: the capture's `meta.mode` it answers for (None: a person's capture);
14
+ - `handler`: the compiler step that reads it;
15
+ - `agent`: the system agent that reads it (None: no model), and `kind_agents`
16
+ for variants of the same source (a meeting transcript is a document read by
17
+ the meeting reader);
18
+ - `on_new_version`: what a new version of the same source does to what the
19
+ previous one taught ("replace": its lines are marked obsolete before the new
20
+ version is read; "add": both stay, as two people saying things);
21
+ - `on_removal`: what its removal does ("mark_obsolete": its lines are marked,
22
+ never erased; "none");
23
+ - `visibility`: who may read what it teaches. "company" for every source today;
24
+ the field is where Fase 4 (BL-010) will declare restricted sources.
25
+
26
+ A new source registers here (`MemorySourceRegistry.register`) instead of adding
27
+ another branch to the compiler.
28
+ """
29
+
30
+ from __future__ import annotations
31
+
32
+ from dataclasses import dataclass, field
33
+
34
+ VERSION_REPLACE = "replace"
35
+ VERSION_ADD = "add"
36
+ REMOVAL_MARK_OBSOLETE = "mark_obsolete"
37
+ REMOVAL_NONE = "none"
38
+ VISIBILITY_COMPANY = "company"
39
+
40
+
41
+ @dataclass(frozen=True)
42
+ class MemorySource:
43
+ key: str
44
+ mode: str | None
45
+ handler: str
46
+ agent: str | None
47
+ kind_agents: dict = field(default_factory=dict)
48
+ on_new_version: str = VERSION_ADD
49
+ on_removal: str = REMOVAL_NONE
50
+ visibility: str = VISIBILITY_COMPANY
51
+ description: str = ""
52
+
53
+ def agent_for(self, meta: dict | None) -> str | None:
54
+ kind = str((meta or {}).get("kind") or "").strip()
55
+ return self.kind_agents.get(kind, self.agent)
56
+
57
+
58
+ class MemorySourceRegistry:
59
+ """Which source each capture is, by its `meta.mode`."""
60
+
61
+ _sources: dict[str | None, MemorySource] = {}
62
+
63
+ @classmethod
64
+ def register(cls, source: MemorySource) -> None:
65
+ cls._sources[source.mode] = source
66
+
67
+ @classmethod
68
+ def for_capture(cls, meta: dict | None) -> MemorySource:
69
+ mode = (meta or {}).get("mode")
70
+ return cls._sources.get(mode) or cls._sources[None]
71
+
72
+ @classmethod
73
+ def get(cls, key: str) -> MemorySource | None:
74
+ return next((source for source in cls._sources.values() if source.key == key), None)
75
+
76
+ @classmethod
77
+ def all(cls) -> list[MemorySource]:
78
+ return list(cls._sources.values())
79
+
80
+
81
+ def register_core_sources(*, compiler_agent: str, correction_agent: str, document_agent: str,
82
+ meeting_agent: str, correction_mode: str, document_mode: str,
83
+ document_removed_mode: str, meeting_kind: str) -> None:
84
+ """The sources core knows; MemoryCompilerService registers them with its constants."""
85
+ MemorySourceRegistry.register(MemorySource(
86
+ key="people", mode=None, handler="_compile_person_capture", agent=compiler_agent,
87
+ description="What a person explained: the chat, MCP, the console, an answered question, the capture API.",
88
+ ))
89
+ MemorySourceRegistry.register(MemorySource(
90
+ key="correction", mode=correction_mode, handler="_apply_correction", agent=correction_agent,
91
+ description="'¿Qué hay que corregir?' on one page.",
92
+ ))
93
+ MemorySourceRegistry.register(MemorySource(
94
+ key="document", mode=document_mode, handler="_ingest_document", agent=document_agent,
95
+ kind_agents={meeting_kind: meeting_agent},
96
+ on_new_version=VERSION_REPLACE, on_removal=REMOVAL_MARK_OBSOLETE,
97
+ description="A document of a Memoria folder (Drive or uploaded), or a meeting transcript.",
98
+ ))
99
+ MemorySourceRegistry.register(MemorySource(
100
+ key="document_removed", mode=document_removed_mode, handler="_mark_document_obsolete", agent=None,
101
+ description="A document that left Memoria, or the previous version of one: its lines marked obsolete.",
102
+ ))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iatoolkit
3
- Version: 2.68.0
3
+ Version: 2.69.0
4
4
  Summary: IAToolkit
5
5
  Author: Fernando Libedinsky
6
6
  License-Expression: MIT
@@ -146,6 +146,7 @@ src/iatoolkit/services/memory_compiler_service.py
146
146
  src/iatoolkit/services/memory_lookup_policy_service.py
147
147
  src/iatoolkit/services/memory_question_service.py
148
148
  src/iatoolkit/services/memory_service.py
149
+ src/iatoolkit/services/memory_sources.py
149
150
  src/iatoolkit/services/memory_usage_service.py
150
151
  src/iatoolkit/services/memory_wiki_service.py
151
152
  src/iatoolkit/services/noop_memory_compilation_trigger.py
File without changes
File without changes
File without changes
File without changes