databricks-tellr-app 0.4.3.dev1__tar.gz → 0.4.3.dev2__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.
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/PKG-INFO +1 -1
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/databricks_tellr_app.egg-info/PKG-INFO +1 -1
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/pyproject.toml +1 -1
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/middleware/security_headers.py +22 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/images.py +27 -45
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/requests.py +2 -2
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/services/chat_service.py +9 -12
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/database.py +0 -40
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/image.py +1 -15
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/image_service.py +9 -9
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/image_tools.py +2 -2
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/image_utils.py +4 -5
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/README.md +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/databricks_tellr_app/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/databricks_tellr_app/run.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/databricks_tellr_app.egg-info/SOURCES.txt +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/databricks_tellr_app.egg-info/dependency_links.txt +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/databricks_tellr_app.egg-info/requires.txt +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/databricks_tellr_app.egg-info/top_level.txt +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/setup.cfg +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/setup.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/_otel_bootstrap.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/fixtures/tour_demo_deck.json +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/main.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/mcp_auth.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/mcp_server.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/middleware/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/middleware/csrf.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/middleware/request_logging.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/_authz.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/admin.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/admin_usage.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/agent_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/chat.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/deck_contributors.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/export.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/feedback.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/google_slides.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/local_version.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/profiles.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/sessions.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/settings/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/settings/contributors.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/settings/deck_prompts.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/settings/design_systems.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/settings/identities.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/settings/slide_styles.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/setup.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/slides.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/tools.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/tour.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/verification.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/version.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/agent_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/feedback.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/responses.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/settings/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/settings/requests.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/settings/responses.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/streaming.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/services/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/services/export_job_queue.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/services/feedback_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/services/job_queue.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/services/session_manager.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/services/session_naming.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/services/usage_events.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/services/usage_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/utils/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/utils/validation.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/config_loader.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/context_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/databricks_client.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/defaults.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/encryption.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/init_default_profile.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/lakebase.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/migrate_profiles_to_agent_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/mlflow_agent_spans.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/mlflow_tracing.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/otel_logging.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/permission_context.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/prompt_modules.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/settings_db.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/user_context.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/deck_contributor.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/design_system.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/encryption_key.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/feedback.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/genie_space.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/google_global_credentials.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/google_oauth_token.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/identity.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/profile.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/profile_contributor.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/prompts.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/request_log.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/session.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/slide_deck_prompt.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/slide_style_library.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/usage_event.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/user_preference.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/types.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/domain/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/domain/slide.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/domain/slide_deck.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/agent.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/agent_factory.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/config_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/config_validator.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/converter_jail/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/converter_jail/ast_guard.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/converter_jail/codeprep.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/converter_jail/gslides_runner.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/converter_jail/jail.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/converter_jail/pptx_runner.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/converter_jail/protocol.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/design_system_compiler.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/design_system_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/design_system_templates.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/drive_uploader.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/evaluation/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/evaluation/llm_judge.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/genie_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/google_slides_auth.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/google_slides_prompts_defaults.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/html_to_google_slides.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/html_to_pptx.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/identity_provider.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/identity_providers/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/identity_providers/account_provider.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/identity_providers/local_provider.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/identity_providers/workspace_provider.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/permission_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/pptx_from_html_huashu.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/pptx_from_records.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/pptx_prompts_defaults.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/profile_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/streaming_callback.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/tools/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/tools/agent_bricks_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/tools/ds_asset_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/tools/genie_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/tools/mcp_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/tools/model_endpoint_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/tools/vector_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/validator.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/css_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/ds_asset_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/error_handling.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/html_safety.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/html_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/js_validator.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/logging_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/pi_filter.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/slide_hash.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/spotlight.py +0 -0
- {databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/text_caps.py +0 -0
|
@@ -31,6 +31,28 @@ Content-Security-Policy differentiated by response type:
|
|
|
31
31
|
'none', no eval) plus the html_safety.py scanner, and any header at
|
|
32
32
|
all is a strict improvement over the previous no-CSP state.
|
|
33
33
|
|
|
34
|
+
SDR-4437 M-CSP — ACCEPTED RESIDUAL (pending SE sign-off). M-CSP asks
|
|
35
|
+
to move ``script-src`` off ``'unsafe-inline'`` to hashes/nonces. That
|
|
36
|
+
is infeasible here and was verified:
|
|
37
|
+
* The SPA's own document has NO inline <script> — index.html loads a
|
|
38
|
+
single external module (``/src/main.tsx``), already covered by
|
|
39
|
+
``'self'``. So the SPA itself does not need 'unsafe-inline'.
|
|
40
|
+
* The 'unsafe-inline' exists ONLY for the srcdoc slide iframes, whose
|
|
41
|
+
generated HTML contains arbitrary inline <script> (Chart.js init,
|
|
42
|
+
etc.) and which inherit THIS document policy in addition to their
|
|
43
|
+
own SLIDE_CSP meta (both enforce; most restrictive wins).
|
|
44
|
+
* Per CSP2+, adding any nonce or hash to ``script-src`` makes the
|
|
45
|
+
browser IGNORE 'unsafe-inline'. A nonce on the parent would
|
|
46
|
+
therefore disable inline execution for the inherited srcdoc slide
|
|
47
|
+
scripts and break slide rendering app-wide — you cannot have
|
|
48
|
+
"nonce + unsafe-inline" both take effect.
|
|
49
|
+
Removing it would require re-architecting slides away from srcdoc
|
|
50
|
+
(backend-served ``src`` iframes), which the frame-ancestors / no-src
|
|
51
|
+
design above deliberately avoids. The residual is bounded: slides stay
|
|
52
|
+
confined by SLIDE_CSP (an egress boundary) + the html_safety scanner,
|
|
53
|
+
and the DOCUMENT_CSP ⊇ SLIDE_CSP superset invariant is locked by
|
|
54
|
+
tests/unit/test_export_csp.py::test_document_csp_header_is_superset_of_slide_csp.
|
|
55
|
+
|
|
34
56
|
- Everything else (JSON APIs, assets, SSE) gets the deny-all
|
|
35
57
|
``API_CSP`` — nothing executes in a JSON response.
|
|
36
58
|
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/images.py
RENAMED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"""Image upload and management API endpoints."""
|
|
2
|
-
import base64
|
|
3
2
|
import logging
|
|
4
3
|
import os
|
|
5
4
|
from typing import List, Optional
|
|
@@ -21,7 +20,7 @@ router = APIRouter(prefix="/api/images", tags=["images"])
|
|
|
21
20
|
|
|
22
21
|
class ImageResponse(BaseModel):
|
|
23
22
|
"""Response schema for image metadata."""
|
|
24
|
-
id:
|
|
23
|
+
id: int
|
|
25
24
|
filename: str
|
|
26
25
|
original_filename: str
|
|
27
26
|
mime_type: str
|
|
@@ -47,7 +46,7 @@ class ImageListResponse(BaseModel):
|
|
|
47
46
|
|
|
48
47
|
class ImageDataResponse(BaseModel):
|
|
49
48
|
"""Response containing image base64 data."""
|
|
50
|
-
id:
|
|
49
|
+
id: int
|
|
51
50
|
mime_type: str
|
|
52
51
|
base64_data: str
|
|
53
52
|
data_uri: str # Ready-to-use: "data:image/png;base64,..."
|
|
@@ -81,7 +80,7 @@ def _get_current_user() -> str:
|
|
|
81
80
|
|
|
82
81
|
def _image_to_response(img: ImageAsset) -> ImageResponse:
|
|
83
82
|
return ImageResponse(
|
|
84
|
-
id=img.
|
|
83
|
+
id=img.id,
|
|
85
84
|
filename=img.filename,
|
|
86
85
|
original_filename=img.original_filename,
|
|
87
86
|
mime_type=img.mime_type,
|
|
@@ -168,75 +167,58 @@ def list_images(
|
|
|
168
167
|
)
|
|
169
168
|
|
|
170
169
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
so a wrong caller cannot even confirm the image exists.
|
|
175
|
-
"""
|
|
176
|
-
if image.category == "ephemeral" and image.uploaded_by != _get_current_user():
|
|
177
|
-
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Image not found")
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
@router.get("/{token}", response_model=ImageResponse)
|
|
181
|
-
def get_image(token: str, db: Session = Depends(get_db)):
|
|
182
|
-
"""Get image metadata by opaque token."""
|
|
170
|
+
@router.get("/{image_id}", response_model=ImageResponse)
|
|
171
|
+
def get_image(image_id: int, db: Session = Depends(get_db)):
|
|
172
|
+
"""Get image metadata by ID."""
|
|
183
173
|
try:
|
|
184
174
|
image = db.query(ImageAsset).filter(
|
|
185
|
-
ImageAsset.
|
|
175
|
+
ImageAsset.id == image_id,
|
|
186
176
|
ImageAsset.is_active == True,
|
|
187
177
|
).first()
|
|
188
178
|
if not image:
|
|
189
179
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Image not found")
|
|
190
|
-
_deny_ephemeral_cross_user(image)
|
|
191
180
|
return _image_to_response(image)
|
|
192
181
|
except HTTPException:
|
|
193
182
|
raise
|
|
194
183
|
except Exception as e:
|
|
195
|
-
logger.error(f"Error getting image: {e}", exc_info=True)
|
|
184
|
+
logger.error(f"Error getting image {image_id}: {e}", exc_info=True)
|
|
196
185
|
raise HTTPException(
|
|
197
186
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
198
187
|
detail="Failed to get image",
|
|
199
188
|
)
|
|
200
189
|
|
|
201
190
|
|
|
202
|
-
@router.get("/{
|
|
203
|
-
def get_image_data(
|
|
204
|
-
"""Get full image as base64 data (for embedding in slides)
|
|
191
|
+
@router.get("/{image_id}/data", response_model=ImageDataResponse)
|
|
192
|
+
def get_image_data(image_id: int, db: Session = Depends(get_db)):
|
|
193
|
+
"""Get full image as base64 data (for embedding in slides)."""
|
|
205
194
|
try:
|
|
206
|
-
|
|
207
|
-
ImageAsset.token == token,
|
|
208
|
-
ImageAsset.is_active == True,
|
|
209
|
-
).first()
|
|
210
|
-
if not image:
|
|
211
|
-
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Image not found")
|
|
212
|
-
_deny_ephemeral_cross_user(image)
|
|
213
|
-
b64_data = base64.b64encode(image.image_data).decode("utf-8")
|
|
195
|
+
b64_data, mime_type = image_service.get_image_base64(db, image_id)
|
|
214
196
|
return ImageDataResponse(
|
|
215
|
-
id=
|
|
216
|
-
mime_type=
|
|
197
|
+
id=image_id,
|
|
198
|
+
mime_type=mime_type,
|
|
217
199
|
base64_data=b64_data,
|
|
218
|
-
data_uri=f"data:{
|
|
200
|
+
data_uri=f"data:{mime_type};base64,{b64_data}",
|
|
219
201
|
)
|
|
220
|
-
except
|
|
221
|
-
raise
|
|
202
|
+
except ValueError as e:
|
|
203
|
+
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
|
|
222
204
|
except Exception as e:
|
|
223
|
-
logger.error(f"Error getting image data: {e}", exc_info=True)
|
|
205
|
+
logger.error(f"Error getting image data {image_id}: {e}", exc_info=True)
|
|
224
206
|
raise HTTPException(
|
|
225
207
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
226
208
|
detail="Failed to get image data",
|
|
227
209
|
)
|
|
228
210
|
|
|
229
211
|
|
|
230
|
-
@router.put("/{
|
|
212
|
+
@router.put("/{image_id}", response_model=ImageResponse)
|
|
231
213
|
def update_image(
|
|
232
|
-
|
|
214
|
+
image_id: int,
|
|
233
215
|
request: ImageUpdateRequest,
|
|
234
216
|
db: Session = Depends(get_db),
|
|
235
217
|
):
|
|
236
218
|
"""Update image metadata (tags, description, category)."""
|
|
237
219
|
try:
|
|
238
220
|
image = db.query(ImageAsset).filter(
|
|
239
|
-
ImageAsset.
|
|
221
|
+
ImageAsset.id == image_id,
|
|
240
222
|
ImageAsset.is_active == True,
|
|
241
223
|
).first()
|
|
242
224
|
if not image:
|
|
@@ -264,20 +246,20 @@ def update_image(
|
|
|
264
246
|
raise
|
|
265
247
|
except Exception as e:
|
|
266
248
|
db.rollback()
|
|
267
|
-
logger.error(f"Error updating image: {e}", exc_info=True)
|
|
249
|
+
logger.error(f"Error updating image {image_id}: {e}", exc_info=True)
|
|
268
250
|
raise HTTPException(
|
|
269
251
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
270
252
|
detail="Failed to update image",
|
|
271
253
|
)
|
|
272
254
|
|
|
273
255
|
|
|
274
|
-
@router.delete("/{
|
|
275
|
-
def delete_image(
|
|
256
|
+
@router.delete("/{image_id}", status_code=status.HTTP_204_NO_CONTENT)
|
|
257
|
+
def delete_image(image_id: int, db: Session = Depends(get_db)):
|
|
276
258
|
"""Soft-delete an image."""
|
|
277
259
|
try:
|
|
278
260
|
user = _get_current_user()
|
|
279
261
|
image = db.query(ImageAsset).filter(
|
|
280
|
-
ImageAsset.
|
|
262
|
+
ImageAsset.id == image_id,
|
|
281
263
|
ImageAsset.is_active == True, # noqa: E712
|
|
282
264
|
).first()
|
|
283
265
|
if not image:
|
|
@@ -288,14 +270,14 @@ def delete_image(token: str, db: Session = Depends(get_db)):
|
|
|
288
270
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
289
271
|
detail="You don't have permission to modify this image",
|
|
290
272
|
)
|
|
291
|
-
image_service.delete_image(db,
|
|
273
|
+
image_service.delete_image(db, image_id, user)
|
|
292
274
|
except HTTPException:
|
|
293
275
|
raise
|
|
294
276
|
except ValueError as e:
|
|
295
277
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
|
|
296
278
|
except Exception as e:
|
|
297
279
|
db.rollback()
|
|
298
|
-
logger.error(f"Error deleting image: {e}", exc_info=True)
|
|
280
|
+
logger.error(f"Error deleting image {image_id}: {e}", exc_info=True)
|
|
299
281
|
raise HTTPException(
|
|
300
282
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
301
283
|
detail="Failed to delete image",
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/requests.py
RENAMED
|
@@ -74,9 +74,9 @@ class ChatRequest(BaseModel):
|
|
|
74
74
|
default=None,
|
|
75
75
|
description="Optional context containing the slides to edit",
|
|
76
76
|
)
|
|
77
|
-
image_ids: Optional[list[
|
|
77
|
+
image_ids: Optional[list[int]] = Field(
|
|
78
78
|
default=None,
|
|
79
|
-
description="
|
|
79
|
+
description="IDs of images attached to this message (from upload or paste)",
|
|
80
80
|
)
|
|
81
81
|
agent_config: Optional[dict] = Field(
|
|
82
82
|
default=None,
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/services/chat_service.py
RENAMED
|
@@ -345,7 +345,7 @@ class ChatService:
|
|
|
345
345
|
session_id: str,
|
|
346
346
|
message: str,
|
|
347
347
|
slide_context: Optional[Dict[str, Any]] = None,
|
|
348
|
-
image_ids: Optional[List[
|
|
348
|
+
image_ids: Optional[List[int]] = None,
|
|
349
349
|
) -> Dict[str, Any]:
|
|
350
350
|
"""Send a message to the agent and get response.
|
|
351
351
|
|
|
@@ -828,7 +828,7 @@ class ChatService:
|
|
|
828
828
|
message: str,
|
|
829
829
|
slide_context: Optional[Dict[str, Any]] = None,
|
|
830
830
|
request_id: Optional[str] = None,
|
|
831
|
-
image_ids: Optional[List[
|
|
831
|
+
image_ids: Optional[List[int]] = None,
|
|
832
832
|
is_first_message_override: Optional[bool] = None,
|
|
833
833
|
) -> Generator[StreamEvent, None, None]:
|
|
834
834
|
"""Send a message and yield streaming events.
|
|
@@ -1993,30 +1993,27 @@ class ChatService:
|
|
|
1993
1993
|
|
|
1994
1994
|
return ([], None)
|
|
1995
1995
|
|
|
1996
|
-
def _inject_image_context(self, message: str, image_ids: List[
|
|
1997
|
-
"""Append image metadata to user message so the agent knows about attached images.
|
|
1998
|
-
|
|
1999
|
-
``image_ids`` are opaque image tokens (SDR-4437 F-TM-7), not int PKs.
|
|
2000
|
-
"""
|
|
1996
|
+
def _inject_image_context(self, message: str, image_ids: List[int]) -> str:
|
|
1997
|
+
"""Append image metadata to user message so the agent knows about attached images."""
|
|
2001
1998
|
from src.core.database import get_db_session
|
|
2002
1999
|
from src.services import image_service
|
|
2003
2000
|
|
|
2004
2001
|
image_descriptions = []
|
|
2005
2002
|
with get_db_session() as db:
|
|
2006
|
-
for
|
|
2003
|
+
for img_id in image_ids:
|
|
2007
2004
|
try:
|
|
2008
2005
|
img = db.query(image_service.ImageAsset).filter(
|
|
2009
|
-
image_service.ImageAsset.
|
|
2006
|
+
image_service.ImageAsset.id == img_id,
|
|
2010
2007
|
image_service.ImageAsset.is_active == True,
|
|
2011
2008
|
).first()
|
|
2012
2009
|
if img:
|
|
2013
2010
|
image_descriptions.append(
|
|
2014
|
-
f'- Image ID {img.
|
|
2011
|
+
f'- Image ID {img.id}: "{img.original_filename}" '
|
|
2015
2012
|
f'({img.description or "no description"}). '
|
|
2016
|
-
f'Use: <img src="{{{{image:{img.
|
|
2013
|
+
f'Use: <img src="{{{{image:{img.id}}}}}" alt="{img.description or img.original_filename}" />'
|
|
2017
2014
|
)
|
|
2018
2015
|
except Exception as e:
|
|
2019
|
-
logger.warning(f"Failed to load image {
|
|
2016
|
+
logger.warning(f"Failed to load image {img_id} for context injection: {e}")
|
|
2020
2017
|
|
|
2021
2018
|
if not image_descriptions:
|
|
2022
2019
|
return message
|
|
@@ -524,8 +524,6 @@ def _run_migrations(engine, schema: str | None = None):
|
|
|
524
524
|
# --- image_assets.tags: json → jsonb (PostgreSQL) for native @> queries ---
|
|
525
525
|
_migrate_image_assets_tags_json_to_jsonb(conn, schema, _qual, is_sqlite)
|
|
526
526
|
|
|
527
|
-
# --- image_assets.token: unguessable external id + backfill (SDR-4437 F-TM-7) ---
|
|
528
|
-
_migrate_image_assets_add_token(conn, inspector, schema, _qual, is_sqlite)
|
|
529
527
|
# --- agent_config: style precedence in the DB, for the raw-SQL writers no
|
|
530
528
|
# --- Python-side bind hook can see (PostgreSQL only; no-op on SQLite) ---
|
|
531
529
|
_migrate_agent_config_precedence_trigger(
|
|
@@ -1060,44 +1058,6 @@ def _ensure_llm_judge_backend_default(
|
|
|
1060
1058
|
)
|
|
1061
1059
|
|
|
1062
1060
|
|
|
1063
|
-
def _migrate_image_assets_add_token(conn, inspector, schema, _qual, is_sqlite) -> None:
|
|
1064
|
-
"""Add the unguessable ``token`` column to image_assets and backfill (SDR-4437 F-TM-7).
|
|
1065
|
-
|
|
1066
|
-
The int PK is enumerable, so image reads now key on an opaque token. Fresh
|
|
1067
|
-
installs get the column via create_all(); existing tables need this ALTER +
|
|
1068
|
-
per-row backfill. Idempotent: gated on the column's absence.
|
|
1069
|
-
"""
|
|
1070
|
-
import secrets
|
|
1071
|
-
|
|
1072
|
-
from sqlalchemy import text
|
|
1073
|
-
|
|
1074
|
-
table = "image_assets"
|
|
1075
|
-
try:
|
|
1076
|
-
cols = {c["name"] for c in inspector.get_columns(table, schema=schema)}
|
|
1077
|
-
except Exception:
|
|
1078
|
-
return
|
|
1079
|
-
if not cols or "token" in cols:
|
|
1080
|
-
return
|
|
1081
|
-
|
|
1082
|
-
q = _qual(table)
|
|
1083
|
-
logger.info(f"Migration: adding token column to {table} (SDR-4437 F-TM-7)")
|
|
1084
|
-
# Add nullable first so the ALTER succeeds on a populated table.
|
|
1085
|
-
conn.execute(text(f"ALTER TABLE {q} ADD COLUMN token VARCHAR(64)"))
|
|
1086
|
-
|
|
1087
|
-
# Backfill every existing row with a distinct unguessable token.
|
|
1088
|
-
row_ids = [r[0] for r in conn.execute(text(f"SELECT id FROM {q} WHERE token IS NULL")).fetchall()]
|
|
1089
|
-
for row_id in row_ids:
|
|
1090
|
-
conn.execute(
|
|
1091
|
-
text(f"UPDATE {q} SET token = :tok WHERE id = :id"),
|
|
1092
|
-
{"tok": secrets.token_urlsafe(32), "id": row_id},
|
|
1093
|
-
)
|
|
1094
|
-
|
|
1095
|
-
# Enforce uniqueness (and non-null on PostgreSQL, now that every row has a token).
|
|
1096
|
-
conn.execute(text(
|
|
1097
|
-
f"CREATE UNIQUE INDEX IF NOT EXISTS ix_image_assets_token ON {q} (token)"
|
|
1098
|
-
))
|
|
1099
|
-
if not is_sqlite:
|
|
1100
|
-
conn.execute(text(f"ALTER TABLE {q} ALTER COLUMN token SET NOT NULL"))
|
|
1101
1061
|
#: The one place the precedence rule is written in SQL. ``$$``-quoted so the body
|
|
1102
1062
|
#: needs no escaping, and named after the rule rather than the tables, since both
|
|
1103
1063
|
#: ``agent_config`` columns share it.
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/image.py
RENAMED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"""Image asset model — metadata and binary data stored together in Lakebase."""
|
|
2
|
-
import secrets
|
|
3
2
|
from datetime import datetime
|
|
4
3
|
|
|
5
4
|
from sqlalchemy import Boolean, Column, DateTime, Integer, JSON, LargeBinary, String, Text
|
|
@@ -11,17 +10,6 @@ from src.core.database import Base
|
|
|
11
10
|
_TagsColumn = JSON().with_variant(JSONB(), "postgresql")
|
|
12
11
|
|
|
13
12
|
|
|
14
|
-
def _new_image_token() -> str:
|
|
15
|
-
"""Unguessable external identifier (SDR-4437 F-TM-7).
|
|
16
|
-
|
|
17
|
-
The autoincrement int PK is enumerable, so it is never exposed. This
|
|
18
|
-
opaque token is the only identifier that leaves the server — it is what
|
|
19
|
-
the API returns, what chat sends in ``image_ids``, and what goes in
|
|
20
|
-
``{{image:...}}`` slide placeholders.
|
|
21
|
-
"""
|
|
22
|
-
return secrets.token_urlsafe(32)
|
|
23
|
-
|
|
24
|
-
|
|
25
13
|
class ImageAsset(Base):
|
|
26
14
|
"""Uploaded image with binary data stored directly in PostgreSQL.
|
|
27
15
|
|
|
@@ -32,9 +20,7 @@ class ImageAsset(Base):
|
|
|
32
20
|
|
|
33
21
|
__tablename__ = "image_assets"
|
|
34
22
|
|
|
35
|
-
id = Column(Integer, primary_key=True)
|
|
36
|
-
# Unguessable external identifier (SDR-4437 F-TM-7). token_urlsafe(32) → 43 chars.
|
|
37
|
-
token = Column(String(64), unique=True, nullable=False, index=True, default=_new_image_token)
|
|
23
|
+
id = Column(Integer, primary_key=True)
|
|
38
24
|
filename = Column(String(255), nullable=False) # Generated: {uuid}.{ext}
|
|
39
25
|
original_filename = Column(String(255), nullable=False) # User's original filename
|
|
40
26
|
mime_type = Column(String(50), nullable=False) # image/png, image/jpeg, image/gif, image/svg+xml
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/image_service.py
RENAMED
|
@@ -51,7 +51,7 @@ def upload_image(
|
|
|
51
51
|
).first()
|
|
52
52
|
if existing:
|
|
53
53
|
raise ValueError(
|
|
54
|
-
f"An image named '{original_filename}' already exists. "
|
|
54
|
+
f"An image named '{original_filename}' already exists (id={existing.id}). "
|
|
55
55
|
"Please rename the file or delete the existing image first."
|
|
56
56
|
)
|
|
57
57
|
|
|
@@ -86,19 +86,19 @@ def upload_image(
|
|
|
86
86
|
return image
|
|
87
87
|
|
|
88
88
|
|
|
89
|
-
def get_image_base64(db: Session,
|
|
89
|
+
def get_image_base64(db: Session, image_id: int) -> tuple[str, str]:
|
|
90
90
|
"""
|
|
91
|
-
Get full image as base64 string
|
|
91
|
+
Get full image as base64 string.
|
|
92
92
|
|
|
93
93
|
Returns:
|
|
94
94
|
Tuple of (base64_data, mime_type)
|
|
95
95
|
"""
|
|
96
96
|
image = db.query(ImageAsset).filter(
|
|
97
|
-
ImageAsset.
|
|
97
|
+
ImageAsset.id == image_id,
|
|
98
98
|
ImageAsset.is_active == True,
|
|
99
99
|
).first()
|
|
100
100
|
if not image:
|
|
101
|
-
raise ValueError(f"Image {
|
|
101
|
+
raise ValueError(f"Image {image_id} not found")
|
|
102
102
|
|
|
103
103
|
b64 = base64.b64encode(image.image_data).decode("utf-8")
|
|
104
104
|
return b64, image.mime_type
|
|
@@ -175,11 +175,11 @@ def search_images(
|
|
|
175
175
|
).all()
|
|
176
176
|
|
|
177
177
|
|
|
178
|
-
def delete_image(db: Session,
|
|
179
|
-
"""Soft-delete an image
|
|
180
|
-
image = db.query(ImageAsset).filter(ImageAsset.
|
|
178
|
+
def delete_image(db: Session, image_id: int, user: str) -> None:
|
|
179
|
+
"""Soft-delete an image."""
|
|
180
|
+
image = db.query(ImageAsset).filter(ImageAsset.id == image_id).first()
|
|
181
181
|
if not image:
|
|
182
|
-
raise ValueError(f"Image {
|
|
182
|
+
raise ValueError(f"Image {image_id} not found")
|
|
183
183
|
|
|
184
184
|
image.is_active = False
|
|
185
185
|
image.updated_by = user
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/image_tools.py
RENAMED
|
@@ -53,13 +53,13 @@ def search_images(
|
|
|
53
53
|
# Must build results inside session scope to avoid DetachedInstanceError
|
|
54
54
|
results = [
|
|
55
55
|
{
|
|
56
|
-
"id": img.
|
|
56
|
+
"id": img.id,
|
|
57
57
|
"filename": img.original_filename,
|
|
58
58
|
"description": img.description,
|
|
59
59
|
"tags": img.tags,
|
|
60
60
|
"category": img.category,
|
|
61
61
|
"mime_type": img.mime_type,
|
|
62
|
-
"usage": f'<img src="{{{{image:{img.
|
|
62
|
+
"usage": f'<img src="{{{{image:{img.id}}}}}" alt="{img.description or img.original_filename}" />',
|
|
63
63
|
}
|
|
64
64
|
for img in images
|
|
65
65
|
]
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/image_utils.py
RENAMED
|
@@ -8,8 +8,7 @@ from src.services import image_service
|
|
|
8
8
|
|
|
9
9
|
logger = logging.getLogger(__name__)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
IMAGE_PLACEHOLDER_PATTERN = re.compile(r"\{\{image:([A-Za-z0-9_-]+)\}\}")
|
|
11
|
+
IMAGE_PLACEHOLDER_PATTERN = re.compile(r"\{\{image:(\d+)\}\}")
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
def substitute_image_placeholders(html: str, db: Session) -> str:
|
|
@@ -23,12 +22,12 @@ def substitute_image_placeholders(html: str, db: Session) -> str:
|
|
|
23
22
|
return html
|
|
24
23
|
|
|
25
24
|
def replace_match(match):
|
|
26
|
-
|
|
25
|
+
image_id = int(match.group(1))
|
|
27
26
|
try:
|
|
28
|
-
b64_data, mime_type = image_service.get_image_base64(db,
|
|
27
|
+
b64_data, mime_type = image_service.get_image_base64(db, image_id)
|
|
29
28
|
return f"data:{mime_type};base64,{b64_data}"
|
|
30
29
|
except Exception as e:
|
|
31
|
-
logger.warning(f"Failed to resolve image placeholder {{{{image:{
|
|
30
|
+
logger.warning(f"Failed to resolve image placeholder {{{{image:{image_id}}}}}: {e}")
|
|
32
31
|
return match.group(0) # Leave placeholder if image not found
|
|
33
32
|
|
|
34
33
|
return IMAGE_PLACEHOLDER_PATTERN.sub(replace_match, html)
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/databricks_tellr_app/__init__.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/databricks_tellr_app/run.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
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/_otel_bootstrap.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/middleware/__init__.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/middleware/csrf.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/__init__.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/_authz.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/admin_usage.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/agent_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/export.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/feedback.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/google_slides.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/local_version.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/profiles.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/sessions.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
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/slides.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/verification.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/routes/version.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/__init__.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/agent_config.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/feedback.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/responses.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/schemas/streaming.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/services/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/services/job_queue.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/services/usage_events.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/utils/__init__.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/api/utils/validation.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/config_loader.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/context_utils.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/databricks_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/init_default_profile.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/mlflow_agent_spans.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/mlflow_tracing.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/otel_logging.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/permission_context.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/prompt_modules.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/core/user_context.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/__init__.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/feedback.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/identity.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/profile.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/prompts.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/database/models/session.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
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/domain/slide_deck.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/agent_factory.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/config_service.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/config_validator.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
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/drive_uploader.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/genie_service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/html_to_pptx.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
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/profile_service.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/tools/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/tools/genie_tool.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/tools/mcp_tool.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/services/validator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/ds_asset_utils.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/error_handling.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/html_safety.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/js_validator.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev1 → databricks_tellr_app-0.4.3.dev2}/src/utils/logging_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|