databricks-tellr-app 0.4.3.dev3463__tar.gz → 0.4.3.dev3464__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.dev3463 → databricks_tellr_app-0.4.3.dev3464}/PKG-INFO +2 -2
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/databricks_tellr_app.egg-info/PKG-INFO +2 -2
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/databricks_tellr_app.egg-info/SOURCES.txt +8 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/databricks_tellr_app.egg-info/requires.txt +1 -1
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/pyproject.toml +2 -2
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/main.py +25 -1
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/middleware/security_headers.py +8 -1
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/settings/slide_styles.py +201 -0
- databricks_tellr_app-0.4.3.dev3464/src/api/services/slide_style_preview_queue.py +583 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/database.py +70 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/defaults.py +1 -1
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/__init__.py +2 -0
- databricks_tellr_app-0.4.3.dev3464/src/database/models/slide_style_library.py +79 -0
- databricks_tellr_app-0.4.3.dev3464/src/database/models/slide_style_preview.py +55 -0
- databricks_tellr_app-0.4.3.dev3464/src/services/agent_definition_manifest_v1.py +3 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/model_endpoint_catalog.py +64 -20
- databricks_tellr_app-0.4.3.dev3464/src/services/slide_style_preview_fixture.py +204 -0
- databricks_tellr_app-0.4.3.dev3464/src/services/slide_style_preview_storage.py +119 -0
- databricks_tellr_app-0.4.3.dev3463/src/database/models/slide_style_library.py +0 -47
- databricks_tellr_app-0.4.3.dev3463/src/services/agent_definition_manifest_v1.py +0 -3
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/README.md +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/databricks_tellr_app/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/databricks_tellr_app/run.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/databricks_tellr_app.egg-info/dependency_links.txt +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/databricks_tellr_app.egg-info/top_level.txt +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/setup.cfg +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/setup.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/_otel_bootstrap.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/fixtures/tour_demo_deck.json +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/mcp_auth.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/mcp_server.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/middleware/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/middleware/csrf.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/middleware/request_logging.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/_authz.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/admin.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/admin_usage.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/agent_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/agent_definitions.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/chat.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/deck_contributors.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/export.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/feedback.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/google_slides.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/images.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/local_version.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/profiles.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/sessions.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/settings/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/settings/contributors.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/settings/deck_prompts.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/settings/design_systems.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/settings/identities.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/setup.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/slides.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/tools.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/tour.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/verification.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/version.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/agent_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/agent_definitions.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/feedback.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/graph_release_history.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/graph_releases.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/requests.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/responses.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/settings/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/settings/requests.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/settings/responses.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/streaming.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/chat_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/deck_level_writer.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/export_job_queue.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/feedback_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/job_queue.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/session_manager.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/session_naming.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/slide_repository.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/usage_events.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/usage_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/utils/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/api/utils/validation.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/backfill_session_slides_startup.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/checkpointer.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/config_loader.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/context_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/databricks_client.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/encryption.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/init_default_profile.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/lakebase.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/migrate_profiles_to_agent_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/mlflow_agent_spans.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/mlflow_tracing.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/otel_logging.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/permission_context.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/prompt_modules.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/settings_db.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/architect.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/build_reviewer.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/builder.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/data_analyst.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/deck_reviewer.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/fix_reviewer.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/fixer.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/strip_retired_prompt_keys.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/core/user_context.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/data_migration.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/deck_contributor.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/deck_review.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/design_system.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/encryption_key.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/feedback.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/genie_space.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/google_global_credentials.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/google_oauth_token.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/graph_checkpoint.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/graph_configuration.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/identity.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/image.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/profile.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/profile_contributor.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/prompts.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/request_log.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/session.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/slide_deck_prompt.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/usage_event.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/user_preference.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/database/types.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/domain/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/domain/conversation_engine.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/domain/conversation_turns.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/domain/deck_spec.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/domain/deck_spec_slides.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/domain/finding.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/domain/finding_copy.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/domain/skill_io.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/domain/slide.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/domain/slide_alignment.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/domain/slide_deck.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/domain/slide_numbering.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_factory.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_model_payload.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_resolution.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_runtime.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_runtime_identity.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_schema_registry.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_schema_types.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_test_workbench.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/collaboration_history.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/config_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/config_validator.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/conversation_pins.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/converter_jail/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/converter_jail/ast_guard.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/converter_jail/codeprep.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/converter_jail/gslides_runner.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/converter_jail/jail.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/converter_jail/pptx_runner.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/converter_jail/protocol.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/deck_css_aggregator.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/deck_review_store.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/design_system_compiler.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/design_system_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/design_system_templates.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/drive_uploader.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/evaluation/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/evaluation/llm_judge.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/foreman_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/gateway_openai.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/genie_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/google_slides_auth.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/google_slides_prompts_defaults.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/builder.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/event_emitter.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/nodes.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/progress.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/routers.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/state.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/user_notices.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration_bootstrap.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration_content.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration_draft.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration_publication.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration_rollback.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration_seed.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration_workbench.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_definition_manifest.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_release_evidence.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_release_history.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/html_to_google_slides.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/html_to_pptx.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/identity_provider.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/identity_providers/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/identity_providers/account_provider.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/identity_providers/local_provider.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/identity_providers/scim_filter.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/identity_providers/workspace_provider.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/image_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/image_tools.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/model_endpoint_probe.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/permission_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/persisted_graph_release.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/pptx_from_html_huashu.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/pptx_from_records.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/pptx_prompts_defaults.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/profile_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/prompt_assembler.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/shared_deck_attribution.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/spec_sync.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/streaming_callback.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/svg_sanitizer.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/template_sections.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/tools/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/tools/agent_bricks_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/tools/ds_asset_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/tools/genie_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/tools/mcp_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/tools/model_endpoint_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/tools/vector_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/services/validator.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/utils/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/utils/css_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/utils/ds_asset_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/utils/error_handling.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/utils/graph_safety.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/utils/html_safety.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/utils/html_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/utils/image_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/utils/js_validator.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/utils/logging_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/utils/pi_filter.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/utils/slide_hash.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/utils/spotlight.py +0 -0
- {databricks_tellr_app-0.4.3.dev3463 → databricks_tellr_app-0.4.3.dev3464}/src/utils/text_caps.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: databricks-tellr-app
|
|
3
|
-
Version: 0.4.3.
|
|
3
|
+
Version: 0.4.3.dev3464
|
|
4
4
|
Summary: Tellr application package for Databricks Apps
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -42,7 +42,7 @@ Requires-Dist: google-auth-oauthlib==1.2.4
|
|
|
42
42
|
Requires-Dist: google-auth-httplib2==0.3.0
|
|
43
43
|
Requires-Dist: cryptography==46.0.3
|
|
44
44
|
Requires-Dist: sse-starlette==3.0.3
|
|
45
|
-
Requires-Dist: databricks-sdk==0.
|
|
45
|
+
Requires-Dist: databricks-sdk==0.157.0
|
|
46
46
|
Requires-Dist: mlflow[databricks]==3.14.0
|
|
47
47
|
Requires-Dist: mlflow-skinny==3.14.0
|
|
48
48
|
Requires-Dist: databricks-agents==1.11.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: databricks-tellr-app
|
|
3
|
-
Version: 0.4.3.
|
|
3
|
+
Version: 0.4.3.dev3464
|
|
4
4
|
Summary: Tellr application package for Databricks Apps
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -42,7 +42,7 @@ Requires-Dist: google-auth-oauthlib==1.2.4
|
|
|
42
42
|
Requires-Dist: google-auth-httplib2==0.3.0
|
|
43
43
|
Requires-Dist: cryptography==46.0.3
|
|
44
44
|
Requires-Dist: sse-starlette==3.0.3
|
|
45
|
-
Requires-Dist: databricks-sdk==0.
|
|
45
|
+
Requires-Dist: databricks-sdk==0.157.0
|
|
46
46
|
Requires-Dist: mlflow[databricks]==3.14.0
|
|
47
47
|
Requires-Dist: mlflow-skinny==3.14.0
|
|
48
48
|
Requires-Dist: databricks-agents==1.11.0
|
|
@@ -62,6 +62,7 @@ setup.py
|
|
|
62
62
|
./src/api/services/session_manager.py
|
|
63
63
|
./src/api/services/session_naming.py
|
|
64
64
|
./src/api/services/slide_repository.py
|
|
65
|
+
./src/api/services/slide_style_preview_queue.py
|
|
65
66
|
./src/api/services/usage_events.py
|
|
66
67
|
./src/api/services/usage_service.py
|
|
67
68
|
./src/api/utils/__init__.py
|
|
@@ -117,6 +118,7 @@ setup.py
|
|
|
117
118
|
./src/database/models/session.py
|
|
118
119
|
./src/database/models/slide_deck_prompt.py
|
|
119
120
|
./src/database/models/slide_style_library.py
|
|
121
|
+
./src/database/models/slide_style_preview.py
|
|
120
122
|
./src/database/models/usage_event.py
|
|
121
123
|
./src/database/models/user_preference.py
|
|
122
124
|
./src/domain/__init__.py
|
|
@@ -183,6 +185,8 @@ setup.py
|
|
|
183
185
|
./src/services/profile_service.py
|
|
184
186
|
./src/services/prompt_assembler.py
|
|
185
187
|
./src/services/shared_deck_attribution.py
|
|
188
|
+
./src/services/slide_style_preview_fixture.py
|
|
189
|
+
./src/services/slide_style_preview_storage.py
|
|
186
190
|
./src/services/spec_sync.py
|
|
187
191
|
./src/services/streaming_callback.py
|
|
188
192
|
./src/services/svg_sanitizer.py
|
|
@@ -297,6 +301,7 @@ src/api/services/job_queue.py
|
|
|
297
301
|
src/api/services/session_manager.py
|
|
298
302
|
src/api/services/session_naming.py
|
|
299
303
|
src/api/services/slide_repository.py
|
|
304
|
+
src/api/services/slide_style_preview_queue.py
|
|
300
305
|
src/api/services/usage_events.py
|
|
301
306
|
src/api/services/usage_service.py
|
|
302
307
|
src/api/utils/__init__.py
|
|
@@ -352,6 +357,7 @@ src/database/models/request_log.py
|
|
|
352
357
|
src/database/models/session.py
|
|
353
358
|
src/database/models/slide_deck_prompt.py
|
|
354
359
|
src/database/models/slide_style_library.py
|
|
360
|
+
src/database/models/slide_style_preview.py
|
|
355
361
|
src/database/models/usage_event.py
|
|
356
362
|
src/database/models/user_preference.py
|
|
357
363
|
src/domain/__init__.py
|
|
@@ -418,6 +424,8 @@ src/services/pptx_prompts_defaults.py
|
|
|
418
424
|
src/services/profile_service.py
|
|
419
425
|
src/services/prompt_assembler.py
|
|
420
426
|
src/services/shared_deck_attribution.py
|
|
427
|
+
src/services/slide_style_preview_fixture.py
|
|
428
|
+
src/services/slide_style_preview_storage.py
|
|
421
429
|
src/services/spec_sync.py
|
|
422
430
|
src/services/streaming_callback.py
|
|
423
431
|
src/services/svg_sanitizer.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "databricks-tellr-app"
|
|
7
|
-
version = "0.4.3.
|
|
7
|
+
version = "0.4.3.dev3464"
|
|
8
8
|
description = "Tellr application package for Databricks Apps"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -86,7 +86,7 @@ dependencies = [
|
|
|
86
86
|
# langgraph-prebuilt 1.0.10→1.1.0, added langgraph-sdk==0.4.2. These match
|
|
87
87
|
# the repo-root requirements.txt and pyproject.toml. MUST be re-verified via
|
|
88
88
|
# a devloop deploy on db-tellr-dev-pinfix or equivalent before PR3 ships.
|
|
89
|
-
"databricks-sdk==0.
|
|
89
|
+
"databricks-sdk==0.157.0",
|
|
90
90
|
"mlflow[databricks]==3.14.0",
|
|
91
91
|
"mlflow-skinny==3.14.0",
|
|
92
92
|
"databricks-agents==1.11.0",
|
|
@@ -49,6 +49,7 @@ from src.api.services.export_job_queue import (
|
|
|
49
49
|
start_export_worker,
|
|
50
50
|
)
|
|
51
51
|
from src.api.services.job_queue import recover_stuck_requests, start_worker
|
|
52
|
+
from src.api.services.slide_style_preview_queue import start_preview_worker
|
|
52
53
|
from src.core.database import (
|
|
53
54
|
is_lakebase_environment,
|
|
54
55
|
start_token_refresh,
|
|
@@ -70,6 +71,7 @@ IS_TESTING = ENVIRONMENT == "test"
|
|
|
70
71
|
_worker_task = None
|
|
71
72
|
_export_worker_task = None
|
|
72
73
|
_export_cleanup_task: asyncio.Task | None = None
|
|
74
|
+
_preview_worker_task = None
|
|
73
75
|
_cleanup_task = None
|
|
74
76
|
_timeout_task = None
|
|
75
77
|
_spec_sweeper_task = None
|
|
@@ -79,7 +81,7 @@ _frontend_assets_stack: ExitStack | None = None
|
|
|
79
81
|
@asynccontextmanager
|
|
80
82
|
async def lifespan(app: FastAPI):
|
|
81
83
|
"""Lifespan context manager for startup/shutdown events."""
|
|
82
|
-
global _worker_task, _export_worker_task, _export_cleanup_task
|
|
84
|
+
global _worker_task, _export_worker_task, _export_cleanup_task, _preview_worker_task
|
|
83
85
|
global _cleanup_task, _timeout_task, _spec_sweeper_task, _frontend_assets_stack
|
|
84
86
|
|
|
85
87
|
# Startup
|
|
@@ -151,6 +153,20 @@ async def lifespan(app: FastAPI):
|
|
|
151
153
|
_export_cleanup_task = await start_export_cleanup_worker()
|
|
152
154
|
logger.info("Export job cleanup worker started")
|
|
153
155
|
|
|
156
|
+
# Start the slide-style preview generation worker
|
|
157
|
+
_preview_worker_task = await start_preview_worker()
|
|
158
|
+
logger.info("Slide-style preview worker started")
|
|
159
|
+
|
|
160
|
+
# Pre-warm previews for active styles so viewers hit a warm cache instead
|
|
161
|
+
# of a cold LLM generation. Bounded + deduplicated; runs off the event loop.
|
|
162
|
+
try:
|
|
163
|
+
from src.api.services.slide_style_preview_queue import warm_missing_previews
|
|
164
|
+
|
|
165
|
+
warmed = await asyncio.to_thread(warm_missing_previews)
|
|
166
|
+
logger.info("Slide-style preview warm backfill enqueued", extra={"enqueued": warmed})
|
|
167
|
+
except Exception: # noqa: BLE001 — warming must never block startup
|
|
168
|
+
logger.warning("Slide-style preview warm backfill failed", exc_info=True)
|
|
169
|
+
|
|
154
170
|
# Start the MCP job timeout sweeper
|
|
155
171
|
from src.api.services.job_queue import mark_timed_out_jobs_loop
|
|
156
172
|
_timeout_task = asyncio.create_task(mark_timed_out_jobs_loop())
|
|
@@ -214,6 +230,14 @@ async def lifespan(app: FastAPI):
|
|
|
214
230
|
pass
|
|
215
231
|
logger.info("Export job cleanup worker stopped")
|
|
216
232
|
|
|
233
|
+
if _preview_worker_task:
|
|
234
|
+
_preview_worker_task.cancel()
|
|
235
|
+
try:
|
|
236
|
+
await _preview_worker_task
|
|
237
|
+
except asyncio.CancelledError:
|
|
238
|
+
pass
|
|
239
|
+
logger.info("Slide-style preview worker stopped")
|
|
240
|
+
|
|
217
241
|
if _cleanup_task:
|
|
218
242
|
_cleanup_task.cancel()
|
|
219
243
|
try:
|
|
@@ -24,6 +24,13 @@ Content-Security-Policy differentiated by response type:
|
|
|
24
24
|
Radix UI injects inline styles at runtime; CSP hashes apply to
|
|
25
25
|
<style>/<script> *elements*, not style *attributes*, so
|
|
26
26
|
``style-src`` needs 'unsafe-inline'.
|
|
27
|
+
3. Monaco: the editors load from jsDelivr via @monaco-editor/react, the
|
|
28
|
+
JS through ``script-src`` and ``editor.main.css`` as a stylesheet
|
|
29
|
+
link, so ``style-src`` also allows ``https://cdn.jsdelivr.net``.
|
|
30
|
+
Without it the sheet is blocked and the editor renders broken (its
|
|
31
|
+
input textarea shows as a stray box above the text). Given
|
|
32
|
+
'unsafe-inline' already, the origin adds no real style-injection
|
|
33
|
+
surface; ``script-src`` already trusts it.
|
|
27
34
|
|
|
28
35
|
``script-src 'unsafe-inline'`` + CDNs is a deliberate, documented
|
|
29
36
|
trade-off forced by srcdoc inheritance: slides remain confined by the
|
|
@@ -83,7 +90,7 @@ from starlette.responses import Response
|
|
|
83
90
|
DOCUMENT_CSP = (
|
|
84
91
|
"default-src 'self'; "
|
|
85
92
|
"script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdn.tailwindcss.com; "
|
|
86
|
-
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; "
|
|
93
|
+
"style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://fonts.googleapis.com; "
|
|
87
94
|
"img-src 'self' data:; "
|
|
88
95
|
"font-src 'self' data: https://cdn.jsdelivr.net https://fonts.gstatic.com; "
|
|
89
96
|
"connect-src 'self'; "
|
|
@@ -16,9 +16,14 @@ from sqlalchemy.orm import Session
|
|
|
16
16
|
from src.api.routes._authz import require_admin
|
|
17
17
|
from src.core.database import get_db, get_db_session
|
|
18
18
|
from src.database.models import SlideStyleLibrary
|
|
19
|
+
from src.services import slide_style_preview_fixture as preview_fixture
|
|
20
|
+
from src.services import slide_style_preview_storage as preview_storage
|
|
19
21
|
|
|
20
22
|
logger = logging.getLogger(__name__)
|
|
21
23
|
|
|
24
|
+
# Fields whose change invalidates a generated preview (see cache-invalidation).
|
|
25
|
+
_PREVIEW_AFFECTING_FIELDS = ("style_content", "image_guidelines")
|
|
26
|
+
|
|
22
27
|
router = APIRouter(prefix="/slide-styles", tags=["slide-styles"])
|
|
23
28
|
|
|
24
29
|
|
|
@@ -68,6 +73,26 @@ class SlideStyleListResponse(BaseModel):
|
|
|
68
73
|
total: int
|
|
69
74
|
|
|
70
75
|
|
|
76
|
+
class SlideStylePreviewResponse(BaseModel):
|
|
77
|
+
"""Read-only preview state for a slide style.
|
|
78
|
+
|
|
79
|
+
``status`` drives the client: ``ready`` (current), ``stale`` (a usable but
|
|
80
|
+
out-of-date copy while regeneration runs), ``queued``/``generating`` (in
|
|
81
|
+
flight), ``failed`` (with optional last-known-good copy), ``missing`` (never
|
|
82
|
+
generated). HTTP is always 200; the client polls on ``status`` rather than
|
|
83
|
+
on status codes.
|
|
84
|
+
"""
|
|
85
|
+
style_id: int
|
|
86
|
+
status: str
|
|
87
|
+
fingerprint: Optional[str] = None
|
|
88
|
+
slides: Optional[List[str]] = None
|
|
89
|
+
css: Optional[str] = None
|
|
90
|
+
assets: Optional[List[dict]] = None
|
|
91
|
+
generated_at: Optional[str] = None
|
|
92
|
+
error_code: Optional[str] = None
|
|
93
|
+
stale: bool = False
|
|
94
|
+
|
|
95
|
+
|
|
71
96
|
# API endpoints
|
|
72
97
|
|
|
73
98
|
@router.get("", response_model=SlideStyleListResponse)
|
|
@@ -238,6 +263,15 @@ def create_slide_style(
|
|
|
238
263
|
db.refresh(style)
|
|
239
264
|
|
|
240
265
|
logger.info(f"Created slide style: {style.name} (id={style.id})")
|
|
266
|
+
|
|
267
|
+
# Warm the visual preview immediately so the first viewer gets a cache
|
|
268
|
+
# hit instead of waiting on a cold generation. Deduplicated + best-effort.
|
|
269
|
+
try:
|
|
270
|
+
from src.api.services.slide_style_preview_queue import try_enqueue
|
|
271
|
+
|
|
272
|
+
try_enqueue(style.id)
|
|
273
|
+
except Exception: # noqa: BLE001 — warming must never fail the create
|
|
274
|
+
logger.warning("Preview warm-on-create failed", exc_info=True)
|
|
241
275
|
|
|
242
276
|
return SlideStyleResponse(
|
|
243
277
|
id=style.id,
|
|
@@ -321,11 +355,38 @@ def update_slide_style(
|
|
|
321
355
|
style.description = request.description
|
|
322
356
|
if request.category is not None:
|
|
323
357
|
style.category = request.category
|
|
358
|
+
|
|
359
|
+
# Detect preview-affecting changes BEFORE mutating, so we can invalidate
|
|
360
|
+
# the cached preview in the SAME transaction as the edit (cache-invalidation).
|
|
361
|
+
preview_affected = False
|
|
362
|
+
if request.style_content is not None and request.style_content != style.style_content:
|
|
363
|
+
preview_affected = True
|
|
364
|
+
if (
|
|
365
|
+
request.image_guidelines is not None
|
|
366
|
+
and request.image_guidelines != style.image_guidelines
|
|
367
|
+
):
|
|
368
|
+
preview_affected = True
|
|
369
|
+
|
|
324
370
|
if request.style_content is not None:
|
|
325
371
|
style.style_content = request.style_content
|
|
326
372
|
if request.image_guidelines is not None:
|
|
327
373
|
style.image_guidelines = request.image_guidelines
|
|
328
374
|
|
|
375
|
+
if preview_affected:
|
|
376
|
+
# Bump the revision (the generation write-back guard) and reset the
|
|
377
|
+
# cached preview to 'missing' so it regenerates. The last-known-good
|
|
378
|
+
# payload row is left in storage until the next successful prune.
|
|
379
|
+
style.style_revision = (style.style_revision or 0) + 1
|
|
380
|
+
style.preview_status = "missing"
|
|
381
|
+
style.preview_fingerprint = None
|
|
382
|
+
style.preview_payload_id = None
|
|
383
|
+
style.preview_error_code = None
|
|
384
|
+
style.preview_error_message = None
|
|
385
|
+
logger.info(
|
|
386
|
+
"Invalidated slide-style preview after edit",
|
|
387
|
+
extra={"style_id": style.id, "style_revision": style.style_revision},
|
|
388
|
+
)
|
|
389
|
+
|
|
329
390
|
# Update the user (skip Databricks call in test/dev to avoid network timeout)
|
|
330
391
|
if os.getenv("ENVIRONMENT") in ("development", "test"):
|
|
331
392
|
style.updated_by = "system"
|
|
@@ -344,6 +405,16 @@ def update_slide_style(
|
|
|
344
405
|
db.refresh(style)
|
|
345
406
|
|
|
346
407
|
logger.info(f"Updated slide style: {style.name} (id={style.id})")
|
|
408
|
+
|
|
409
|
+
# If the edit invalidated the preview, warm it right away (against the
|
|
410
|
+
# now-committed new revision) so viewers don't hit a cold regeneration.
|
|
411
|
+
if preview_affected:
|
|
412
|
+
try:
|
|
413
|
+
from src.api.services.slide_style_preview_queue import try_enqueue
|
|
414
|
+
|
|
415
|
+
try_enqueue(style.id)
|
|
416
|
+
except Exception: # noqa: BLE001 — warming must never fail the update
|
|
417
|
+
logger.warning("Preview warm-on-update failed", exc_info=True)
|
|
347
418
|
|
|
348
419
|
return SlideStyleResponse(
|
|
349
420
|
id=style.id,
|
|
@@ -510,3 +581,133 @@ def set_default_slide_style(style_id: int):
|
|
|
510
581
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
511
582
|
detail="Failed to set default slide style",
|
|
512
583
|
)
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
@router.get("/{style_id}/preview", response_model=SlideStylePreviewResponse)
|
|
587
|
+
def get_slide_style_preview(
|
|
588
|
+
style_id: int,
|
|
589
|
+
db: Session = Depends(get_db),
|
|
590
|
+
):
|
|
591
|
+
"""Read the cached visual preview for a slide style. NEVER generates inline.
|
|
592
|
+
|
|
593
|
+
Visibility mirrors ``GET /{style_id}`` (404 parity). When the cached preview
|
|
594
|
+
is missing or stale relative to the current generation fingerprint, this
|
|
595
|
+
enqueues a deduplicated background job and returns the current state (with a
|
|
596
|
+
stale copy if one exists) so the UI stays fast and crawlers/prefetch/scroll
|
|
597
|
+
never trigger LLM cost.
|
|
598
|
+
"""
|
|
599
|
+
from src.api.services.slide_style_preview_queue import try_enqueue
|
|
600
|
+
|
|
601
|
+
style = db.query(SlideStyleLibrary).filter(SlideStyleLibrary.id == style_id).first()
|
|
602
|
+
if not style:
|
|
603
|
+
raise HTTPException(
|
|
604
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
|
605
|
+
detail=f"Slide style {style_id} not found",
|
|
606
|
+
)
|
|
607
|
+
|
|
608
|
+
current_fp = preview_fixture.compute_fingerprint(
|
|
609
|
+
style.style_content,
|
|
610
|
+
style.image_guidelines,
|
|
611
|
+
preview_fixture.current_builder_definition(db),
|
|
612
|
+
)
|
|
613
|
+
status_val = style.preview_status or "missing"
|
|
614
|
+
|
|
615
|
+
# Load any stored payload (ready OR last-known-good) once.
|
|
616
|
+
payload = None
|
|
617
|
+
if style.preview_payload_id:
|
|
618
|
+
payload = preview_storage.load_payload(db, style.preview_payload_id)
|
|
619
|
+
|
|
620
|
+
def _resp(status_str: str, *, include_payload: bool, stale: bool = False):
|
|
621
|
+
has = include_payload and payload
|
|
622
|
+
return SlideStylePreviewResponse(
|
|
623
|
+
style_id=style_id,
|
|
624
|
+
status=status_str,
|
|
625
|
+
fingerprint=style.preview_fingerprint if include_payload else None,
|
|
626
|
+
slides=(payload or {}).get("slides") if has else None,
|
|
627
|
+
css=(payload or {}).get("css") if has else None,
|
|
628
|
+
assets=(payload or {}).get("assets") if has else None,
|
|
629
|
+
generated_at=style.preview_generated_at.isoformat()
|
|
630
|
+
if (has and style.preview_generated_at)
|
|
631
|
+
else None,
|
|
632
|
+
error_code=style.preview_error_code,
|
|
633
|
+
stale=stale,
|
|
634
|
+
)
|
|
635
|
+
|
|
636
|
+
# Ready and current (cache hit).
|
|
637
|
+
if status_val == "ready" and style.preview_fingerprint == current_fp and payload:
|
|
638
|
+
logger.info(
|
|
639
|
+
"slide_style_preview.cache_hit",
|
|
640
|
+
extra={"style_id": style_id, "status": "ready"},
|
|
641
|
+
)
|
|
642
|
+
return _resp("ready", include_payload=True)
|
|
643
|
+
|
|
644
|
+
# Ready but stale (fingerprint moved). Serve the stale copy, kick a refresh.
|
|
645
|
+
if status_val == "ready" and payload:
|
|
646
|
+
age_s = None
|
|
647
|
+
if style.preview_generated_at:
|
|
648
|
+
from datetime import datetime as _dt
|
|
649
|
+
|
|
650
|
+
age_s = (_dt.utcnow() - style.preview_generated_at).total_seconds()
|
|
651
|
+
logger.info(
|
|
652
|
+
"slide_style_preview.cache_stale",
|
|
653
|
+
extra={"style_id": style_id, "stale_age_s": age_s},
|
|
654
|
+
)
|
|
655
|
+
try_enqueue(style_id)
|
|
656
|
+
return _resp("stale", include_payload=True, stale=True)
|
|
657
|
+
|
|
658
|
+
# In flight. Serve stale copy underneath if present. try_enqueue no-ops a
|
|
659
|
+
# live job and re-queues one whose worker died, so a viewer recovers it.
|
|
660
|
+
if status_val in ("queued", "generating"):
|
|
661
|
+
try_enqueue(style_id)
|
|
662
|
+
return _resp(status_val, include_payload=bool(payload), stale=bool(payload))
|
|
663
|
+
|
|
664
|
+
# Failed. Return last-known-good if we have one; otherwise just the error.
|
|
665
|
+
if status_val == "failed":
|
|
666
|
+
return _resp("failed", include_payload=bool(payload), stale=bool(payload))
|
|
667
|
+
|
|
668
|
+
# Missing (or unknown): enqueue and report queued.
|
|
669
|
+
try_enqueue(style_id)
|
|
670
|
+
# Re-read status: try_enqueue may have transitioned it to 'queued'.
|
|
671
|
+
return SlideStylePreviewResponse(style_id=style_id, status="queued")
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
# SDR-4437 HIGH-3: workspace-global library writes are admin-only.
|
|
675
|
+
@router.post(
|
|
676
|
+
"/{style_id}/preview/regenerate",
|
|
677
|
+
response_model=SlideStylePreviewResponse,
|
|
678
|
+
dependencies=[Depends(require_admin)],
|
|
679
|
+
)
|
|
680
|
+
def regenerate_slide_style_preview(
|
|
681
|
+
style_id: int,
|
|
682
|
+
db: Session = Depends(get_db),
|
|
683
|
+
):
|
|
684
|
+
"""Explicitly (re)generate a slide-style preview. Admin-only, deduplicated.
|
|
685
|
+
|
|
686
|
+
Enqueues a background job against the current style snapshot. Idempotent: if
|
|
687
|
+
a generation is already in flight this is a no-op that returns the in-flight
|
|
688
|
+
status.
|
|
689
|
+
"""
|
|
690
|
+
from datetime import datetime as _dt
|
|
691
|
+
|
|
692
|
+
from src.api.services.slide_style_preview_queue import claimable_clause, try_enqueue
|
|
693
|
+
|
|
694
|
+
style = db.query(SlideStyleLibrary).filter(SlideStyleLibrary.id == style_id).first()
|
|
695
|
+
if not style:
|
|
696
|
+
raise HTTPException(
|
|
697
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
|
698
|
+
detail=f"Slide style {style_id} not found",
|
|
699
|
+
)
|
|
700
|
+
|
|
701
|
+
# Force a re-attempt even from a 'failed'/'ready' terminal state by clearing
|
|
702
|
+
# to 'missing' first (in its own committed txn), then enqueue. A live job is
|
|
703
|
+
# left alone (no duplicate generation); an abandoned one is claimable.
|
|
704
|
+
db.query(SlideStyleLibrary).filter(
|
|
705
|
+
SlideStyleLibrary.id == style_id, claimable_clause(_dt.utcnow())
|
|
706
|
+
).update({"preview_status": "missing"}, synchronize_session=False)
|
|
707
|
+
db.commit()
|
|
708
|
+
|
|
709
|
+
try_enqueue(style_id)
|
|
710
|
+
db.refresh(style)
|
|
711
|
+
return SlideStylePreviewResponse(
|
|
712
|
+
style_id=style_id, status=style.preview_status or "queued"
|
|
713
|
+
)
|