databricks-tellr-app 0.4.3.dev4__tar.gz → 0.4.3.dev5__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.dev4 → databricks_tellr_app-0.4.3.dev5}/PKG-INFO +1 -1
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/databricks_tellr_app.egg-info/PKG-INFO +1 -1
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/pyproject.toml +1 -1
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/chat.py +2 -2
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/export.py +4 -4
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/google_slides.py +51 -100
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/sessions.py +1 -1
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/settings/identities.py +3 -3
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/setup.py +2 -2
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/slides.py +13 -13
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/verification.py +3 -3
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/agent.py +17 -4
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/README.md +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/databricks_tellr_app/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/databricks_tellr_app/run.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/databricks_tellr_app.egg-info/SOURCES.txt +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/databricks_tellr_app.egg-info/dependency_links.txt +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/databricks_tellr_app.egg-info/requires.txt +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/databricks_tellr_app.egg-info/top_level.txt +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/setup.cfg +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/setup.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/_otel_bootstrap.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/fixtures/tour_demo_deck.json +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/main.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/mcp_auth.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/mcp_server.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/middleware/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/middleware/csrf.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/middleware/request_logging.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/middleware/security_headers.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/_authz.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/admin.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/admin_usage.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/agent_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/deck_contributors.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/feedback.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/images.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/local_version.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/profiles.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/settings/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/settings/contributors.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/settings/deck_prompts.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/settings/design_systems.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/settings/slide_styles.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/tools.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/tour.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/version.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/schemas/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/schemas/agent_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/schemas/feedback.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/schemas/requests.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/schemas/responses.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/schemas/settings/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/schemas/settings/requests.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/schemas/settings/responses.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/schemas/streaming.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/services/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/services/chat_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/services/export_job_queue.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/services/feedback_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/services/job_queue.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/services/session_manager.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/services/session_naming.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/services/usage_events.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/services/usage_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/utils/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/utils/validation.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/config_loader.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/context_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/database.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/databricks_client.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/defaults.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/encryption.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/init_default_profile.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/lakebase.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/migrate_profiles_to_agent_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/mlflow_agent_spans.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/mlflow_tracing.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/otel_logging.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/permission_context.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/prompt_modules.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/settings_db.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/core/user_context.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/deck_contributor.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/design_system.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/encryption_key.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/feedback.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/genie_space.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/google_global_credentials.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/google_oauth_token.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/identity.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/image.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/profile.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/profile_contributor.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/prompts.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/request_log.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/session.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/slide_deck_prompt.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/slide_style_library.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/usage_event.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/models/user_preference.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/database/types.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/domain/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/domain/slide.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/domain/slide_deck.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/agent_factory.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/config_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/config_validator.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/converter_jail/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/converter_jail/ast_guard.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/converter_jail/codeprep.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/converter_jail/gslides_runner.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/converter_jail/jail.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/converter_jail/pptx_runner.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/converter_jail/protocol.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/design_system_compiler.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/design_system_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/design_system_templates.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/drive_uploader.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/evaluation/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/evaluation/llm_judge.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/genie_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/google_slides_auth.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/google_slides_prompts_defaults.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/html_to_google_slides.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/html_to_pptx.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/identity_provider.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/identity_providers/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/identity_providers/account_provider.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/identity_providers/local_provider.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/identity_providers/workspace_provider.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/image_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/image_tools.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/permission_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/pptx_from_html_huashu.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/pptx_from_records.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/pptx_prompts_defaults.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/profile_service.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/streaming_callback.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/tools/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/tools/agent_bricks_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/tools/ds_asset_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/tools/genie_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/tools/mcp_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/tools/model_endpoint_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/tools/vector_tool.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/services/validator.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/utils/__init__.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/utils/css_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/utils/ds_asset_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/utils/error_handling.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/utils/html_safety.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/utils/html_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/utils/image_utils.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/utils/js_validator.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/utils/logging_config.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/utils/pi_filter.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/utils/slide_hash.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/utils/spotlight.py +0 -0
- {databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/utils/text_caps.py +0 -0
|
@@ -384,7 +384,7 @@ async def send_message(
|
|
|
384
384
|
logger.error(f"Chat request failed: {e}", exc_info=True)
|
|
385
385
|
raise HTTPException(
|
|
386
386
|
status_code=500,
|
|
387
|
-
detail="Failed to process message",
|
|
387
|
+
detail=f"Failed to process message: {str(e)}",
|
|
388
388
|
) from e
|
|
389
389
|
finally:
|
|
390
390
|
await asyncio.to_thread(
|
|
@@ -662,7 +662,7 @@ async def submit_chat_async(
|
|
|
662
662
|
session_manager.release_session_lock, request.session_id
|
|
663
663
|
)
|
|
664
664
|
logger.error(f"Failed to submit async chat: {e}")
|
|
665
|
-
raise HTTPException(status_code=500, detail=
|
|
665
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
666
666
|
|
|
667
667
|
|
|
668
668
|
@router.get("/chat/poll/{request_id}")
|
{databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/export.py
RENAMED
|
@@ -754,13 +754,13 @@ async def export_to_pptx(request: ExportPPTXRequest):
|
|
|
754
754
|
temp_dir.rmdir()
|
|
755
755
|
except Exception:
|
|
756
756
|
pass
|
|
757
|
-
raise HTTPException(status_code=500, detail="Export failed")
|
|
757
|
+
raise HTTPException(status_code=500, detail=f"Export failed: {str(e)}")
|
|
758
758
|
|
|
759
759
|
except HTTPException:
|
|
760
760
|
raise
|
|
761
761
|
except Exception as e:
|
|
762
762
|
logger.error("PPTX export failed", exc_info=True, extra={"error": str(e)})
|
|
763
|
-
raise HTTPException(status_code=500, detail="Export failed")
|
|
763
|
+
raise HTTPException(status_code=500, detail=f"Export failed: {str(e)}")
|
|
764
764
|
|
|
765
765
|
|
|
766
766
|
# =============================================================================
|
|
@@ -893,7 +893,7 @@ async def start_pptx_export_async(request: ExportPPTXRequest):
|
|
|
893
893
|
except Exception as e:
|
|
894
894
|
total_time = time.time() - start_time
|
|
895
895
|
logger.error(f"Failed to start async export after {total_time:.2f}s: {e}", exc_info=True)
|
|
896
|
-
raise HTTPException(status_code=500, detail=
|
|
896
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
897
897
|
|
|
898
898
|
|
|
899
899
|
@router.get("/pptx/poll/{job_id}", response_model=ExportJobResponse)
|
|
@@ -1038,7 +1038,7 @@ async def export_pptx_editable_from_records(request: ExportPPTXFromRecordsReques
|
|
|
1038
1038
|
pptx_bytes = build_pptx(title, request.slides, font_mode=font_mode)
|
|
1039
1039
|
except Exception as e:
|
|
1040
1040
|
logger.exception(f"Editable PPTX emission failed: {e}")
|
|
1041
|
-
raise HTTPException(status_code=500, detail=
|
|
1041
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
1042
1042
|
|
|
1043
1043
|
safe = "".join(c if c.isalnum() or c in "-_" else "_" for c in title).strip("_") or "slides"
|
|
1044
1044
|
from fastapi.responses import Response
|
{databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/google_slides.py
RENAMED
|
@@ -10,10 +10,9 @@ user tokens are stored per-user in the ``google_oauth_tokens`` table.
|
|
|
10
10
|
import json
|
|
11
11
|
import logging
|
|
12
12
|
import os
|
|
13
|
-
import secrets
|
|
14
13
|
from typing import Any, Optional
|
|
15
14
|
|
|
16
|
-
from fastapi import APIRouter, Depends, HTTPException, Query, Request
|
|
15
|
+
from fastapi import APIRouter, Depends, HTTPException, Query, Request
|
|
17
16
|
from fastapi.responses import HTMLResponse
|
|
18
17
|
from pydantic import BaseModel
|
|
19
18
|
from sqlalchemy.orm import Session
|
|
@@ -34,12 +33,6 @@ logger = logging.getLogger(__name__)
|
|
|
34
33
|
|
|
35
34
|
router = APIRouter(prefix="/api/export/google-slides", tags=["google-slides"])
|
|
36
35
|
|
|
37
|
-
# F-CR-3 (SDR-4437): the OAuth "state" carries an unguessable nonce that is also
|
|
38
|
-
# stored in this short-lived cookie; the callback requires them to match before
|
|
39
|
-
# exchanging the authorization code (anti-CSRF / anti-login-CSRF double-submit).
|
|
40
|
-
_OAUTH_STATE_COOKIE = "g_oauth_state"
|
|
41
|
-
_OAUTH_COOKIE_PATH = "/api/export/google-slides"
|
|
42
|
-
|
|
43
36
|
|
|
44
37
|
# -------------------------------------------------------------------------
|
|
45
38
|
# Helpers
|
|
@@ -105,76 +98,32 @@ class AuthUrlResponse(BaseModel):
|
|
|
105
98
|
# -------------------------------------------------------------------------
|
|
106
99
|
|
|
107
100
|
|
|
108
|
-
def
|
|
109
|
-
"""
|
|
101
|
+
def _build_redirect_uri(request: Request) -> str:
|
|
102
|
+
"""Build the OAuth callback redirect URI from the current request.
|
|
103
|
+
|
|
104
|
+
Google requires redirect URIs to match *exactly* what's registered in GCP,
|
|
105
|
+
with no query parameters.
|
|
110
106
|
|
|
111
107
|
Behind a reverse proxy (e.g. Databricks Apps), ``request.base_url``
|
|
112
108
|
returns the internal address (``http://localhost:8000``). We use the
|
|
113
109
|
``X-Forwarded-Host`` / ``X-Forwarded-Proto`` headers set by the proxy
|
|
114
|
-
to reconstruct the public URL instead.
|
|
110
|
+
to reconstruct the public URL instead.
|
|
111
|
+
|
|
112
|
+
For localhost, Google only allows ``http``.
|
|
115
113
|
"""
|
|
116
114
|
forwarded_host = request.headers.get("x-forwarded-host")
|
|
117
115
|
forwarded_proto = request.headers.get("x-forwarded-proto")
|
|
118
116
|
|
|
119
117
|
if forwarded_host:
|
|
120
118
|
scheme = forwarded_proto or "https"
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
base = str(request.base_url).rstrip("/")
|
|
124
|
-
if "://localhost" in base or "://127.0.0.1" in base:
|
|
125
|
-
base = base.replace("https://", "http://")
|
|
126
|
-
return base
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
def _build_redirect_uri(request: Request) -> str:
|
|
130
|
-
"""Build the OAuth callback redirect URI from the current request.
|
|
131
|
-
|
|
132
|
-
Google requires redirect URIs to match *exactly* what's registered in GCP,
|
|
133
|
-
with no query parameters.
|
|
134
|
-
"""
|
|
135
|
-
return f"{_build_app_origin(request)}/api/export/google-slides/auth/callback"
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
# Callback page template. The JS object braces are intentionally literal; the
|
|
139
|
-
# %TOKENS% are substituted below so the postMessage targets the explicit app
|
|
140
|
-
# origin (F-CR-3) instead of the wildcard '*'.
|
|
141
|
-
_CALLBACK_TEMPLATE = """
|
|
142
|
-
<html><body>
|
|
143
|
-
<h2>%TITLE%</h2>
|
|
144
|
-
<p>%MESSAGE%</p>
|
|
145
|
-
<script>
|
|
146
|
-
if (window.opener) {
|
|
147
|
-
window.opener.postMessage({ type: 'google-slides-auth', success: %SUCCESS% }, %ORIGIN%);
|
|
148
|
-
}
|
|
149
|
-
setTimeout(() => window.close(), %DELAY%);
|
|
150
|
-
</script>
|
|
151
|
-
</body></html>
|
|
152
|
-
"""
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
def _callback_response(app_origin: str, *, success: bool) -> HTMLResponse:
|
|
156
|
-
"""Render the popup callback page and clear the anti-CSRF state cookie.
|
|
157
|
-
|
|
158
|
-
``postMessage`` targets ``app_origin`` explicitly (F-CR-3); ``json.dumps``
|
|
159
|
-
yields a safely-quoted JS string literal for the origin.
|
|
160
|
-
"""
|
|
161
|
-
if success:
|
|
162
|
-
title, message, delay = "Authorization Successful", "You can close this window.", "1500"
|
|
119
|
+
base = f"{scheme}://{forwarded_host.split(',')[0].strip()}"
|
|
163
120
|
else:
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
.replace("%MESSAGE%", message)
|
|
171
|
-
.replace("%SUCCESS%", "true" if success else "false")
|
|
172
|
-
.replace("%ORIGIN%", json.dumps(app_origin))
|
|
173
|
-
.replace("%DELAY%", delay)
|
|
174
|
-
)
|
|
175
|
-
resp = HTMLResponse(content=body, status_code=200)
|
|
176
|
-
resp.delete_cookie(_OAUTH_STATE_COOKIE, path=_OAUTH_COOKIE_PATH)
|
|
177
|
-
return resp
|
|
121
|
+
base = str(request.base_url).rstrip("/")
|
|
122
|
+
# Force http for localhost (Google rejects https://localhost)
|
|
123
|
+
if "://localhost" in base or "://127.0.0.1" in base:
|
|
124
|
+
base = base.replace("https://", "http://")
|
|
125
|
+
|
|
126
|
+
return f"{base}/api/export/google-slides/auth/callback"
|
|
178
127
|
|
|
179
128
|
|
|
180
129
|
@router.get("/auth/status", response_model=AuthStatusResponse)
|
|
@@ -192,7 +141,6 @@ async def auth_status(db: Session = Depends(get_db)):
|
|
|
192
141
|
@router.get("/auth/url", response_model=AuthUrlResponse)
|
|
193
142
|
async def auth_url(
|
|
194
143
|
request: Request,
|
|
195
|
-
response: Response,
|
|
196
144
|
db: Session = Depends(get_db),
|
|
197
145
|
):
|
|
198
146
|
"""Generate the Google OAuth consent URL.
|
|
@@ -201,26 +149,13 @@ async def auth_url(
|
|
|
201
149
|
passed via the OAuth ``state`` parameter so the callback can persist the
|
|
202
150
|
token for the correct user — the redirect URI itself stays clean
|
|
203
151
|
(no query params) to satisfy Google's exact-match requirement.
|
|
204
|
-
|
|
205
|
-
F-CR-3: an unguessable nonce is bound into both the ``state`` and a
|
|
206
|
-
short-lived cookie; the callback requires them to match.
|
|
207
152
|
"""
|
|
208
153
|
try:
|
|
209
154
|
auth = _get_auth(db)
|
|
210
155
|
redirect_uri = _build_redirect_uri(request)
|
|
211
|
-
|
|
212
|
-
state = json.dumps({"user": _get_user_identity(), "nonce": nonce})
|
|
156
|
+
state = json.dumps({"user": _get_user_identity()})
|
|
213
157
|
url = auth.get_auth_url(redirect_uri=redirect_uri, state=state)
|
|
214
158
|
|
|
215
|
-
response.set_cookie(
|
|
216
|
-
key=_OAUTH_STATE_COOKIE,
|
|
217
|
-
value=nonce,
|
|
218
|
-
max_age=600,
|
|
219
|
-
httponly=True,
|
|
220
|
-
secure=True,
|
|
221
|
-
samesite="lax", # sent on Google's top-level redirect back to us
|
|
222
|
-
path=_OAUTH_COOKIE_PATH,
|
|
223
|
-
)
|
|
224
159
|
return AuthUrlResponse(url=url)
|
|
225
160
|
except GoogleSlidesAuthError as exc:
|
|
226
161
|
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
@@ -249,22 +184,12 @@ async def auth_callback(
|
|
|
249
184
|
them in the ``google_oauth_tokens`` table. Returns a small HTML page
|
|
250
185
|
that notifies the opener window and closes itself.
|
|
251
186
|
"""
|
|
252
|
-
app_origin = _build_app_origin(request)
|
|
253
|
-
cookie_nonce = request.cookies.get(_OAUTH_STATE_COOKIE)
|
|
254
187
|
try:
|
|
255
188
|
state_data = json.loads(state) if state else {}
|
|
256
189
|
user = state_data.get("user")
|
|
257
190
|
if not user:
|
|
258
191
|
raise ValueError("Missing user in OAuth state")
|
|
259
192
|
|
|
260
|
-
# F-CR-3: verify the anti-CSRF nonce BEFORE exchanging the code. The
|
|
261
|
-
# state nonce must match the cookie set when the auth URL was issued.
|
|
262
|
-
state_nonce = state_data.get("nonce")
|
|
263
|
-
if not cookie_nonce or not state_nonce or not secrets.compare_digest(
|
|
264
|
-
str(cookie_nonce), str(state_nonce)
|
|
265
|
-
):
|
|
266
|
-
raise ValueError("OAuth state nonce mismatch")
|
|
267
|
-
|
|
268
193
|
auth = _get_auth(db)
|
|
269
194
|
redirect_uri = _build_redirect_uri(request)
|
|
270
195
|
code_verifier = state_data.get("code_verifier")
|
|
@@ -273,13 +198,39 @@ async def auth_callback(
|
|
|
273
198
|
"Google Slides OAuth callback successful",
|
|
274
199
|
extra={"user": _get_user_identity()},
|
|
275
200
|
)
|
|
276
|
-
except Exception:
|
|
277
|
-
# F-CR-2 (SDR-4437): never reflect the raw exception into the HTML page —
|
|
278
|
-
# it is logged server-side above. Show a static, generic failure message.
|
|
201
|
+
except Exception as exc:
|
|
279
202
|
logger.error("OAuth callback failed", exc_info=True)
|
|
280
|
-
return
|
|
203
|
+
return HTMLResponse(
|
|
204
|
+
content=f"""
|
|
205
|
+
<html><body>
|
|
206
|
+
<h2>Authorization Failed</h2>
|
|
207
|
+
<p>{exc}</p>
|
|
208
|
+
<script>
|
|
209
|
+
if (window.opener) {{
|
|
210
|
+
window.opener.postMessage({{ type: 'google-slides-auth', success: false }}, '*');
|
|
211
|
+
}}
|
|
212
|
+
setTimeout(() => window.close(), 3000);
|
|
213
|
+
</script>
|
|
214
|
+
</body></html>
|
|
215
|
+
""",
|
|
216
|
+
status_code=200,
|
|
217
|
+
)
|
|
281
218
|
|
|
282
|
-
return
|
|
219
|
+
return HTMLResponse(
|
|
220
|
+
content="""
|
|
221
|
+
<html><body>
|
|
222
|
+
<h2>Authorization Successful</h2>
|
|
223
|
+
<p>You can close this window.</p>
|
|
224
|
+
<script>
|
|
225
|
+
if (window.opener) {
|
|
226
|
+
window.opener.postMessage({ type: 'google-slides-auth', success: true }, '*');
|
|
227
|
+
}
|
|
228
|
+
setTimeout(() => window.close(), 1500);
|
|
229
|
+
</script>
|
|
230
|
+
</body></html>
|
|
231
|
+
""",
|
|
232
|
+
status_code=200,
|
|
233
|
+
)
|
|
283
234
|
|
|
284
235
|
|
|
285
236
|
# -------------------------------------------------------------------------
|
|
@@ -333,7 +284,7 @@ async def start_google_slides_export(
|
|
|
333
284
|
slide_deck = chat_service.get_slides(request_body.session_id)
|
|
334
285
|
except Exception as exc:
|
|
335
286
|
logger.error("Failed to fetch slides", exc_info=True)
|
|
336
|
-
raise HTTPException(status_code=500, detail="Failed to fetch slides") from exc
|
|
287
|
+
raise HTTPException(status_code=500, detail=f"Failed to fetch slides: {exc}") from exc
|
|
337
288
|
|
|
338
289
|
if not slide_deck or not slide_deck.get("slides"):
|
|
339
290
|
raise HTTPException(status_code=404, detail="No slides available")
|
|
@@ -497,7 +448,7 @@ async def export_google_slides_from_records(
|
|
|
497
448
|
)
|
|
498
449
|
except Exception as exc:
|
|
499
450
|
logger.error("Drive upload failed", exc_info=True)
|
|
500
|
-
raise HTTPException(status_code=502, detail="Drive upload failed") from exc
|
|
451
|
+
raise HTTPException(status_code=502, detail=f"Drive upload failed: {exc}") from exc
|
|
501
452
|
|
|
502
453
|
session_manager.set_google_slides_info(
|
|
503
454
|
session_id=request.session_id,
|
|
@@ -647,7 +598,7 @@ async def export_google_slides_from_huashu(
|
|
|
647
598
|
logger.error("Drive upload failed (huashu path)", exc_info=True)
|
|
648
599
|
raise HTTPException(
|
|
649
600
|
status_code=502,
|
|
650
|
-
detail="Drive upload failed",
|
|
601
|
+
detail=f"Drive upload failed: {exc}",
|
|
651
602
|
) from exc
|
|
652
603
|
|
|
653
604
|
session_manager.set_google_slides_info(
|
{databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/sessions.py
RENAMED
|
@@ -553,7 +553,7 @@ async def duplicate_session(
|
|
|
553
553
|
logger.error(f"Failed to duplicate session: {e}", exc_info=True)
|
|
554
554
|
raise HTTPException(
|
|
555
555
|
status_code=500,
|
|
556
|
-
detail="Failed to duplicate session",
|
|
556
|
+
detail=f"Failed to duplicate session: {str(e)}",
|
|
557
557
|
) from e
|
|
558
558
|
|
|
559
559
|
|
|
@@ -109,7 +109,7 @@ def list_users(
|
|
|
109
109
|
logger.error(f"Failed to list users: {e}", exc_info=True)
|
|
110
110
|
raise HTTPException(
|
|
111
111
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
112
|
-
detail="Failed to list users",
|
|
112
|
+
detail=f"Failed to list users: {e}",
|
|
113
113
|
)
|
|
114
114
|
|
|
115
115
|
|
|
@@ -149,7 +149,7 @@ def list_groups(
|
|
|
149
149
|
logger.error(f"Failed to list groups: {e}", exc_info=True)
|
|
150
150
|
raise HTTPException(
|
|
151
151
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
152
|
-
detail="Failed to list groups",
|
|
152
|
+
detail=f"Failed to list groups: {e}",
|
|
153
153
|
)
|
|
154
154
|
|
|
155
155
|
|
|
@@ -203,5 +203,5 @@ def search_identities(
|
|
|
203
203
|
logger.error(f"Failed to search identities: {e}", exc_info=True)
|
|
204
204
|
raise HTTPException(
|
|
205
205
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
206
|
-
detail="Failed to search identities",
|
|
206
|
+
detail=f"Failed to search identities: {e}",
|
|
207
207
|
)
|
|
@@ -123,7 +123,7 @@ async def configure_workspace(request: ConfigureWorkspaceRequest):
|
|
|
123
123
|
logger.error(f"Failed to configure workspace: {e}")
|
|
124
124
|
raise HTTPException(
|
|
125
125
|
status_code=500,
|
|
126
|
-
detail="Failed to save configuration"
|
|
126
|
+
detail=f"Failed to save configuration: {str(e)}"
|
|
127
127
|
)
|
|
128
128
|
|
|
129
129
|
|
|
@@ -154,5 +154,5 @@ async def test_connection():
|
|
|
154
154
|
logger.error(f"Connection test failed: {e}")
|
|
155
155
|
raise HTTPException(
|
|
156
156
|
status_code=400,
|
|
157
|
-
detail="Connection failed"
|
|
157
|
+
detail=f"Connection failed: {str(e)}"
|
|
158
158
|
)
|
{databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/slides.py
RENAMED
|
@@ -105,7 +105,7 @@ async def get_slides(
|
|
|
105
105
|
raise
|
|
106
106
|
except Exception as e:
|
|
107
107
|
logger.error(f"Failed to get slides: {e}", exc_info=True)
|
|
108
|
-
raise HTTPException(status_code=500, detail=
|
|
108
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
109
109
|
|
|
110
110
|
|
|
111
111
|
@router.put("/reorder")
|
|
@@ -167,7 +167,7 @@ async def reorder_slides(request: ReorderRequest, db: Session = Depends(get_db))
|
|
|
167
167
|
raise HTTPException(status_code=400, detail=str(e))
|
|
168
168
|
except Exception as e:
|
|
169
169
|
logger.error(f"Failed to reorder slides: {e}", exc_info=True)
|
|
170
|
-
raise HTTPException(status_code=500, detail=
|
|
170
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
171
171
|
finally:
|
|
172
172
|
await asyncio.to_thread(
|
|
173
173
|
session_manager.release_session_lock,
|
|
@@ -235,7 +235,7 @@ async def update_slide(index: int, request: UpdateSlideRequest, db: Session = De
|
|
|
235
235
|
raise HTTPException(status_code=400, detail=str(e))
|
|
236
236
|
except Exception as e:
|
|
237
237
|
logger.error(f"Failed to update slide: {e}", exc_info=True)
|
|
238
|
-
raise HTTPException(status_code=500, detail=
|
|
238
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
239
239
|
finally:
|
|
240
240
|
await asyncio.to_thread(
|
|
241
241
|
session_manager.release_session_lock,
|
|
@@ -303,7 +303,7 @@ async def duplicate_slide(index: int, request: SlideActionRequest, db: Session =
|
|
|
303
303
|
raise HTTPException(status_code=400, detail=str(e))
|
|
304
304
|
except Exception as e:
|
|
305
305
|
logger.error(f"Failed to duplicate slide: {e}", exc_info=True)
|
|
306
|
-
raise HTTPException(status_code=500, detail=
|
|
306
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
307
307
|
finally:
|
|
308
308
|
await asyncio.to_thread(
|
|
309
309
|
session_manager.release_session_lock,
|
|
@@ -377,7 +377,7 @@ async def delete_slide(
|
|
|
377
377
|
raise HTTPException(status_code=400, detail=str(e))
|
|
378
378
|
except Exception as e:
|
|
379
379
|
logger.error(f"Failed to delete slide: {e}", exc_info=True)
|
|
380
|
-
raise HTTPException(status_code=500, detail=
|
|
380
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
381
381
|
finally:
|
|
382
382
|
await asyncio.to_thread(
|
|
383
383
|
session_manager.release_session_lock,
|
|
@@ -476,7 +476,7 @@ async def update_slide_verification(index: int, request: UpdateVerificationReque
|
|
|
476
476
|
raise
|
|
477
477
|
except Exception as e:
|
|
478
478
|
logger.error(f"Failed to update slide verification: {e}", exc_info=True)
|
|
479
|
-
raise HTTPException(status_code=500, detail=
|
|
479
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
480
480
|
|
|
481
481
|
|
|
482
482
|
# ============================================================================
|
|
@@ -546,7 +546,7 @@ async def create_version(request: CreateVersionRequest):
|
|
|
546
546
|
raise HTTPException(status_code=400, detail=str(e))
|
|
547
547
|
except Exception as e:
|
|
548
548
|
logger.error(f"Failed to create version: {e}", exc_info=True)
|
|
549
|
-
raise HTTPException(status_code=500, detail=
|
|
549
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
550
550
|
|
|
551
551
|
|
|
552
552
|
@router.patch("/versions/{version_number}/verification")
|
|
@@ -595,7 +595,7 @@ async def update_version_verification(
|
|
|
595
595
|
raise HTTPException(status_code=400, detail=str(e))
|
|
596
596
|
except Exception as e:
|
|
597
597
|
logger.error(f"Failed to update version verification: {e}", exc_info=True)
|
|
598
|
-
raise HTTPException(status_code=500, detail=
|
|
598
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
599
599
|
|
|
600
600
|
|
|
601
601
|
class SyncVerificationRequest(BaseModel):
|
|
@@ -663,7 +663,7 @@ async def sync_latest_version_verification(request: SyncVerificationRequest):
|
|
|
663
663
|
|
|
664
664
|
except Exception as e:
|
|
665
665
|
logger.error(f"Failed to sync version verification: {e}", exc_info=True)
|
|
666
|
-
raise HTTPException(status_code=500, detail=
|
|
666
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
667
667
|
|
|
668
668
|
|
|
669
669
|
@router.get("/versions")
|
|
@@ -701,7 +701,7 @@ async def list_versions(session_id: str = Query(..., description="Session ID")):
|
|
|
701
701
|
return {"versions": [], "current_version": None}
|
|
702
702
|
except Exception as e:
|
|
703
703
|
logger.error(f"Failed to list versions: {e}", exc_info=True)
|
|
704
|
-
raise HTTPException(status_code=500, detail=
|
|
704
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
705
705
|
|
|
706
706
|
|
|
707
707
|
# NOTE: must be registered BEFORE the parameterized "/versions/{version_number}"
|
|
@@ -738,7 +738,7 @@ async def get_current_version(session_id: str = Query(..., description="Session
|
|
|
738
738
|
return {"current_version": None}
|
|
739
739
|
except Exception as e:
|
|
740
740
|
logger.error(f"Failed to get current version: {e}", exc_info=True)
|
|
741
|
-
raise HTTPException(status_code=500, detail=
|
|
741
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
742
742
|
|
|
743
743
|
|
|
744
744
|
@router.get("/versions/{version_number}")
|
|
@@ -789,7 +789,7 @@ async def preview_version(
|
|
|
789
789
|
raise
|
|
790
790
|
except Exception as e:
|
|
791
791
|
logger.error(f"Failed to preview version: {e}", exc_info=True)
|
|
792
|
-
raise HTTPException(status_code=500, detail=
|
|
792
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
793
793
|
|
|
794
794
|
|
|
795
795
|
@router.post("/versions/{version_number}/restore")
|
|
@@ -859,7 +859,7 @@ async def restore_version(version_number: int, request: RestoreVersionRequest):
|
|
|
859
859
|
raise HTTPException(status_code=400, detail=str(e))
|
|
860
860
|
except Exception as e:
|
|
861
861
|
logger.error(f"Failed to restore version: {e}", exc_info=True)
|
|
862
|
-
raise HTTPException(status_code=500, detail=
|
|
862
|
+
raise HTTPException(status_code=500, detail=str(e))
|
|
863
863
|
finally:
|
|
864
864
|
await asyncio.to_thread(
|
|
865
865
|
session_manager.release_session_lock,
|
{databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/verification.py
RENAMED
|
@@ -291,7 +291,7 @@ async def verify_slide(slide_index: int, request: VerifySlideRequest):
|
|
|
291
291
|
logger.error(f"Verification failed: {e}", exc_info=True)
|
|
292
292
|
raise HTTPException(
|
|
293
293
|
status_code=500,
|
|
294
|
-
detail="Verification failed",
|
|
294
|
+
detail=f"Verification failed: {str(e)}",
|
|
295
295
|
)
|
|
296
296
|
|
|
297
297
|
|
|
@@ -413,7 +413,7 @@ async def submit_feedback(slide_index: int, request: FeedbackRequest):
|
|
|
413
413
|
logger.error(f"Failed to submit feedback: {e}", exc_info=True)
|
|
414
414
|
raise HTTPException(
|
|
415
415
|
status_code=500,
|
|
416
|
-
detail="Failed to submit feedback",
|
|
416
|
+
detail=f"Failed to submit feedback: {str(e)}",
|
|
417
417
|
)
|
|
418
418
|
|
|
419
419
|
|
|
@@ -541,6 +541,6 @@ async def get_genie_link(
|
|
|
541
541
|
logger.error(f"Failed to get Genie link: {e}", exc_info=True)
|
|
542
542
|
raise HTTPException(
|
|
543
543
|
status_code=500,
|
|
544
|
-
detail="Failed to get Genie link",
|
|
544
|
+
detail=f"Failed to get Genie link: {str(e)}",
|
|
545
545
|
)
|
|
546
546
|
|
|
@@ -49,6 +49,7 @@ from src.utils.html_utils import (
|
|
|
49
49
|
split_script_by_canvas,
|
|
50
50
|
)
|
|
51
51
|
from src.utils.js_validator import validate_and_fix_javascript
|
|
52
|
+
from src.utils.spotlight import spotlight
|
|
52
53
|
from src.utils.text_caps import cap_tool_output
|
|
53
54
|
|
|
54
55
|
logger = logging.getLogger(__name__)
|
|
@@ -882,14 +883,24 @@ class SlideGeneratorAgent:
|
|
|
882
883
|
return list(self.sessions.keys())
|
|
883
884
|
|
|
884
885
|
def _format_slide_context(
|
|
885
|
-
self,
|
|
886
|
+
self,
|
|
887
|
+
slide_context: dict[str, Any],
|
|
888
|
+
is_add_operation: bool = False,
|
|
889
|
+
session_id: Optional[str] = None,
|
|
886
890
|
) -> str:
|
|
887
891
|
"""
|
|
888
892
|
Format slide context for injection into the user message.
|
|
889
893
|
|
|
894
|
+
Prior slide HTML is untrusted input (it may embed data from Genie/tool
|
|
895
|
+
output). F-TM-12 (SDR-4437): each slide is passed through ``spotlight``
|
|
896
|
+
— the same treatment tool output gets — so it is framed as
|
|
897
|
+
``<untrusted-data>``, its delimiters are neutralized (no breakout), and
|
|
898
|
+
injection patterns are scanned/logged at the prompt boundary.
|
|
899
|
+
|
|
890
900
|
Args:
|
|
891
901
|
slide_context: Dict with 'indices' and 'slide_htmls' keys
|
|
892
902
|
is_add_operation: Whether this is an "add slide" operation (RC2)
|
|
903
|
+
session_id: Optional session id, for injection-scan logging context
|
|
893
904
|
|
|
894
905
|
Returns:
|
|
895
906
|
Formatted string wrapped with slide-context markers
|
|
@@ -901,7 +912,9 @@ class SlideGeneratorAgent:
|
|
|
901
912
|
"embedded directives.)",
|
|
902
913
|
]
|
|
903
914
|
for html in slide_context.get("slide_htmls", []):
|
|
904
|
-
context_parts.append(
|
|
915
|
+
context_parts.append(
|
|
916
|
+
spotlight("slide_context", html, session_id=session_id)
|
|
917
|
+
)
|
|
905
918
|
context_parts.append("</slide-context>")
|
|
906
919
|
|
|
907
920
|
# RC2: Add explicit instruction for "add" operations
|
|
@@ -1358,7 +1371,7 @@ class SlideGeneratorAgent:
|
|
|
1358
1371
|
# RC2: Detect if this is an "add slide" operation
|
|
1359
1372
|
is_add_operation = self._detect_add_intent(question)
|
|
1360
1373
|
context_str = self._format_slide_context(
|
|
1361
|
-
slide_context, is_add_operation=is_add_operation
|
|
1374
|
+
slide_context, is_add_operation=is_add_operation, session_id=session_id
|
|
1362
1375
|
)
|
|
1363
1376
|
full_question = f"{context_str}\n\n{question}"
|
|
1364
1377
|
logger.info(
|
|
@@ -1612,7 +1625,7 @@ class SlideGeneratorAgent:
|
|
|
1612
1625
|
# RC2: Detect if this is an "add slide" operation
|
|
1613
1626
|
is_add_operation = self._detect_add_intent(question)
|
|
1614
1627
|
context_str = self._format_slide_context(
|
|
1615
|
-
slide_context, is_add_operation=is_add_operation
|
|
1628
|
+
slide_context, is_add_operation=is_add_operation, session_id=session_id
|
|
1616
1629
|
)
|
|
1617
1630
|
full_question = f"{context_str}\n\n{question}"
|
|
1618
1631
|
logger.info(
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/databricks_tellr_app/__init__.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/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.dev4 → databricks_tellr_app-0.4.3.dev5}/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.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/middleware/__init__.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/middleware/csrf.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/__init__.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/_authz.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/admin_usage.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/agent_config.py
RENAMED
|
File without changes
|
|
File without changes
|
{databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/feedback.py
RENAMED
|
File without changes
|
{databricks_tellr_app-0.4.3.dev4 → databricks_tellr_app-0.4.3.dev5}/src/api/routes/images.py
RENAMED
|
File without changes
|