iatoolkit 2.44.3__tar.gz → 2.45.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.
- {iatoolkit-2.44.3/src/iatoolkit.egg-info → iatoolkit-2.45.0}/PKG-INFO +1 -1
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/__init__.py +1 -1
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/llm_providers/openai_compatible_chat_adapter.py +49 -11
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/llm_providers/openrouter_adapter.py +24 -16
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/llm_proxy.py +36 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/license_service.py +1 -14
- iatoolkit-2.45.0/src/iatoolkit/services/operator_identity_service.py +104 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/profile_service.py +32 -1
- {iatoolkit-2.44.3 → iatoolkit-2.45.0/src/iatoolkit.egg-info}/PKG-INFO +1 -1
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit.egg-info/SOURCES.txt +1 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/LICENSE +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/LICENSE_COMMUNITY.md +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/pyproject.toml +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/readme.md +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/requirements.txt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/setup.cfg +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/base_company.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/cli_commands.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/__init__.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/bridge_validation.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/exceptions.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/interfaces/__init__.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/interfaces/asset_storage.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/interfaces/database_provider.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/interfaces/memory_compilation_trigger.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/interfaces/memory_lint_trigger.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/interfaces/secret_provider.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/interfaces/signup_policy_resolver.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/interfaces/web_search_provider.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/model_registry.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/routes.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/secret_resolver.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/session_manager.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/util.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/company_registry.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/__init__.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/llm_capabilities.yaml +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/channel_business_identity.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/channel_conversation_continuity.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/channel_response_style.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/chat_state_rules.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/chat_user_profile.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/core_identity.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/email_output.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/file_download_output.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/format_styles.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/html_structures.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/links_documents.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/memory_usage.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/multimodal_basics.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/output_basics.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/presentation_formatting.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/query_main.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/sql_aggregation_scope.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/sql_casting.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/sql_core.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/sql_jsonb.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/sql_mysql_casting.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/sql_mysql_json.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/sql_redshift_basics.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/sql_redshift_types.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/sql_rules.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/tool_html_passthrough.prompt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts_pack.yaml +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_tools_pack.yaml +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/core.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/__init__.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/brevo_mail_app.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/call_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/connectors/__init__.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/connectors/file_connector.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/connectors/file_connector_factory.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/connectors/google_cloud_storage_connector.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/connectors/google_drive_connector.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/connectors/local_file_connector.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/connectors/s3_connector.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/google_auth_client.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/google_chat_app.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/inference_embeddings_client.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/inference_handler.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/jina_embeddings_client.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/llm_gateway_resolver.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/llm_providers/__init__.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/llm_providers/anthropic_adapter.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/llm_providers/deepseek_adapter.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/llm_providers/gemini_adapter.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/llm_providers/openai_adapter.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/llm_response.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/redis_session_manager.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/locales/en.yaml +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/locales/es.yaml +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/__init__.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/api_key_repo.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/bridge_repo.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/database_manager.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/document_repo.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/env_secret_provider.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/filesystem_asset_repository.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/knowledge_wiki_repo.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/llm_query_repo.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/mcp_token_repo.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/memory_repo.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/models.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/profile_repo.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/prompt_resource_repo.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/sql_dataset_repo.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/sql_source_repo.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/repositories/vs_repo.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/runtime_logging.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/__init__.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/api_key_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/attachment_policy_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/auth_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/benchmark_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/branding_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/company_context_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/configuration_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/context_builder_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/dispatcher_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/embedding_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/excel_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/file_processor_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/history_manager_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/http_tool_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/i18n_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/inference_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/jwt_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/knowledge_base_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/language_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/llm_client_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/mail_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/markdown_wiki_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/mcp_token_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/memory_compiler_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/memory_lint_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/memory_lookup_policy_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/memory_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/memory_wiki_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/noop_memory_compilation_trigger.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/noop_memory_lint_trigger.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/parsers/__init__.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/parsers/contracts.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/parsers/image_normalizer.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/parsers/parsing_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/parsers/pdf_ocr_detection.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/parsers/provider_factory.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/parsers/provider_resolver.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/parsers/providers/__init__.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/parsers/providers/basic_provider.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/parsers/providers/docling_provider.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/parsers/validator.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/pdf_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/prompt_resource_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/prompt_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/query_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/signup_policy_resolver.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/sql_dataset_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/sql_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/sql_source_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/storage_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/structured_output_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/system_prompt_catalog.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/system_tools.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/telemetry_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/tenant_wiki_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/tool_output_contract.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/tool_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/user_feedback_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/user_session_context_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/visual_kb_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/visual_tool_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/warmup_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/web_search/__init__.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/web_search/provider_factory.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/web_search/providers/__init__.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/web_search/providers/brave_provider.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/services/web_search_service.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/images/fernando.jpeg +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/images/iatoolkit_core.png +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/images/iatoolkit_logo.png +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/js/chat_feedback_button.js +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/js/chat_filepond.js +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/js/chat_help_content.js +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/js/chat_history_button.js +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/js/chat_logout_button.js +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/js/chat_main.js +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/js/chat_memory_button.js +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/js/chat_model_selector.js +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/js/chat_onboarding_button.js +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/js/chat_prompt_manager.js +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/js/chat_reload_button.js +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/styles/chat_iatoolkit.css +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/styles/chat_modal.css +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/styles/chat_public.css +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/styles/documents.css +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/styles/landing_page.css +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/styles/llm_output.css +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/static/styles/onboarding.css +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/_company_header.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/_login_widget.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/account.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/base.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/change_password.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/chat.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/chat_memory_modal.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/chat_modals.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/error.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/forgot_password.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/home_hosted_default.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/memory/wiki_schema.md +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/onboarding_shell.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/pdf/base.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/pdf/letter.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/pdf/report.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/pdf/simple.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/templates/signup.html +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/__init__.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/account_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/api_key_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/base_login_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/categories_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/change_password_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/chat_context_preview_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/chat_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/configuration_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/connectors_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/embedding_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/forgot_password_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/help_content_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/history_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/home_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/init_context_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/llmquery_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/load_document_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/login_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/logout_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/memory_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/profile_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/prompt_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/prompt_context_preview_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/prompt_resource_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/rag_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/root_redirect_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/signup_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/static_page_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/tool_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/user_feedback_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/users_api_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/views/verify_user_view.py +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit.egg-info/dependency_links.txt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit.egg-info/requires.txt +0 -0
- {iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit.egg-info/top_level.txt +0 -0
|
@@ -8,8 +8,11 @@ import json
|
|
|
8
8
|
import logging
|
|
9
9
|
import mimetypes
|
|
10
10
|
import threading
|
|
11
|
+
import time
|
|
11
12
|
from typing import Any, Dict, List, Optional
|
|
12
13
|
|
|
14
|
+
import openai
|
|
15
|
+
|
|
13
16
|
from iatoolkit.common.exceptions import IAToolkitException
|
|
14
17
|
from iatoolkit.infra.llm_response import LLMResponse, ToolCall, Usage
|
|
15
18
|
|
|
@@ -45,6 +48,16 @@ class OpenAICompatibleChatAdapter:
|
|
|
45
48
|
supports_thinking = False
|
|
46
49
|
allow_follow_up_tool_calls = True
|
|
47
50
|
|
|
51
|
+
#: `LLMProxy` builds every client with `max_retries=0` by default (see
|
|
52
|
+
#: `LLMProxy.DEFAULT_MAX_RETRIES`), so a bare transport failure - DNS,
|
|
53
|
+
#: TCP reset, TLS handshake - was previously only recovered by the RQ-level
|
|
54
|
+
#: task retry: 10s+ of wait, a full job re-run, and the earlier attempt's
|
|
55
|
+
#: error dropped (see `TaskService._record_task_retry_attempt`). Retrying a
|
|
56
|
+
#: handful of times here, right where the failure happens, recovers the
|
|
57
|
+
#: common "connection error, works on the 2nd try" case in ~1-2s instead.
|
|
58
|
+
_CONNECTION_ERROR_MAX_ATTEMPTS = 3
|
|
59
|
+
_CONNECTION_ERROR_RETRY_DELAY_SECONDS = 0.75
|
|
60
|
+
|
|
48
61
|
def __init__(self, openai_compatible_client, provider_label: str = "OpenAI-compatible"):
|
|
49
62
|
self.client = openai_compatible_client
|
|
50
63
|
self.provider_label = provider_label
|
|
@@ -168,19 +181,44 @@ class OpenAICompatibleChatAdapter:
|
|
|
168
181
|
_ = kwargs
|
|
169
182
|
|
|
170
183
|
def _create_chat_completion(self, call_kwargs: Dict[str, Any]) -> Any:
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
184
|
+
attempt = 1
|
|
185
|
+
while True:
|
|
186
|
+
try:
|
|
187
|
+
return self.client.chat.completions.create(**call_kwargs)
|
|
188
|
+
except openai.APITimeoutError:
|
|
189
|
+
# A read/write timeout means the request may already be running
|
|
190
|
+
# upstream (a long generation just took its time) - resending it
|
|
191
|
+
# would risk paying for the same generation twice with no
|
|
192
|
+
# guarantee the retry is any faster. Let the RQ-level task retry
|
|
193
|
+
# handle this one instead of looping on it here.
|
|
176
194
|
raise
|
|
195
|
+
except openai.APIConnectionError as ex:
|
|
196
|
+
# A transport-level failure (DNS, TCP reset, TLS handshake) happens
|
|
197
|
+
# before the request reaches the provider, so retrying is safe and
|
|
198
|
+
# cheap - unlike APITimeoutError above, there's no ambiguity about
|
|
199
|
+
# whether the provider already started working on this request.
|
|
200
|
+
if attempt >= self._CONNECTION_ERROR_MAX_ATTEMPTS:
|
|
201
|
+
raise
|
|
202
|
+
logging.warning(
|
|
203
|
+
"[%sAdapter] Connection error calling provider (attempt %s/%s); retrying: %s",
|
|
204
|
+
self.provider_label,
|
|
205
|
+
attempt,
|
|
206
|
+
self._CONNECTION_ERROR_MAX_ATTEMPTS,
|
|
207
|
+
ex,
|
|
208
|
+
)
|
|
209
|
+
time.sleep(self._CONNECTION_ERROR_RETRY_DELAY_SECONDS)
|
|
210
|
+
attempt += 1
|
|
211
|
+
except Exception as ex:
|
|
212
|
+
retry_call_kwargs = self._build_retry_without_tool_choice_kwargs(call_kwargs, ex)
|
|
213
|
+
if retry_call_kwargs is None:
|
|
214
|
+
raise
|
|
177
215
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
216
|
+
logging.warning(
|
|
217
|
+
"[%sAdapter] Provider rejected tool_choice for model '%s'; retrying without tool_choice.",
|
|
218
|
+
self.provider_label,
|
|
219
|
+
call_kwargs.get("model"),
|
|
220
|
+
)
|
|
221
|
+
return self.client.chat.completions.create(**retry_call_kwargs)
|
|
184
222
|
|
|
185
223
|
@staticmethod
|
|
186
224
|
def _build_retry_without_tool_choice_kwargs(
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/llm_providers/openrouter_adapter.py
RENAMED
|
@@ -16,22 +16,21 @@ class OpenRouterAdapter(OpenAICompatibleChatAdapter):
|
|
|
16
16
|
supports_metadata = True
|
|
17
17
|
supports_parallel_tool_calls = True
|
|
18
18
|
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
# through OpenRouter's own `file-parser` plugin sidesteps that per-model gap
|
|
25
|
-
# instead of trying to track which routed model does or doesn't accept PDFs.
|
|
26
|
-
#
|
|
27
|
-
# engine="native": let the routed model read the PDF with its own
|
|
28
|
-
# multimodal capability, falling back to OpenRouter's own extraction only
|
|
29
|
-
# when the model doesn't support that. engine="mistral-ocr" used to be the
|
|
30
|
-
# default here, but it forces every PDF - regardless of model support -
|
|
31
|
-
# through OpenRouter's shared OCR pipeline, which is what produced the
|
|
32
|
-
# "document parsing engine is currently rate limited" failures.
|
|
19
|
+
# Fixed at "native" by policy: a PDF attachment must reach the routed model
|
|
20
|
+
# as-is, for it to read with its own vision/multimodal capability - never
|
|
21
|
+
# silently rewritten into extracted text by OpenRouter's OCR/parsing
|
|
22
|
+
# pipeline. This only applies when nothing else already requested a plugin
|
|
23
|
+
# (see _extend_call_kwargs below); an explicit `plugins` kwarg always wins.
|
|
33
24
|
_PDF_FILE_PARSER_PLUGIN = [{"id": "file-parser", "pdf": {"engine": "native"}}]
|
|
34
25
|
|
|
26
|
+
# Providers observed returning HTTP 400 on `type: "file"` content parts
|
|
27
|
+
# even when routed to a model whose aggregate catalog entry lists "file"
|
|
28
|
+
# as a supported input modality (OpenRouter's per-endpoint support lags
|
|
29
|
+
# the model-level declaration). Excluded via `provider.ignore` whenever
|
|
30
|
+
# we send a native file attachment, so routing skips them instead of
|
|
31
|
+
# failing the request.
|
|
32
|
+
_FILE_UNSUPPORTED_PROVIDERS = ("parasail", "akashml", "alibaba", "chutes", "reka")
|
|
33
|
+
|
|
35
34
|
def __init__(self, openrouter_client):
|
|
36
35
|
super().__init__(openai_compatible_client=openrouter_client, provider_label="OpenRouter")
|
|
37
36
|
|
|
@@ -74,8 +73,17 @@ class OpenRouterAdapter(OpenAICompatibleChatAdapter):
|
|
|
74
73
|
if kwargs.get(key) is not None:
|
|
75
74
|
extra_body[key] = kwargs.get(key)
|
|
76
75
|
|
|
77
|
-
if
|
|
78
|
-
|
|
76
|
+
if self._has_pdf_attachment(kwargs.get("attachments")):
|
|
77
|
+
if "plugins" not in extra_body:
|
|
78
|
+
extra_body["plugins"] = self._PDF_FILE_PARSER_PLUGIN
|
|
79
|
+
|
|
80
|
+
provider_opts = dict(extra_body.get("provider") or {})
|
|
81
|
+
ignore = list(provider_opts.get("ignore") or [])
|
|
82
|
+
for provider_slug in self._FILE_UNSUPPORTED_PROVIDERS:
|
|
83
|
+
if provider_slug not in ignore:
|
|
84
|
+
ignore.append(provider_slug)
|
|
85
|
+
provider_opts["ignore"] = ignore
|
|
86
|
+
extra_body["provider"] = provider_opts
|
|
79
87
|
|
|
80
88
|
if extra_body:
|
|
81
89
|
call_kwargs["extra_body"] = extra_body
|
|
@@ -132,6 +132,11 @@ class LLMProxy:
|
|
|
132
132
|
model_config=model_config,
|
|
133
133
|
request_kwargs=request_kwargs,
|
|
134
134
|
)
|
|
135
|
+
request_kwargs = self._apply_provider_default_routing(
|
|
136
|
+
provider=provider,
|
|
137
|
+
provider_config=provider_config,
|
|
138
|
+
request_kwargs=request_kwargs,
|
|
139
|
+
)
|
|
135
140
|
request_kwargs = self._apply_company_request_defaults(
|
|
136
141
|
company_short_name=company_short_name,
|
|
137
142
|
model=model,
|
|
@@ -330,6 +335,37 @@ class LLMProxy:
|
|
|
330
335
|
|
|
331
336
|
return effective_kwargs
|
|
332
337
|
|
|
338
|
+
def _apply_provider_default_routing(
|
|
339
|
+
self,
|
|
340
|
+
provider: str,
|
|
341
|
+
provider_config: Dict[str, Any],
|
|
342
|
+
request_kwargs: Dict[str, Any],
|
|
343
|
+
) -> Dict[str, Any]:
|
|
344
|
+
"""
|
|
345
|
+
Company-wide OpenRouter routing default, configured once under
|
|
346
|
+
`llm.openrouter.routing` instead of repeated on every model.
|
|
347
|
+
Applied after model-level routing so precedence stays
|
|
348
|
+
caller-explicit > per-model routing > this provider-wide default.
|
|
349
|
+
"""
|
|
350
|
+
effective_kwargs = dict(request_kwargs or {})
|
|
351
|
+
|
|
352
|
+
if provider != self.PROVIDER_OPENROUTER or not isinstance(provider_config, dict):
|
|
353
|
+
return effective_kwargs
|
|
354
|
+
|
|
355
|
+
default_routing = provider_config.get("routing")
|
|
356
|
+
if not isinstance(default_routing, dict) or not default_routing:
|
|
357
|
+
return effective_kwargs
|
|
358
|
+
|
|
359
|
+
existing_provider = effective_kwargs.get("provider")
|
|
360
|
+
if isinstance(existing_provider, dict):
|
|
361
|
+
merged_provider = dict(default_routing)
|
|
362
|
+
merged_provider.update(existing_provider)
|
|
363
|
+
effective_kwargs["provider"] = merged_provider
|
|
364
|
+
elif existing_provider is None:
|
|
365
|
+
effective_kwargs["provider"] = dict(default_routing)
|
|
366
|
+
|
|
367
|
+
return effective_kwargs
|
|
368
|
+
|
|
333
369
|
def _apply_company_request_defaults(
|
|
334
370
|
self,
|
|
335
371
|
company_short_name: str,
|
|
@@ -27,7 +27,6 @@ class LicenseService:
|
|
|
27
27
|
"license_type": "Community Edition",
|
|
28
28
|
"plan": "Open Source (Community Edition)",
|
|
29
29
|
"max_companies": 1,
|
|
30
|
-
"max_tools": 3,
|
|
31
30
|
"features": {
|
|
32
31
|
"multi_tenant": False,
|
|
33
32
|
"rag_advanced": False,
|
|
@@ -46,11 +45,8 @@ class LicenseService:
|
|
|
46
45
|
def get_max_companies(self) -> int:
|
|
47
46
|
return self.limits.get("max_companies", 1)
|
|
48
47
|
|
|
49
|
-
def get_max_tools_per_company(self) -> int:
|
|
50
|
-
return self.limits.get("max_tools", 3)
|
|
51
|
-
|
|
52
48
|
def get_license_info(self) -> str:
|
|
53
|
-
return f"Plan: {self.get_plan_name()}, Companies: {self.get_max_companies()}
|
|
49
|
+
return f"Plan: {self.get_plan_name()}, Companies: {self.get_max_companies()}"
|
|
54
50
|
|
|
55
51
|
# --- Restriction Validators ---
|
|
56
52
|
|
|
@@ -65,15 +61,6 @@ class LicenseService:
|
|
|
65
61
|
)
|
|
66
62
|
|
|
67
63
|
|
|
68
|
-
def validate_tool_config_limit(self, tools_config: list):
|
|
69
|
-
"""Validates a configuration list before processing it."""
|
|
70
|
-
limit = self.get_max_tools_per_company()
|
|
71
|
-
if limit != -1 and len(tools_config) > limit:
|
|
72
|
-
raise IAToolkitException(
|
|
73
|
-
IAToolkitException.ErrorType.PERMISSION,
|
|
74
|
-
f"Configuration defines {len(tools_config)} tools, but limit is {limit}."
|
|
75
|
-
)
|
|
76
|
-
|
|
77
64
|
# --- Feature Gating Validators ---
|
|
78
65
|
|
|
79
66
|
def has_feature(self, feature_key: str) -> bool:
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Copyright (c) 2024 Fernando Libedinsky
|
|
2
|
+
# Product: IAToolkit
|
|
3
|
+
#
|
|
4
|
+
# IAToolkit is open source software.
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
from injector import inject, singleton
|
|
10
|
+
|
|
11
|
+
from iatoolkit.common.exceptions import IAToolkitException
|
|
12
|
+
from iatoolkit.repositories.profile_repo import ProfileRepo
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@singleton
|
|
16
|
+
class OperatorIdentityService:
|
|
17
|
+
"""Which company operates this deployment.
|
|
18
|
+
|
|
19
|
+
One question that four places used to answer with the same typed string: where
|
|
20
|
+
the operator's own accounts live, which company you must be signed into to
|
|
21
|
+
reach the control center, whose portfolio the console lists, and — the one that
|
|
22
|
+
handles money — whose merchant account collects invoices.
|
|
23
|
+
|
|
24
|
+
Lives in the core because the core, Enterprise and the website all ask it, and
|
|
25
|
+
a rule restated in three repositories drifts. Same reason ``ServiceModel`` is
|
|
26
|
+
here.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
#: The name this deployment used before the question was a setting. Kept as a
|
|
30
|
+
#: fallback so nothing has to be configured here, but only honoured when the
|
|
31
|
+
#: company actually exists: on any other deployment the name is meaningless,
|
|
32
|
+
#: and silently accepting it is what made a monthly close resolve the payment
|
|
33
|
+
#: configuration of a company that was not there and mark every invoice failed.
|
|
34
|
+
LEGACY_COMPANY_SHORT_NAME = "iat_store"
|
|
35
|
+
|
|
36
|
+
#: In order. The second name predates this service and is honoured by the
|
|
37
|
+
#: Stripe webhook, so a deployment that already set it keeps working without
|
|
38
|
+
#: being asked to set a second variable for the same fact.
|
|
39
|
+
SETTING_NAMES = ("IAT_OPERATOR_COMPANY", "IAT_BILLING_COMPANY_SHORT_NAME")
|
|
40
|
+
SETTING_NAME = SETTING_NAMES[0]
|
|
41
|
+
|
|
42
|
+
@classmethod
|
|
43
|
+
def stated_name(cls) -> str:
|
|
44
|
+
"""What this deployment calls its operator, without checking it exists.
|
|
45
|
+
|
|
46
|
+
For callers with no database at hand. The verification belongs on the
|
|
47
|
+
money path — see ``company_short_name`` — and skipping it here is safe
|
|
48
|
+
because those callers fail in the open: a company that does not exist
|
|
49
|
+
cannot authenticate anyone and holds no payment configuration.
|
|
50
|
+
"""
|
|
51
|
+
for setting in cls.SETTING_NAMES:
|
|
52
|
+
value = (os.getenv(setting) or "").strip().lower()
|
|
53
|
+
if value:
|
|
54
|
+
return value
|
|
55
|
+
return cls.LEGACY_COMPANY_SHORT_NAME
|
|
56
|
+
|
|
57
|
+
@inject
|
|
58
|
+
def __init__(self, profile_repo: ProfileRepo):
|
|
59
|
+
self.profile_repo = profile_repo
|
|
60
|
+
self._resolved: str | None = None
|
|
61
|
+
|
|
62
|
+
def company_short_name(self) -> str:
|
|
63
|
+
"""The operator company, resolved once per process.
|
|
64
|
+
|
|
65
|
+
Cached because the answer cannot change without a deployment, and this is
|
|
66
|
+
read on paths that run per request and per invoice.
|
|
67
|
+
"""
|
|
68
|
+
if self._resolved:
|
|
69
|
+
return self._resolved
|
|
70
|
+
|
|
71
|
+
for setting in self.SETTING_NAMES:
|
|
72
|
+
configured = (os.getenv(setting) or "").strip().lower()
|
|
73
|
+
if configured:
|
|
74
|
+
self._resolved = configured
|
|
75
|
+
logging.info("Operator company: '%s' (from %s).", configured, setting)
|
|
76
|
+
return self._resolved
|
|
77
|
+
|
|
78
|
+
if self._company_exists(self.LEGACY_COMPANY_SHORT_NAME):
|
|
79
|
+
self._resolved = self.LEGACY_COMPANY_SHORT_NAME
|
|
80
|
+
logging.info(
|
|
81
|
+
"Operator company: '%s' (default). Set %s to name it explicitly.",
|
|
82
|
+
self._resolved,
|
|
83
|
+
self.SETTING_NAME,
|
|
84
|
+
)
|
|
85
|
+
return self._resolved
|
|
86
|
+
|
|
87
|
+
# Deliberately loud. The alternative is what used to happen: a name from
|
|
88
|
+
# another deployment travels down to the payment configuration and the
|
|
89
|
+
# close writes failed invoices, which reads as a collection problem.
|
|
90
|
+
raise IAToolkitException(
|
|
91
|
+
IAToolkitException.ErrorType.CONFIG_ERROR,
|
|
92
|
+
f"This deployment has no operator company. Set {self.SETTING_NAME} to the "
|
|
93
|
+
f"short name of the company that operates it (there is no "
|
|
94
|
+
f"'{self.LEGACY_COMPANY_SHORT_NAME}' company in this database).",
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
def _company_exists(self, short_name: str) -> bool:
|
|
98
|
+
try:
|
|
99
|
+
return self.profile_repo.get_company_by_short_name(short_name) is not None
|
|
100
|
+
except Exception as exc:
|
|
101
|
+
# Unreadable is not the same as absent, and guessing either way here is
|
|
102
|
+
# worse than saying so: the caller gets the explicit error below.
|
|
103
|
+
logging.warning("Could not check whether company '%s' exists: %s", short_name, exc)
|
|
104
|
+
return False
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
from injector import inject
|
|
7
7
|
from iatoolkit.repositories.profile_repo import ProfileRepo
|
|
8
8
|
from iatoolkit.services.i18n_service import I18nService
|
|
9
|
-
from iatoolkit.repositories.models import User, Company
|
|
9
|
+
from iatoolkit.repositories.models import User, Company, user_company
|
|
10
10
|
from flask_bcrypt import check_password_hash
|
|
11
11
|
from flask import request, has_request_context
|
|
12
12
|
from iatoolkit.common.session_manager import SessionManager
|
|
@@ -24,6 +24,7 @@ import logging
|
|
|
24
24
|
from html import escape
|
|
25
25
|
from datetime import datetime
|
|
26
26
|
from typing import List, Dict
|
|
27
|
+
from sqlalchemy import update
|
|
27
28
|
from iatoolkit.common.interfaces.signup_policy_resolver import SignupPolicyResolver
|
|
28
29
|
from iatoolkit.services.signup_policy_resolver import AllowAllSignupPolicyResolver
|
|
29
30
|
|
|
@@ -71,6 +72,10 @@ class ProfileService:
|
|
|
71
72
|
text = fallback
|
|
72
73
|
return text.lower()
|
|
73
74
|
|
|
75
|
+
@staticmethod
|
|
76
|
+
def _normalize_email_value(email: str | None) -> str:
|
|
77
|
+
return str(email or "").strip().lower()
|
|
78
|
+
|
|
74
79
|
def _resolve_google_names(self, email: str, google_identity: GoogleIdentity) -> tuple[str, str]:
|
|
75
80
|
given_name = str(google_identity.given_name or "").strip()
|
|
76
81
|
family_name = str(google_identity.family_name or "").strip()
|
|
@@ -116,6 +121,30 @@ class ProfileService:
|
|
|
116
121
|
'message': 'Login ok',
|
|
117
122
|
}
|
|
118
123
|
|
|
124
|
+
def _promote_bootstrap_owner_if_needed(self, company: Company, user: User) -> None:
|
|
125
|
+
params = company.parameters if isinstance(company.parameters, dict) else {}
|
|
126
|
+
pending_admin_email = self._normalize_email_value(params.get("bootstrap_admin_email"))
|
|
127
|
+
user_email = self._normalize_email_value(getattr(user, "email", ""))
|
|
128
|
+
|
|
129
|
+
if not pending_admin_email or pending_admin_email != user_email:
|
|
130
|
+
return
|
|
131
|
+
|
|
132
|
+
self.profile_repo.session.execute(
|
|
133
|
+
update(user_company)
|
|
134
|
+
.where(
|
|
135
|
+
user_company.c.user_id == user.id,
|
|
136
|
+
user_company.c.company_id == company.id,
|
|
137
|
+
)
|
|
138
|
+
.values(role="admin")
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
updated_params = dict(params)
|
|
142
|
+
updated_params.pop("bootstrap_admin_email", None)
|
|
143
|
+
updated_params["workspace_owner_email"] = user_email
|
|
144
|
+
company.parameters = updated_params
|
|
145
|
+
self.profile_repo.session.add(company)
|
|
146
|
+
self.profile_repo.session.commit()
|
|
147
|
+
|
|
119
148
|
def _link_user_to_google(self, user: User, google_identity: GoogleIdentity):
|
|
120
149
|
user.auth_method = 'google'
|
|
121
150
|
user.google_sub = google_identity.subject
|
|
@@ -574,6 +603,7 @@ class ProfileService:
|
|
|
574
603
|
# add new company to existing user
|
|
575
604
|
existing_user.companies.append(company)
|
|
576
605
|
self.profile_repo.save_user(existing_user)
|
|
606
|
+
self._promote_bootstrap_owner_if_needed(company, existing_user)
|
|
577
607
|
return {"message": self.i18n_service.t('flash_messages.user_associated_success')}
|
|
578
608
|
|
|
579
609
|
# add the new user
|
|
@@ -610,6 +640,7 @@ class ProfileService:
|
|
|
610
640
|
|
|
611
641
|
# and create in the database
|
|
612
642
|
self.profile_repo.create_user(new_user)
|
|
643
|
+
self._promote_bootstrap_owner_if_needed(company, new_user)
|
|
613
644
|
|
|
614
645
|
# send email with verification
|
|
615
646
|
if not cfg or cfg.get('verify_account', True):
|
|
@@ -137,6 +137,7 @@ src/iatoolkit/services/memory_service.py
|
|
|
137
137
|
src/iatoolkit/services/memory_wiki_service.py
|
|
138
138
|
src/iatoolkit/services/noop_memory_compilation_trigger.py
|
|
139
139
|
src/iatoolkit/services/noop_memory_lint_trigger.py
|
|
140
|
+
src/iatoolkit/services/operator_identity_service.py
|
|
140
141
|
src/iatoolkit/services/pdf_service.py
|
|
141
142
|
src/iatoolkit/services/profile_service.py
|
|
142
143
|
src/iatoolkit/services/prompt_resource_service.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
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.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/interfaces/memory_compilation_trigger.py
RENAMED
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/interfaces/memory_lint_trigger.py
RENAMED
|
File without changes
|
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/common/interfaces/signup_policy_resolver.py
RENAMED
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/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.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/chat_state_rules.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/chat_user_profile.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/core_identity.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/email_output.prompt
RENAMED
|
File without changes
|
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/format_styles.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/html_structures.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/links_documents.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/memory_usage.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/multimodal_basics.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/output_basics.prompt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/sql_casting.prompt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/sql_mysql_casting.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/sql_mysql_json.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/sql_redshift_basics.prompt
RENAMED
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/config/system_prompts/sql_redshift_types.prompt
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
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/connectors/file_connector_factory.py
RENAMED
|
File without changes
|
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/connectors/google_drive_connector.py
RENAMED
|
File without changes
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/connectors/local_file_connector.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
|
{iatoolkit-2.44.3 → iatoolkit-2.45.0}/src/iatoolkit/infra/llm_providers/anthropic_adapter.py
RENAMED
|
File without changes
|