iatoolkit 2.74.0__tar.gz → 2.74.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.
- {iatoolkit-2.74.0/src/iatoolkit.egg-info → iatoolkit-2.74.1}/PKG-INFO +1 -1
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/__init__.py +1 -1
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/model_registry.py +42 -5
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/llm_providers/openai_adapter.py +9 -5
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/llm_proxy.py +42 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/attachment_policy_service.py +51 -132
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/configuration_service.py +5 -1
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/system_agent_runner.py +3 -2
- {iatoolkit-2.74.0 → iatoolkit-2.74.1/src/iatoolkit.egg-info}/PKG-INFO +1 -1
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/LICENSE +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/LICENSE_COMMUNITY.md +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/pyproject.toml +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/readme.md +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/setup.cfg +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/base_company.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/cli_commands.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/__init__.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/access.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/bridge_validation.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/company_paths.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/exceptions.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/interfaces/__init__.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/interfaces/asset_storage.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/interfaces/database_provider.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/interfaces/history_compaction_trigger.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/interfaces/memory_compilation_trigger.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/interfaces/secret_provider.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/interfaces/signup_policy_resolver.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/interfaces/web_search_provider.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/memory_tools.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/routes.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/search_terms.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/secret_resolver.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/session_manager.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/text_splitter.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/url_safety.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/util.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/company_registry.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/__init__.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/llm_capabilities.yaml +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_agents/history_compaction.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_agents/memory_compiler.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_agents/memory_correction.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_agents/memory_document_ingest.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_agents/memory_image_ingest.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_agents/memory_meeting_ingest.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_agents/memory_question_review.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_agents_pack.yaml +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/channel_business_identity.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/channel_conversation_continuity.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/channel_response_style.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/chat_state_rules.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/chat_user_profile.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/core_identity.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/email_output.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/file_download_output.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/format_styles.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/html_structures.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/links_documents.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/memory_usage.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/multimodal_basics.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/output_basics.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/presentation_formatting.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/query_main.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/sql_aggregation_scope.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/sql_casting.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/sql_core.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/sql_jsonb.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/sql_mysql_casting.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/sql_mysql_json.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/sql_redshift_basics.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/sql_redshift_types.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/sql_rules.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/tool_html_passthrough.prompt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts_pack.yaml +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_tools_pack.yaml +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/core.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/__init__.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/brevo_mail_app.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/call_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/connectors/__init__.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/google_auth_client.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/google_chat_app.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/inference_embeddings_client.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/inference_handler.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/jina_embeddings_client.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/llm_gateway_resolver.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/llm_providers/__init__.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/llm_providers/anthropic_adapter.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/llm_providers/deepseek_adapter.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/llm_providers/gemini_adapter.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/llm_providers/openai_compatible_chat_adapter.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/llm_providers/openrouter_adapter.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/llm_response.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/infra/redis_session_manager.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/locales/en.yaml +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/locales/es.yaml +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/__init__.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/advisory_lock.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/api_key_repo.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/bridge_repo.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/database_manager.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/document_repo.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/env_secret_provider.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/filesystem_asset_repository.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/knowledge_wiki_repo.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/llm_query_repo.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/mcp_token_repo.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/memory_question_repo.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/memory_repo.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/memory_usage_repo.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/models.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/profile_repo.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/prompt_resource_repo.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/sql_dataset_repo.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/sql_source_repo.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/repositories/vs_repo.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/runtime_logging.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/__init__.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/api_key_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/auth_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/branding_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/company_context_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/context_builder_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/dispatcher_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/embedding_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/excel_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/file_processor_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/history_compaction_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/history_manager_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/http_tool_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/i18n_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/inference_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/jwt_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/knowledge_base_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/language_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/license_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/llm_client_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/mail_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/markdown_wiki_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/mcp_token_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/memory_compiler_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/memory_lookup_policy_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/memory_question_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/memory_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/memory_sources.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/memory_usage_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/memory_wiki_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/noop_history_compaction_trigger.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/noop_memory_compilation_trigger.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/operator_identity_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/parsers/__init__.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/parsers/contracts.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/parsers/image_normalizer.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/parsers/parsing_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/parsers/pdf_ocr_detection.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/parsers/provider_factory.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/parsers/provider_resolver.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/parsers/providers/__init__.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/parsers/providers/basic_provider.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/parsers/providers/docling_provider.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/parsers/validator.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/pdf_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/profile_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/prompt_resource_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/prompt_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/query_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/resource_access_scope.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/signup_policy_resolver.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/sql_dataset_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/sql_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/sql_source_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/storage_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/structured_output_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/system_agent_catalog.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/system_prompt_catalog.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/system_tools.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/telemetry_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/tenant_wiki_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/tool_output_contract.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/tool_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/user_feedback_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/user_session_context_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/visual_kb_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/visual_tool_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/warmup_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/web_search/__init__.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/web_search/provider_factory.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/web_search/providers/__init__.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/web_search/providers/brave_provider.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/web_search_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/services/wiki_page_index_service.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/images/favicon.ico +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/images/favicon.png +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/images/fernando.jpeg +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/images/iatoolkit_core.png +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/images/iatoolkit_logo.png +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/js/chat_feedback_button.js +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/js/chat_filepond.js +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/js/chat_header_navigation.js +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/js/chat_help_content.js +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/js/chat_history_button.js +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/js/chat_logout_button.js +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/js/chat_main.js +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/js/chat_memory_button.js +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/js/chat_model_selector.js +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/js/chat_onboarding_button.js +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/js/chat_prompt_manager.js +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/styles/account.css +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/styles/chat_iatoolkit.css +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/styles/chat_modal.css +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/styles/chat_public.css +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/styles/documents.css +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/styles/landing_page.css +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/styles/llm_output.css +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/styles/onboarding.css +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/static/styles/wiki_page.css +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/_chat_header.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/_company_header.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/_login_widget.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/account.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/base.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/change_password.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/chat.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/chat_memory_modal.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/chat_modals.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/error.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/forgot_password.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/home_hosted_default.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/login_global.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/memory/wiki_schema.md +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/onboarding_shell.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/pdf/base.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/pdf/letter.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/pdf/report.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/pdf/simple.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/signup.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/templates/wiki_page.html +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/__init__.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/account_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/api_key_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/base_login_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/categories_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/change_password_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/chat_context_preview_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/chat_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/configuration_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/connectors_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/embedding_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/forgot_password_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/help_content_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/history_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/home_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/init_context_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/llmquery_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/load_document_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/login_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/logout_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/memory_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/profile_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/prompt_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/prompt_context_preview_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/prompt_resource_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/rag_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/root_redirect_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/signup_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/static_page_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/tool_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/user_feedback_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/users_api_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/verify_user_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/views/wiki_page_view.py +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit.egg-info/SOURCES.txt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit.egg-info/requires.txt +0 -0
- {iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit.egg-info/top_level.txt +0 -0
|
@@ -165,21 +165,58 @@ class ModelRegistry:
|
|
|
165
165
|
return candidate # type: ignore[return-value]
|
|
166
166
|
return self.get_provider(model or "")
|
|
167
167
|
|
|
168
|
-
|
|
168
|
+
@staticmethod
|
|
169
|
+
def catalog_capabilities(model_config: dict | None) -> dict | None:
|
|
170
|
+
"""The capabilities the model catalogue holds for a model, or None when unknown.
|
|
171
|
+
|
|
172
|
+
Written by `models-sync` from OpenRouter (BL-009, Fase F) and carried in
|
|
173
|
+
the model's configuration. Empty, or a company.yaml model outside the
|
|
174
|
+
catalogue, means unknown: the provider's rules decide.
|
|
175
|
+
"""
|
|
176
|
+
capabilities = (model_config or {}).get("capabilities") if isinstance(model_config, dict) else None
|
|
177
|
+
if not isinstance(capabilities, dict):
|
|
178
|
+
return None
|
|
179
|
+
if not capabilities.get("supported_parameters") and not capabilities.get("input_modalities"):
|
|
180
|
+
return None
|
|
181
|
+
return capabilities
|
|
182
|
+
|
|
183
|
+
@staticmethod
|
|
184
|
+
def _declares(capabilities: dict | None, *parameters: str) -> bool | None:
|
|
185
|
+
"""Whether the model declares any of `parameters`; None when nothing is known."""
|
|
186
|
+
if not capabilities:
|
|
187
|
+
return None
|
|
188
|
+
declared = {str(value).strip().lower() for value in capabilities.get("supported_parameters") or []}
|
|
189
|
+
if not declared:
|
|
190
|
+
return None
|
|
191
|
+
return any(parameter in declared for parameter in parameters)
|
|
192
|
+
|
|
193
|
+
def get_capabilities(self, model: str, provider: str | None = None, capabilities: dict | None = None) -> dict:
|
|
194
|
+
"""What the request may carry for this model.
|
|
195
|
+
|
|
196
|
+
Two halves, both required: what the provider's adapter knows how to send,
|
|
197
|
+
and what the model accepts. The second comes from the model catalogue
|
|
198
|
+
(`capabilities`) when it is known; without it, the provider decides alone.
|
|
199
|
+
The catalogue only ever narrows: a parameter the adapter cannot send is
|
|
200
|
+
never offered because the model would accept it.
|
|
201
|
+
"""
|
|
169
202
|
normalized_provider = self.normalize_provider(provider=provider, model=model)
|
|
170
203
|
# `openai_compatible` is absent on purpose. Its adapter targets any server
|
|
171
204
|
# that speaks chat.completions — llama.cpp, vLLM, a private gateway — and
|
|
172
205
|
# forwards no reasoning field, because one the server does not know earns a
|
|
173
206
|
# 400. Claiming the capability here made the tenant's Models page offer a
|
|
174
207
|
# reasoning control whose value went nowhere.
|
|
175
|
-
|
|
208
|
+
adapter_sends_reasoning = normalized_provider in {
|
|
176
209
|
"openai",
|
|
177
210
|
"xai",
|
|
178
211
|
"openrouter",
|
|
179
212
|
"deepseek",
|
|
180
213
|
}
|
|
181
|
-
|
|
182
|
-
|
|
214
|
+
adapter_sends_verbosity = normalized_provider in {"openai", "xai", "openrouter"}
|
|
215
|
+
|
|
216
|
+
model_reasons = self._declares(capabilities, "reasoning", "reasoning_effort")
|
|
217
|
+
model_takes_verbosity = self._declares(capabilities, "verbosity")
|
|
218
|
+
supports_reasoning_effort = adapter_sends_reasoning and model_reasons is not False
|
|
219
|
+
supports_text_verbosity = adapter_sends_verbosity and model_takes_verbosity is not False
|
|
183
220
|
|
|
184
221
|
return {
|
|
185
222
|
"provider": normalized_provider,
|
|
@@ -187,7 +224,7 @@ class ModelRegistry:
|
|
|
187
224
|
"allowed_reasoning_efforts": list(self._reasoning_effort_options) if supports_reasoning_effort else [],
|
|
188
225
|
"supports_text_verbosity": supports_text_verbosity,
|
|
189
226
|
"allowed_text_verbosity": list(self._text_verbosity_options) if supports_text_verbosity else [],
|
|
190
|
-
"
|
|
227
|
+
"capabilities_source": "catalog" if model_reasons is not None else "provider",
|
|
191
228
|
}
|
|
192
229
|
|
|
193
230
|
def get_request_defaults(self, model: str) -> dict:
|
|
@@ -19,8 +19,9 @@ class OpenAIAdapter:
|
|
|
19
19
|
self.client = openai_client
|
|
20
20
|
|
|
21
21
|
#: Reasoning models whose reasoning can travel between calls as encrypted
|
|
22
|
-
#: items
|
|
23
|
-
#: `include` with a 400.
|
|
22
|
+
#: items, for a model the catalogue does not describe: a model without
|
|
23
|
+
#: reasoning answers the `include` with a 400. When the catalogue knows the
|
|
24
|
+
#: model, the proxy says so (`carries_reasoning`) and this list is not read.
|
|
24
25
|
_ENCRYPTED_REASONING_MODEL_PREFIXES = ("gpt-5", "o1", "o3", "o4")
|
|
25
26
|
|
|
26
27
|
def create_response(self,
|
|
@@ -35,7 +36,8 @@ class OpenAIAdapter:
|
|
|
35
36
|
attachments: Optional[List[Dict]] = None,
|
|
36
37
|
store: Optional[bool] = None,
|
|
37
38
|
metadata: Optional[Dict[str, str]] = None,
|
|
38
|
-
telemetry_execution: Any = None
|
|
39
|
+
telemetry_execution: Any = None,
|
|
40
|
+
carries_reasoning: Optional[bool] = None) -> LLMResponse:
|
|
39
41
|
"""Llamada a la API de OpenAI y mapeo a estructura común.
|
|
40
42
|
|
|
41
43
|
IAToolkit owns the history (BL-009): every call carries the whole
|
|
@@ -62,7 +64,7 @@ class OpenAIAdapter:
|
|
|
62
64
|
|
|
63
65
|
# Nothing stays at OpenAI: the next call sends the history again.
|
|
64
66
|
params['store'] = False
|
|
65
|
-
if self._carries_encrypted_reasoning(model):
|
|
67
|
+
if self._carries_encrypted_reasoning(model, carries_reasoning):
|
|
66
68
|
# Without a stored response the model would lose its reasoning
|
|
67
69
|
# between tool rounds; it comes back encrypted and is sent again.
|
|
68
70
|
params['include'] = ["reasoning.encrypted_content"]
|
|
@@ -93,7 +95,9 @@ class OpenAIAdapter:
|
|
|
93
95
|
raise IAToolkitException(IAToolkitException.ErrorType.LLM_ERROR, error_message)
|
|
94
96
|
|
|
95
97
|
@classmethod
|
|
96
|
-
def _carries_encrypted_reasoning(cls, model: str) -> bool:
|
|
98
|
+
def _carries_encrypted_reasoning(cls, model: str, carries_reasoning: Optional[bool] = None) -> bool:
|
|
99
|
+
if carries_reasoning is not None:
|
|
100
|
+
return carries_reasoning
|
|
97
101
|
name = str(model or "").strip().lower()
|
|
98
102
|
if "-chat" in name:
|
|
99
103
|
return False # gpt-5-chat-latest and the like do not reason
|
|
@@ -160,6 +160,12 @@ class LLMProxy:
|
|
|
160
160
|
provider=provider,
|
|
161
161
|
request_kwargs=request_kwargs,
|
|
162
162
|
)
|
|
163
|
+
request_kwargs = self._apply_model_capabilities(
|
|
164
|
+
model=model,
|
|
165
|
+
provider=provider,
|
|
166
|
+
model_config=model_config,
|
|
167
|
+
request_kwargs=request_kwargs,
|
|
168
|
+
)
|
|
163
169
|
if telemetry_execution is not None:
|
|
164
170
|
request_kwargs["telemetry_execution"] = telemetry_execution
|
|
165
171
|
|
|
@@ -451,6 +457,42 @@ class LLMProxy:
|
|
|
451
457
|
effective_kwargs["reasoning"] = merged_reasoning
|
|
452
458
|
return effective_kwargs
|
|
453
459
|
|
|
460
|
+
def _apply_model_capabilities(
|
|
461
|
+
self,
|
|
462
|
+
model: str,
|
|
463
|
+
provider: str,
|
|
464
|
+
model_config: Dict[str, Any] | None,
|
|
465
|
+
request_kwargs: Dict[str, Any],
|
|
466
|
+
) -> Dict[str, Any]:
|
|
467
|
+
"""Drops the parameters the model itself does not accept (BL-009, Fase F).
|
|
468
|
+
|
|
469
|
+
The steps before this one decide by provider: every OpenAI model gets a
|
|
470
|
+
reasoning effort and a verbosity, which a model that does not reason
|
|
471
|
+
(gpt-4.1, gpt-5-chat) refuses. When the catalogue knows the model, its
|
|
472
|
+
`supported_parameters` have the last word. When it does not, nothing
|
|
473
|
+
changes: the provider's rules stay as they were.
|
|
474
|
+
"""
|
|
475
|
+
catalog_capabilities = ModelRegistry.catalog_capabilities(model_config)
|
|
476
|
+
if catalog_capabilities is None:
|
|
477
|
+
return request_kwargs
|
|
478
|
+
|
|
479
|
+
capabilities = self.model_registry.get_capabilities(
|
|
480
|
+
model, provider=provider, capabilities=catalog_capabilities
|
|
481
|
+
)
|
|
482
|
+
effective_kwargs = dict(request_kwargs or {})
|
|
483
|
+
if not capabilities.get("supports_reasoning_effort"):
|
|
484
|
+
effective_kwargs.pop("reasoning", None)
|
|
485
|
+
effective_kwargs.pop("reasoning_effort", None)
|
|
486
|
+
if not capabilities.get("supports_text_verbosity"):
|
|
487
|
+
text = effective_kwargs.get("text")
|
|
488
|
+
if isinstance(text, dict) and "verbosity" in text:
|
|
489
|
+
effective_kwargs["text"] = {key: value for key, value in text.items() if key != "verbosity"}
|
|
490
|
+
if provider == self.PROVIDER_OPENAI:
|
|
491
|
+
# Whether the model's reasoning can travel between calls: the adapter
|
|
492
|
+
# asks for it only then, instead of guessing from the model's name.
|
|
493
|
+
effective_kwargs["carries_reasoning"] = bool(capabilities.get("supports_reasoning_effort"))
|
|
494
|
+
return effective_kwargs
|
|
495
|
+
|
|
454
496
|
# -------------------------------------------------------------------------
|
|
455
497
|
# Client cache
|
|
456
498
|
# -------------------------------------------------------------------------
|
|
@@ -10,13 +10,10 @@ from typing import Any, Dict, List
|
|
|
10
10
|
import base64
|
|
11
11
|
import logging
|
|
12
12
|
import mimetypes
|
|
13
|
-
import threading
|
|
14
|
-
import time
|
|
15
|
-
|
|
16
|
-
import requests
|
|
17
13
|
|
|
18
14
|
from injector import inject
|
|
19
15
|
|
|
16
|
+
from iatoolkit.common.model_registry import ModelRegistry
|
|
20
17
|
from iatoolkit.services.configuration_service import ConfigurationService
|
|
21
18
|
from iatoolkit.common.util import Utility
|
|
22
19
|
|
|
@@ -30,16 +27,12 @@ class AttachmentPolicyService:
|
|
|
30
27
|
|
|
31
28
|
DEFAULT_MODE = MODE_EXTRACTED_ONLY
|
|
32
29
|
DEFAULT_FALLBACK = FALLBACK_EXTRACT
|
|
33
|
-
OPENROUTER_MODELS_CACHE_TTL_SECONDS = 300
|
|
34
|
-
OPENROUTER_MODELS_TIMEOUT_SECONDS = 8
|
|
35
30
|
|
|
36
31
|
@inject
|
|
37
32
|
def __init__(self, configuration_service: ConfigurationService, util: Utility):
|
|
38
33
|
self.configuration_service = configuration_service
|
|
39
34
|
self.util = util
|
|
40
35
|
self._default_capabilities: dict | None = None
|
|
41
|
-
self._openrouter_models_cache: dict[str, dict[str, Any]] = {}
|
|
42
|
-
self._openrouter_models_cache_lock = threading.Lock()
|
|
43
36
|
self._default_capabilities_path = (
|
|
44
37
|
Path(__file__).resolve().parent.parent / "config" / "llm_capabilities.yaml"
|
|
45
38
|
)
|
|
@@ -72,7 +65,7 @@ class AttachmentPolicyService:
|
|
|
72
65
|
) -> dict:
|
|
73
66
|
mode = self.normalize_mode((policy or {}).get("attachment_mode"))
|
|
74
67
|
fallback = self.normalize_fallback((policy or {}).get("attachment_fallback"))
|
|
75
|
-
capabilities = self.
|
|
68
|
+
capabilities = self.get_effective_capabilities(company_short_name, provider, model)
|
|
76
69
|
|
|
77
70
|
if not files:
|
|
78
71
|
return {
|
|
@@ -102,8 +95,6 @@ class AttachmentPolicyService:
|
|
|
102
95
|
"fallback_to_extract": 0,
|
|
103
96
|
"errors": 0,
|
|
104
97
|
}
|
|
105
|
-
openrouter_native_image_error: str | None = None
|
|
106
|
-
openrouter_native_image_checked = False
|
|
107
98
|
|
|
108
99
|
for file_obj in files:
|
|
109
100
|
stats["total_files"] += 1
|
|
@@ -114,36 +105,17 @@ class AttachmentPolicyService:
|
|
|
114
105
|
wants_native = self._wants_native(mode, meta, capabilities)
|
|
115
106
|
wants_extract = self._wants_extract(mode, meta, capabilities)
|
|
116
107
|
native_ok = False
|
|
117
|
-
native_blocked_by_model_catalog = False
|
|
118
108
|
|
|
119
109
|
if wants_native:
|
|
120
|
-
if
|
|
121
|
-
if not openrouter_native_image_checked:
|
|
122
|
-
openrouter_native_image_error = self._get_openrouter_native_image_error(
|
|
123
|
-
company_short_name=company_short_name,
|
|
124
|
-
model=model,
|
|
125
|
-
)
|
|
126
|
-
openrouter_native_image_checked = True
|
|
127
|
-
if openrouter_native_image_error:
|
|
128
|
-
if fallback == self.FALLBACK_EXTRACT or wants_extract:
|
|
129
|
-
stats["fallback_to_extract"] += 1
|
|
130
|
-
wants_extract = True
|
|
131
|
-
native_blocked_by_model_catalog = True
|
|
132
|
-
else:
|
|
133
|
-
if openrouter_native_image_error not in errors:
|
|
134
|
-
errors.append(openrouter_native_image_error)
|
|
135
|
-
continue
|
|
136
|
-
if (not native_blocked_by_model_catalog) and bool(capabilities.get("supports_native_images")):
|
|
110
|
+
if bool(capabilities.get("supports_native_images")):
|
|
137
111
|
files_for_context.append(dict(file_obj))
|
|
138
112
|
native_ok = True
|
|
139
113
|
stats["native_sent_count"] += 1
|
|
140
|
-
elif
|
|
114
|
+
elif fallback == self.FALLBACK_EXTRACT or wants_extract:
|
|
141
115
|
stats["fallback_to_extract"] += 1
|
|
142
116
|
wants_extract = True
|
|
143
|
-
|
|
144
|
-
errors.append(
|
|
145
|
-
f"Image attachment '{filename}' cannot be sent as native image for provider '{provider}'."
|
|
146
|
-
)
|
|
117
|
+
else:
|
|
118
|
+
errors.append(self._native_image_error(filename, provider, model, capabilities))
|
|
147
119
|
|
|
148
120
|
if wants_extract:
|
|
149
121
|
extract_copy = dict(file_obj)
|
|
@@ -204,6 +176,51 @@ class AttachmentPolicyService:
|
|
|
204
176
|
"stats": stats,
|
|
205
177
|
}
|
|
206
178
|
|
|
179
|
+
def get_effective_capabilities(self, company_short_name: str, provider: str, model: str | None) -> dict:
|
|
180
|
+
"""What can go natively to this model: what the provider's adapter sends, narrowed by the model.
|
|
181
|
+
|
|
182
|
+
The provider half (llm_capabilities.yaml and the company's overrides)
|
|
183
|
+
says what our adapter knows how to send. The model half comes from the
|
|
184
|
+
model catalogue (BL-009, Fase F): `input_modalities` as OpenRouter
|
|
185
|
+
publishes them. Both must hold, so a provider that takes images does not
|
|
186
|
+
make a text-only model take them. A model the catalogue does not know
|
|
187
|
+
keeps the provider's answer.
|
|
188
|
+
"""
|
|
189
|
+
capabilities = dict(self.get_effective_provider_capabilities(company_short_name, provider))
|
|
190
|
+
capabilities["capabilities_source"] = "provider"
|
|
191
|
+
modalities = self._model_input_modalities(company_short_name, model)
|
|
192
|
+
if modalities is None:
|
|
193
|
+
return capabilities
|
|
194
|
+
capabilities["supports_native_images"] = bool(capabilities.get("supports_native_images")) and "image" in modalities
|
|
195
|
+
capabilities["supports_native_files"] = bool(capabilities.get("supports_native_files")) and "file" in modalities
|
|
196
|
+
capabilities["input_modalities"] = sorted(modalities)
|
|
197
|
+
capabilities["capabilities_source"] = "catalog"
|
|
198
|
+
return capabilities
|
|
199
|
+
|
|
200
|
+
def _model_input_modalities(self, company_short_name: str, model: str | None) -> set[str] | None:
|
|
201
|
+
if not model:
|
|
202
|
+
return None
|
|
203
|
+
try:
|
|
204
|
+
model_config = self.configuration_service.get_llm_model_config(company_short_name, model) or {}
|
|
205
|
+
except Exception as e:
|
|
206
|
+
logging.debug("Could not read the configuration of model '%s': %s", model, e)
|
|
207
|
+
return None
|
|
208
|
+
catalog = ModelRegistry.catalog_capabilities(model_config)
|
|
209
|
+
if not catalog or not catalog.get("input_modalities"):
|
|
210
|
+
return None
|
|
211
|
+
return {str(value).strip().lower() for value in catalog["input_modalities"] if str(value or "").strip()}
|
|
212
|
+
|
|
213
|
+
@staticmethod
|
|
214
|
+
def _native_image_error(filename: str, provider: str, model: str | None, capabilities: dict) -> str:
|
|
215
|
+
if capabilities.get("capabilities_source") == "catalog":
|
|
216
|
+
modalities = ", ".join(capabilities.get("input_modalities") or []) or "(none)"
|
|
217
|
+
return (
|
|
218
|
+
f"Image attachment '{filename}' cannot be sent as a native image: the model catalogue "
|
|
219
|
+
f"publishes '{model}' with input modalities {modalities}, without 'image'. "
|
|
220
|
+
"Use a model that takes images, or allow text extraction."
|
|
221
|
+
)
|
|
222
|
+
return f"Image attachment '{filename}' cannot be sent as native image for provider '{provider}'."
|
|
223
|
+
|
|
207
224
|
def get_effective_provider_capabilities(self, company_short_name: str, provider: str) -> dict:
|
|
208
225
|
provider_key = str(provider or "unknown").strip().lower() or "unknown"
|
|
209
226
|
defaults = self._load_default_capabilities().get(provider_key) or self._load_default_capabilities().get("unknown", {})
|
|
@@ -270,104 +287,6 @@ class AttachmentPolicyService:
|
|
|
270
287
|
merged.setdefault("max_files_per_request", 0)
|
|
271
288
|
return merged
|
|
272
289
|
|
|
273
|
-
def _get_openrouter_native_image_error(self, company_short_name: str, model: str | None) -> str | None:
|
|
274
|
-
model_id = str(model or "").strip()
|
|
275
|
-
if not model_id:
|
|
276
|
-
return (
|
|
277
|
-
"Este modelo/provider no expone visión nativa por API: no se resolvio el modelo efectivo "
|
|
278
|
-
"para OpenRouter, por lo que no puedo confirmar soporte de imagenes nativas."
|
|
279
|
-
)
|
|
280
|
-
|
|
281
|
-
model_metadata, verified = self._lookup_openrouter_model_metadata(company_short_name, model_id)
|
|
282
|
-
if not verified:
|
|
283
|
-
return None
|
|
284
|
-
if not isinstance(model_metadata, dict):
|
|
285
|
-
return (
|
|
286
|
-
"Este modelo/provider no expone visión nativa por API verificable: "
|
|
287
|
-
f"OpenRouter no publica metadata para el modelo '{model_id}', por lo que no puedo confirmar "
|
|
288
|
-
"que acepte imagenes nativas."
|
|
289
|
-
)
|
|
290
|
-
|
|
291
|
-
architecture = model_metadata.get("architecture") or {}
|
|
292
|
-
raw_input_modalities = architecture.get("input_modalities") or []
|
|
293
|
-
input_modalities = [
|
|
294
|
-
str(modality or "").strip().lower()
|
|
295
|
-
for modality in raw_input_modalities
|
|
296
|
-
if str(modality or "").strip()
|
|
297
|
-
]
|
|
298
|
-
if "image" in input_modalities:
|
|
299
|
-
return None
|
|
300
|
-
|
|
301
|
-
published_model_id = str(model_metadata.get("id") or model_id).strip() or model_id
|
|
302
|
-
published_modalities = ", ".join(input_modalities) if input_modalities else "(vacio)"
|
|
303
|
-
return (
|
|
304
|
-
"Este modelo/provider no expone visión nativa por API: "
|
|
305
|
-
f"OpenRouter publica el modelo '{published_model_id}' con input_modalities={published_modalities}, "
|
|
306
|
-
"sin 'image'. Para enviar imagenes nativas usa un modelo/provider que publique 'image' "
|
|
307
|
-
"como modalidad de entrada."
|
|
308
|
-
)
|
|
309
|
-
|
|
310
|
-
def _lookup_openrouter_model_metadata(self, company_short_name: str, model: str) -> tuple[dict | None, bool]:
|
|
311
|
-
provider_config = self.configuration_service.get_llm_provider_config(company_short_name, "openrouter") or {}
|
|
312
|
-
base_url = str(provider_config.get("base_url") or "https://openrouter.ai/api/v1").strip()
|
|
313
|
-
models_url = f"{base_url.rstrip('/')}/models"
|
|
314
|
-
catalog = self._get_openrouter_models_catalog(models_url)
|
|
315
|
-
if catalog is None:
|
|
316
|
-
return None, False
|
|
317
|
-
|
|
318
|
-
model_key = str(model or "").strip().lower()
|
|
319
|
-
for item in catalog:
|
|
320
|
-
if not isinstance(item, dict):
|
|
321
|
-
continue
|
|
322
|
-
candidates = {
|
|
323
|
-
str(item.get("id") or "").strip().lower(),
|
|
324
|
-
str(item.get("canonical_slug") or "").strip().lower(),
|
|
325
|
-
}
|
|
326
|
-
candidates.update(
|
|
327
|
-
{
|
|
328
|
-
candidate.split("/")[-1]
|
|
329
|
-
for candidate in list(candidates)
|
|
330
|
-
if candidate and "/" in candidate
|
|
331
|
-
}
|
|
332
|
-
)
|
|
333
|
-
if model_key and model_key in candidates:
|
|
334
|
-
return item, True
|
|
335
|
-
|
|
336
|
-
return None, True
|
|
337
|
-
|
|
338
|
-
def _get_openrouter_models_catalog(self, models_url: str) -> list[dict] | None:
|
|
339
|
-
current_time = time.time()
|
|
340
|
-
with self._openrouter_models_cache_lock:
|
|
341
|
-
cached_entry = self._openrouter_models_cache.get(models_url)
|
|
342
|
-
if cached_entry and (current_time - float(cached_entry.get("fetched_at") or 0)) < self.OPENROUTER_MODELS_CACHE_TTL_SECONDS:
|
|
343
|
-
cached_data = cached_entry.get("data")
|
|
344
|
-
if isinstance(cached_data, list):
|
|
345
|
-
return cached_data
|
|
346
|
-
|
|
347
|
-
try:
|
|
348
|
-
response = requests.get(
|
|
349
|
-
models_url,
|
|
350
|
-
params={"output_modalities": "all"},
|
|
351
|
-
timeout=self.OPENROUTER_MODELS_TIMEOUT_SECONDS,
|
|
352
|
-
headers={"User-Agent": "IAToolkit AttachmentPolicy/1.0"},
|
|
353
|
-
)
|
|
354
|
-
response.raise_for_status()
|
|
355
|
-
payload = response.json()
|
|
356
|
-
catalog = payload.get("data") if isinstance(payload, dict) else None
|
|
357
|
-
if not isinstance(catalog, list):
|
|
358
|
-
logging.warning("OpenRouter models API returned an unexpected payload shape for '%s'.", models_url)
|
|
359
|
-
return None
|
|
360
|
-
except Exception as exc:
|
|
361
|
-
logging.warning("Could not fetch OpenRouter model metadata from '%s': %s", models_url, exc)
|
|
362
|
-
return None
|
|
363
|
-
|
|
364
|
-
with self._openrouter_models_cache_lock:
|
|
365
|
-
self._openrouter_models_cache[models_url] = {
|
|
366
|
-
"fetched_at": current_time,
|
|
367
|
-
"data": catalog,
|
|
368
|
-
}
|
|
369
|
-
return catalog
|
|
370
|
-
|
|
371
290
|
def _normalize_file_meta(self, file_obj: dict) -> dict:
|
|
372
291
|
if not isinstance(file_obj, dict):
|
|
373
292
|
return {"name": "attachment", "payload": "", "mime_type": "application/octet-stream", "is_image": False}
|
|
@@ -1435,7 +1435,11 @@ class ConfigurationService:
|
|
|
1435
1435
|
provider=normalized.get("provider"),
|
|
1436
1436
|
model=model_id,
|
|
1437
1437
|
)
|
|
1438
|
-
capabilities = self.model_registry.get_capabilities(
|
|
1438
|
+
capabilities = self.model_registry.get_capabilities(
|
|
1439
|
+
model_id,
|
|
1440
|
+
provider=provider,
|
|
1441
|
+
capabilities=self.model_registry.catalog_capabilities(normalized),
|
|
1442
|
+
)
|
|
1439
1443
|
descriptor = dict(normalized)
|
|
1440
1444
|
descriptor["id"] = model_id
|
|
1441
1445
|
descriptor["label"] = str(descriptor.get("label") or model_id).strip()
|
|
@@ -250,7 +250,8 @@ class SystemAgentRunner:
|
|
|
250
250
|
ignored, ignored_platform)
|
|
251
251
|
|
|
252
252
|
def supports_images(self, company_short_name: str, model: str | None) -> bool:
|
|
253
|
-
"""Whether the model
|
|
253
|
+
"""Whether the model takes native images: its provider's adapter sends them and,
|
|
254
|
+
when the model catalogue knows it, the model accepts them (BL-009, Fase F)."""
|
|
254
255
|
if not model:
|
|
255
256
|
return False
|
|
256
257
|
try:
|
|
@@ -265,7 +266,7 @@ class SystemAgentRunner:
|
|
|
265
266
|
if self._attachment_policy is None:
|
|
266
267
|
self._attachment_policy = AttachmentPolicyService(self.configuration_service, Utility())
|
|
267
268
|
try:
|
|
268
|
-
capabilities = self._attachment_policy.
|
|
269
|
+
capabilities = self._attachment_policy.get_effective_capabilities(company_short_name, provider, model)
|
|
269
270
|
except Exception as exc:
|
|
270
271
|
logging.warning("Capabilities of provider '%s' could not be read: %s", provider, exc)
|
|
271
272
|
return False
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/interfaces/history_compaction_trigger.py
RENAMED
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/interfaces/memory_compilation_trigger.py
RENAMED
|
File without changes
|
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/interfaces/signup_policy_resolver.py
RENAMED
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/common/interfaces/web_search_provider.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_agents/history_compaction.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_agents/memory_compiler.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_agents/memory_correction.prompt
RENAMED
|
File without changes
|
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_agents/memory_image_ingest.prompt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/chat_state_rules.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/chat_user_profile.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/core_identity.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/email_output.prompt
RENAMED
|
File without changes
|
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/format_styles.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/html_structures.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/links_documents.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/memory_usage.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/multimodal_basics.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/output_basics.prompt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/sql_casting.prompt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/sql_mysql_casting.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.74.0 → iatoolkit-2.74.1}/src/iatoolkit/config/system_prompts/sql_mysql_json.prompt
RENAMED
|
File without changes
|