databricks-tellr-app 0.4.3.dev19__tar.gz → 0.4.3.dev20__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.
Files changed (180) hide show
  1. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/PKG-INFO +10 -8
  2. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/databricks_tellr_app/run.py +45 -0
  3. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/databricks_tellr_app.egg-info/PKG-INFO +10 -8
  4. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/databricks_tellr_app.egg-info/SOURCES.txt +24 -0
  5. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/databricks_tellr_app.egg-info/requires.txt +9 -7
  6. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/pyproject.toml +17 -8
  7. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/main.py +2 -14
  8. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/mcp_auth.py +25 -36
  9. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/chat.py +12 -0
  10. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/sessions.py +22 -5
  11. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/settings/design_systems.py +2 -22
  12. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/slides.py +4 -4
  13. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/verification.py +9 -9
  14. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/version.py +2 -6
  15. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/schemas/agent_config.py +4 -10
  16. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/schemas/settings/requests.py +0 -11
  17. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/schemas/settings/responses.py +0 -2
  18. databricks_tellr_app-0.4.3.dev20/src/api/services/deck_level_writer.py +332 -0
  19. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/services/session_manager.py +972 -45
  20. databricks_tellr_app-0.4.3.dev20/src/api/services/slide_repository.py +378 -0
  21. databricks_tellr_app-0.4.3.dev20/src/core/backfill_session_slides_startup.py +315 -0
  22. databricks_tellr_app-0.4.3.dev20/src/core/checkpointer.py +488 -0
  23. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/config_loader.py +4 -11
  24. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/database.py +375 -0
  25. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/databricks_client.py +0 -50
  26. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/defaults.py +9 -0
  27. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/encryption.py +32 -54
  28. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/init_default_profile.py +0 -5
  29. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/migrate_profiles_to_agent_config.py +4 -28
  30. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/settings_db.py +3 -2
  31. databricks_tellr_app-0.4.3.dev20/src/core/strip_retired_prompt_keys.py +210 -0
  32. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/__init__.py +8 -0
  33. databricks_tellr_app-0.4.3.dev20/src/database/models/deck_review.py +77 -0
  34. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/encryption_key.py +2 -6
  35. databricks_tellr_app-0.4.3.dev20/src/database/models/graph_checkpoint.py +104 -0
  36. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/prompts.py +7 -6
  37. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/session.py +127 -1
  38. databricks_tellr_app-0.4.3.dev20/src/domain/deck_spec.py +166 -0
  39. databricks_tellr_app-0.4.3.dev20/src/domain/finding.py +313 -0
  40. databricks_tellr_app-0.4.3.dev20/src/domain/skill_io.py +259 -0
  41. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/agent.py +24 -5
  42. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/agent_factory.py +19 -35
  43. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/config_service.py +0 -12
  44. databricks_tellr_app-0.4.3.dev20/src/services/deck_css_aggregator.py +190 -0
  45. databricks_tellr_app-0.4.3.dev20/src/services/deck_review_store.py +263 -0
  46. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/design_system_compiler.py +1 -20
  47. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/profile_service.py +0 -7
  48. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/validator.py +6 -10
  49. databricks_tellr_app-0.4.3.dev20/src/utils/css_utils.py +289 -0
  50. databricks_tellr_app-0.4.3.dev19/src/utils/css_utils.py +0 -78
  51. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/README.md +0 -0
  52. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/databricks_tellr_app/__init__.py +0 -0
  53. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/databricks_tellr_app.egg-info/dependency_links.txt +0 -0
  54. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/databricks_tellr_app.egg-info/top_level.txt +0 -0
  55. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/setup.cfg +0 -0
  56. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/setup.py +0 -0
  57. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/__init__.py +0 -0
  58. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/__init__.py +0 -0
  59. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/_otel_bootstrap.py +0 -0
  60. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/fixtures/tour_demo_deck.json +0 -0
  61. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/mcp_server.py +0 -0
  62. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/middleware/__init__.py +0 -0
  63. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/middleware/csrf.py +0 -0
  64. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/middleware/request_logging.py +0 -0
  65. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/middleware/security_headers.py +0 -0
  66. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/__init__.py +0 -0
  67. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/_authz.py +0 -0
  68. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/admin.py +0 -0
  69. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/admin_usage.py +0 -0
  70. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/agent_config.py +0 -0
  71. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/deck_contributors.py +0 -0
  72. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/export.py +0 -0
  73. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/feedback.py +0 -0
  74. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/google_slides.py +0 -0
  75. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/images.py +0 -0
  76. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/local_version.py +0 -0
  77. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/profiles.py +0 -0
  78. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/settings/__init__.py +0 -0
  79. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/settings/contributors.py +0 -0
  80. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/settings/deck_prompts.py +0 -0
  81. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/settings/identities.py +0 -0
  82. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/settings/slide_styles.py +0 -0
  83. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/setup.py +0 -0
  84. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/tools.py +0 -0
  85. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/routes/tour.py +0 -0
  86. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/schemas/__init__.py +0 -0
  87. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/schemas/feedback.py +0 -0
  88. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/schemas/requests.py +0 -0
  89. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/schemas/responses.py +0 -0
  90. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/schemas/settings/__init__.py +0 -0
  91. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/schemas/streaming.py +0 -0
  92. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/services/__init__.py +0 -0
  93. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/services/chat_service.py +0 -0
  94. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/services/export_job_queue.py +0 -0
  95. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/services/feedback_service.py +0 -0
  96. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/services/job_queue.py +0 -0
  97. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/services/session_naming.py +0 -0
  98. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/services/usage_events.py +0 -0
  99. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/services/usage_service.py +0 -0
  100. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/utils/__init__.py +0 -0
  101. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/api/utils/validation.py +0 -0
  102. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/__init__.py +0 -0
  103. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/context_utils.py +0 -0
  104. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/lakebase.py +0 -0
  105. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/mlflow_agent_spans.py +0 -0
  106. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/mlflow_tracing.py +0 -0
  107. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/otel_logging.py +0 -0
  108. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/permission_context.py +0 -0
  109. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/prompt_modules.py +0 -0
  110. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/core/user_context.py +0 -0
  111. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/__init__.py +0 -0
  112. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/deck_contributor.py +0 -0
  113. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/design_system.py +0 -0
  114. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/feedback.py +0 -0
  115. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/genie_space.py +0 -0
  116. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/google_global_credentials.py +0 -0
  117. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/google_oauth_token.py +0 -0
  118. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/identity.py +0 -0
  119. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/image.py +0 -0
  120. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/profile.py +0 -0
  121. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/profile_contributor.py +0 -0
  122. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/request_log.py +0 -0
  123. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/slide_deck_prompt.py +0 -0
  124. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/slide_style_library.py +0 -0
  125. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/usage_event.py +0 -0
  126. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/models/user_preference.py +0 -0
  127. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/database/types.py +0 -0
  128. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/domain/__init__.py +0 -0
  129. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/domain/slide.py +0 -0
  130. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/domain/slide_deck.py +0 -0
  131. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/__init__.py +0 -0
  132. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/config_validator.py +0 -0
  133. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/converter_jail/__init__.py +0 -0
  134. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/converter_jail/ast_guard.py +0 -0
  135. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/converter_jail/codeprep.py +0 -0
  136. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/converter_jail/gslides_runner.py +0 -0
  137. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/converter_jail/jail.py +0 -0
  138. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/converter_jail/pptx_runner.py +0 -0
  139. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/converter_jail/protocol.py +0 -0
  140. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/design_system_service.py +0 -0
  141. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/design_system_templates.py +0 -0
  142. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/drive_uploader.py +0 -0
  143. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/evaluation/__init__.py +0 -0
  144. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/evaluation/llm_judge.py +0 -0
  145. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/genie_service.py +0 -0
  146. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/google_slides_auth.py +0 -0
  147. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/google_slides_prompts_defaults.py +0 -0
  148. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/html_to_google_slides.py +0 -0
  149. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/html_to_pptx.py +0 -0
  150. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/identity_provider.py +0 -0
  151. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/identity_providers/__init__.py +0 -0
  152. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/identity_providers/account_provider.py +0 -0
  153. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/identity_providers/local_provider.py +0 -0
  154. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/identity_providers/workspace_provider.py +0 -0
  155. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/image_service.py +0 -0
  156. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/image_tools.py +0 -0
  157. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/permission_service.py +0 -0
  158. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/pptx_from_html_huashu.py +0 -0
  159. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/pptx_from_records.py +0 -0
  160. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/pptx_prompts_defaults.py +0 -0
  161. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/streaming_callback.py +0 -0
  162. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/tools/__init__.py +0 -0
  163. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/tools/agent_bricks_tool.py +0 -0
  164. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/tools/ds_asset_tool.py +0 -0
  165. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/tools/genie_tool.py +0 -0
  166. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/tools/mcp_tool.py +0 -0
  167. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/tools/model_endpoint_tool.py +0 -0
  168. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/services/tools/vector_tool.py +0 -0
  169. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/utils/__init__.py +0 -0
  170. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/utils/ds_asset_utils.py +0 -0
  171. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/utils/error_handling.py +0 -0
  172. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/utils/html_safety.py +0 -0
  173. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/utils/html_utils.py +0 -0
  174. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/utils/image_utils.py +0 -0
  175. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/utils/js_validator.py +0 -0
  176. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/utils/logging_config.py +0 -0
  177. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/utils/pi_filter.py +0 -0
  178. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/utils/slide_hash.py +0 -0
  179. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/src/utils/spotlight.py +0 -0
  180. {databricks_tellr_app-0.4.3.dev19 → databricks_tellr_app-0.4.3.dev20}/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.dev19
3
+ Version: 0.4.3.dev20
4
4
  Summary: Tellr application package for Databricks Apps
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -10,10 +10,10 @@ Requires-Dist: python-multipart==0.0.20
10
10
  Requires-Dist: pydantic==2.12.4
11
11
  Requires-Dist: pydantic-settings==2.12.0
12
12
  Requires-Dist: databricks-langchain==0.9.0
13
- Requires-Dist: langchain==1.0.5
14
- Requires-Dist: langchain-core==1.0.4
15
- Requires-Dist: langchain-community==0.4.1
16
- Requires-Dist: langchain-text-splitters==1.0.0
13
+ Requires-Dist: langchain==1.3.14
14
+ Requires-Dist: langchain-core==1.5.3
15
+ Requires-Dist: langchain-community==0.4.2
16
+ Requires-Dist: langchain-text-splitters==1.1.2
17
17
  Requires-Dist: litellm==1.80.11
18
18
  Requires-Dist: mcp==1.27.0
19
19
  Requires-Dist: opentelemetry-api==1.38.0
@@ -47,9 +47,11 @@ Requires-Dist: databricks-ai-bridge==0.21.0
47
47
  Requires-Dist: databricks-ai-search==0.76
48
48
  Requires-Dist: databricks-connect==16.1.7
49
49
  Requires-Dist: databricks-vectorsearch==0.75
50
- Requires-Dist: langchain-classic==1.0.0
51
- Requires-Dist: langgraph==1.0.10
52
- Requires-Dist: langgraph-prebuilt==1.0.10
50
+ Requires-Dist: langchain-classic==1.0.8
51
+ Requires-Dist: langgraph==1.2.10
52
+ Requires-Dist: langgraph-checkpoint==4.1.1
53
+ Requires-Dist: langgraph-prebuilt==1.1.0
54
+ Requires-Dist: langgraph-sdk==0.4.2
53
55
  Requires-Dist: langsmith==0.9.5
54
56
  Requires-Dist: unitycatalog-ai==0.3.2
55
57
  Requires-Dist: unitycatalog-langchain==0.3.0
@@ -74,6 +74,29 @@ def init_database(seed_databricks_defaults: bool = False) -> None:
74
74
  logger.error(f"Failed to migrate profiles/sessions to agent_config: {e}\n{tb}")
75
75
  raise SystemExit(1) from e
76
76
 
77
+ # Row-per-slide (PR1): migrate historical deck_json blobs into session_slides
78
+ # rows. Runs HERE, pre-fork, for the same reason as the two migrations above —
79
+ # the uvicorn workers must never execute migration code. It originally lived in
80
+ # the FastAPI lifespan; main moved migrations out of the lifespan while this
81
+ # branch was in flight, so it was relocated on merge rather than dropped.
82
+ #
83
+ # Guarded by a per-deck NOT EXISTS anti-join over session_slides (index-only
84
+ # against its composite PK), so it is a no-op scan once every deck has rows.
85
+ # A deck whose blob will not parse is logged and skipped, never raised — one
86
+ # bad row must not abort startup.
87
+ logger.info("Backfilling session_slides rows...")
88
+ try:
89
+ from src.core.database import get_session_local
90
+ from src.core.backfill_session_slides_startup import backfill_unmigrated_decks
91
+
92
+ slide_decks = backfill_unmigrated_decks(get_session_local())
93
+ if slide_decks:
94
+ logger.info(f"Backfilled {slide_decks} deck(s) into session_slides rows")
95
+ except Exception as e:
96
+ tb = traceback.format_exc()
97
+ logger.error(f"Failed to backfill session_slides rows: {e}\n{tb}")
98
+ raise SystemExit(1) from e
99
+
77
100
  # Seed default content
78
101
  logger.info(f"Seeding defaults (include_databricks={seed_databricks_defaults})...")
79
102
  try:
@@ -97,6 +120,28 @@ def init_database(seed_databricks_defaults: bool = False) -> None:
97
120
  logger.error(f"Failed to ensure encryption key: {e}\n{tb}")
98
121
  raise SystemExit(1) from e
99
122
 
123
+ # Retired prompt overrides: strip 'system_prompt' and
124
+ # 'slide_editing_instructions' out of every stored agent_config blob. The
125
+ # physical columns are dropped inside init_db()'s migration chain, early,
126
+ # because a database that still has them cannot insert a profile; the BLOB
127
+ # strip runs LAST, deliberately — it is the one position no later step can
128
+ # undo by writing a fresh blob (seed_defaults above creates profiles).
129
+ # A blob that will not parse is logged and skipped, never raised, so one bad
130
+ # row cannot abort startup; anything else here is SystemExit(1) like the five
131
+ # steps above.
132
+ logger.info("Stripping retired prompt keys from agent_config blobs...")
133
+ try:
134
+ from src.core.database import get_session_local
135
+ from src.core.strip_retired_prompt_keys import strip_retired_prompt_keys
136
+
137
+ stripped = strip_retired_prompt_keys(get_session_local())
138
+ if stripped:
139
+ logger.info(f"Stripped retired prompt keys from {stripped} row(s)")
140
+ except Exception as e:
141
+ tb = traceback.format_exc()
142
+ logger.error(f"Failed to strip retired prompt keys from agent_config: {e}\n{tb}")
143
+ raise SystemExit(1) from e
144
+
100
145
 
101
146
  def main() -> None:
102
147
  """Start the uvicorn server."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: databricks-tellr-app
3
- Version: 0.4.3.dev19
3
+ Version: 0.4.3.dev20
4
4
  Summary: Tellr application package for Databricks Apps
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -10,10 +10,10 @@ Requires-Dist: python-multipart==0.0.20
10
10
  Requires-Dist: pydantic==2.12.4
11
11
  Requires-Dist: pydantic-settings==2.12.0
12
12
  Requires-Dist: databricks-langchain==0.9.0
13
- Requires-Dist: langchain==1.0.5
14
- Requires-Dist: langchain-core==1.0.4
15
- Requires-Dist: langchain-community==0.4.1
16
- Requires-Dist: langchain-text-splitters==1.0.0
13
+ Requires-Dist: langchain==1.3.14
14
+ Requires-Dist: langchain-core==1.5.3
15
+ Requires-Dist: langchain-community==0.4.2
16
+ Requires-Dist: langchain-text-splitters==1.1.2
17
17
  Requires-Dist: litellm==1.80.11
18
18
  Requires-Dist: mcp==1.27.0
19
19
  Requires-Dist: opentelemetry-api==1.38.0
@@ -47,9 +47,11 @@ Requires-Dist: databricks-ai-bridge==0.21.0
47
47
  Requires-Dist: databricks-ai-search==0.76
48
48
  Requires-Dist: databricks-connect==16.1.7
49
49
  Requires-Dist: databricks-vectorsearch==0.75
50
- Requires-Dist: langchain-classic==1.0.0
51
- Requires-Dist: langgraph==1.0.10
52
- Requires-Dist: langgraph-prebuilt==1.0.10
50
+ Requires-Dist: langchain-classic==1.0.8
51
+ Requires-Dist: langgraph==1.2.10
52
+ Requires-Dist: langgraph-checkpoint==4.1.1
53
+ Requires-Dist: langgraph-prebuilt==1.1.0
54
+ Requires-Dist: langgraph-sdk==0.4.2
53
55
  Requires-Dist: langsmith==0.9.5
54
56
  Requires-Dist: unitycatalog-ai==0.3.2
55
57
  Requires-Dist: unitycatalog-langchain==0.3.0
@@ -51,16 +51,20 @@ setup.py
51
51
  ./src/api/schemas/settings/responses.py
52
52
  ./src/api/services/__init__.py
53
53
  ./src/api/services/chat_service.py
54
+ ./src/api/services/deck_level_writer.py
54
55
  ./src/api/services/export_job_queue.py
55
56
  ./src/api/services/feedback_service.py
56
57
  ./src/api/services/job_queue.py
57
58
  ./src/api/services/session_manager.py
58
59
  ./src/api/services/session_naming.py
60
+ ./src/api/services/slide_repository.py
59
61
  ./src/api/services/usage_events.py
60
62
  ./src/api/services/usage_service.py
61
63
  ./src/api/utils/__init__.py
62
64
  ./src/api/utils/validation.py
63
65
  ./src/core/__init__.py
66
+ ./src/core/backfill_session_slides_startup.py
67
+ ./src/core/checkpointer.py
64
68
  ./src/core/config_loader.py
65
69
  ./src/core/context_utils.py
66
70
  ./src/core/database.py
@@ -76,17 +80,20 @@ setup.py
76
80
  ./src/core/permission_context.py
77
81
  ./src/core/prompt_modules.py
78
82
  ./src/core/settings_db.py
83
+ ./src/core/strip_retired_prompt_keys.py
79
84
  ./src/core/user_context.py
80
85
  ./src/database/__init__.py
81
86
  ./src/database/types.py
82
87
  ./src/database/models/__init__.py
83
88
  ./src/database/models/deck_contributor.py
89
+ ./src/database/models/deck_review.py
84
90
  ./src/database/models/design_system.py
85
91
  ./src/database/models/encryption_key.py
86
92
  ./src/database/models/feedback.py
87
93
  ./src/database/models/genie_space.py
88
94
  ./src/database/models/google_global_credentials.py
89
95
  ./src/database/models/google_oauth_token.py
96
+ ./src/database/models/graph_checkpoint.py
90
97
  ./src/database/models/identity.py
91
98
  ./src/database/models/image.py
92
99
  ./src/database/models/profile.py
@@ -99,6 +106,9 @@ setup.py
99
106
  ./src/database/models/usage_event.py
100
107
  ./src/database/models/user_preference.py
101
108
  ./src/domain/__init__.py
109
+ ./src/domain/deck_spec.py
110
+ ./src/domain/finding.py
111
+ ./src/domain/skill_io.py
102
112
  ./src/domain/slide.py
103
113
  ./src/domain/slide_deck.py
104
114
  ./src/services/__init__.py
@@ -106,6 +116,8 @@ setup.py
106
116
  ./src/services/agent_factory.py
107
117
  ./src/services/config_service.py
108
118
  ./src/services/config_validator.py
119
+ ./src/services/deck_css_aggregator.py
120
+ ./src/services/deck_review_store.py
109
121
  ./src/services/design_system_compiler.py
110
122
  ./src/services/design_system_service.py
111
123
  ./src/services/design_system_templates.py
@@ -213,16 +225,20 @@ src/api/schemas/settings/requests.py
213
225
  src/api/schemas/settings/responses.py
214
226
  src/api/services/__init__.py
215
227
  src/api/services/chat_service.py
228
+ src/api/services/deck_level_writer.py
216
229
  src/api/services/export_job_queue.py
217
230
  src/api/services/feedback_service.py
218
231
  src/api/services/job_queue.py
219
232
  src/api/services/session_manager.py
220
233
  src/api/services/session_naming.py
234
+ src/api/services/slide_repository.py
221
235
  src/api/services/usage_events.py
222
236
  src/api/services/usage_service.py
223
237
  src/api/utils/__init__.py
224
238
  src/api/utils/validation.py
225
239
  src/core/__init__.py
240
+ src/core/backfill_session_slides_startup.py
241
+ src/core/checkpointer.py
226
242
  src/core/config_loader.py
227
243
  src/core/context_utils.py
228
244
  src/core/database.py
@@ -238,17 +254,20 @@ src/core/otel_logging.py
238
254
  src/core/permission_context.py
239
255
  src/core/prompt_modules.py
240
256
  src/core/settings_db.py
257
+ src/core/strip_retired_prompt_keys.py
241
258
  src/core/user_context.py
242
259
  src/database/__init__.py
243
260
  src/database/types.py
244
261
  src/database/models/__init__.py
245
262
  src/database/models/deck_contributor.py
263
+ src/database/models/deck_review.py
246
264
  src/database/models/design_system.py
247
265
  src/database/models/encryption_key.py
248
266
  src/database/models/feedback.py
249
267
  src/database/models/genie_space.py
250
268
  src/database/models/google_global_credentials.py
251
269
  src/database/models/google_oauth_token.py
270
+ src/database/models/graph_checkpoint.py
252
271
  src/database/models/identity.py
253
272
  src/database/models/image.py
254
273
  src/database/models/profile.py
@@ -261,6 +280,9 @@ src/database/models/slide_style_library.py
261
280
  src/database/models/usage_event.py
262
281
  src/database/models/user_preference.py
263
282
  src/domain/__init__.py
283
+ src/domain/deck_spec.py
284
+ src/domain/finding.py
285
+ src/domain/skill_io.py
264
286
  src/domain/slide.py
265
287
  src/domain/slide_deck.py
266
288
  src/services/__init__.py
@@ -268,6 +290,8 @@ src/services/agent.py
268
290
  src/services/agent_factory.py
269
291
  src/services/config_service.py
270
292
  src/services/config_validator.py
293
+ src/services/deck_css_aggregator.py
294
+ src/services/deck_review_store.py
271
295
  src/services/design_system_compiler.py
272
296
  src/services/design_system_service.py
273
297
  src/services/design_system_templates.py
@@ -4,10 +4,10 @@ python-multipart==0.0.20
4
4
  pydantic==2.12.4
5
5
  pydantic-settings==2.12.0
6
6
  databricks-langchain==0.9.0
7
- langchain==1.0.5
8
- langchain-core==1.0.4
9
- langchain-community==0.4.1
10
- langchain-text-splitters==1.0.0
7
+ langchain==1.3.14
8
+ langchain-core==1.5.3
9
+ langchain-community==0.4.2
10
+ langchain-text-splitters==1.1.2
11
11
  litellm==1.80.11
12
12
  mcp==1.27.0
13
13
  opentelemetry-api==1.38.0
@@ -41,9 +41,11 @@ databricks-ai-bridge==0.21.0
41
41
  databricks-ai-search==0.76
42
42
  databricks-connect==16.1.7
43
43
  databricks-vectorsearch==0.75
44
- langchain-classic==1.0.0
45
- langgraph==1.0.10
46
- langgraph-prebuilt==1.0.10
44
+ langchain-classic==1.0.8
45
+ langgraph==1.2.10
46
+ langgraph-checkpoint==4.1.1
47
+ langgraph-prebuilt==1.1.0
48
+ langgraph-sdk==0.4.2
47
49
  langsmith==0.9.5
48
50
  unitycatalog-ai==0.3.2
49
51
  unitycatalog-langchain==0.3.0
@@ -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.dev19"
7
+ version = "0.4.3.dev20"
8
8
  description = "Tellr application package for Databricks Apps"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -15,10 +15,10 @@ dependencies = [
15
15
  "pydantic==2.12.4",
16
16
  "pydantic-settings==2.12.0",
17
17
  "databricks-langchain==0.9.0",
18
- "langchain==1.0.5",
19
- "langchain-core==1.0.4",
20
- "langchain-community==0.4.1",
21
- "langchain-text-splitters==1.0.0",
18
+ "langchain==1.3.14",
19
+ "langchain-core==1.5.3",
20
+ "langchain-community==0.4.2",
21
+ "langchain-text-splitters==1.1.2",
22
22
  "litellm==1.80.11",
23
23
  "mcp==1.27.0",
24
24
  "opentelemetry-api==1.38.0",
@@ -73,6 +73,13 @@ dependencies = [
73
73
  # `pip install databricks-tellr-app` is safe.
74
74
  # SDR-4437 MEDIUM-7 (July 2026): the 7 formerly-ranged direct deps above
75
75
  # this block are now exact-pinned too; same refresh discipline.
76
+ # PR2 LangGraph stack bump (August 2026): updated langchain 1.0.5→1.3.14,
77
+ # langchain-core 1.0.4→1.5.3, langchain-community 0.4.1→0.4.2,
78
+ # langchain-text-splitters 1.0.0→1.1.2, langchain-classic 1.0.0→1.0.8,
79
+ # langgraph 1.0.10→1.2.10, added langgraph-checkpoint==4.1.1,
80
+ # langgraph-prebuilt 1.0.10→1.1.0, added langgraph-sdk==0.4.2. These match
81
+ # the repo-root requirements.txt and pyproject.toml. MUST be re-verified via
82
+ # a devloop deploy on db-tellr-dev-pinfix or equivalent before PR3 ships.
76
83
  "databricks-sdk==0.120.0",
77
84
  "mlflow[databricks]==3.14.0",
78
85
  "mlflow-skinny==3.14.0",
@@ -81,9 +88,11 @@ dependencies = [
81
88
  "databricks-ai-search==0.76",
82
89
  "databricks-connect==16.1.7",
83
90
  "databricks-vectorsearch==0.75",
84
- "langchain-classic==1.0.0",
85
- "langgraph==1.0.10",
86
- "langgraph-prebuilt==1.0.10",
91
+ "langchain-classic==1.0.8",
92
+ "langgraph==1.2.10",
93
+ "langgraph-checkpoint==4.1.1",
94
+ "langgraph-prebuilt==1.1.0",
95
+ "langgraph-sdk==0.4.2",
87
96
  "langsmith==0.9.5",
88
97
  "unitycatalog-ai==0.3.2",
89
98
  "unitycatalog-langchain==0.3.0",
@@ -489,23 +489,11 @@ logger.info("MCP server mounted at /mcp")
489
489
 
490
490
  @app.get("/api/health")
491
491
  async def health():
492
- """Health check endpoint.
493
-
494
- ``encryption_key_source`` is load-bearing for deployment: ``tellr.update``
495
- polls it to confirm a relocated app is reading the secret before it deletes
496
- the Lakebase key row. Reports the source only — never the key.
497
-
498
- ``version`` comes from the installed wheel's metadata, so it tracks the
499
- deployed release; it reads "unknown" from a source checkout.
500
- """
501
- from src.api.routes.version import get_installed_version
502
- from src.core.encryption import key_source
503
-
492
+ """Health check endpoint."""
504
493
  return {
505
494
  "status": "healthy",
506
495
  "environment": ENVIRONMENT,
507
- "version": get_installed_version(),
508
- "encryption_key_source": key_source(),
496
+ "version": "0.3.0",
509
497
  }
510
498
 
511
499
 
@@ -16,22 +16,19 @@ Accepts three identity sources, evaluated in priority order:
16
16
  identity headers. The receiving app (tellr) trusts those headers
17
17
  because the same proxy sets them, strips any caller-supplied versions,
18
18
  and cannot be bypassed by external traffic. This path has no user
19
- token, so the user-client ContextVar is left **unset**: agent tools
20
- that resolve their client via ``get_user_client()`` fail closed rather
21
- than silently running as tellr's service principal (SDR-4437 / F-CR-3).
22
- Code that legitimately needs SP credentials on this path must call
23
- ``get_system_client()`` explicitly. Attribution (``created_by`` on
24
- decks, etc.) remains the real user via ``user_name``.
19
+ token, so downstream Databricks API calls use tellr's own service
20
+ principal credentials; attribution (``created_by`` on decks, etc.)
21
+ remains the real user via ``user_name``.
25
22
 
26
23
  The priority-3 path is gated on ``TELLR_TRUST_FORWARDED_IDENTITY=true``
27
24
  so the behaviour is explicit at deploy time. Production Databricks Apps
28
25
  deployments enable it; local dev does not.
29
26
 
30
27
  The resolved identity is bound into the same request-scoped ContextVars
31
- the browser flow uses (``set_current_user``, ``set_permission_context``,
32
- and — only when a user token is present — ``set_user_client``), so
33
- downstream services (session manager, permission service, MLflow, Google
34
- OAuth) see the caller's identity without any MCP-specific plumbing.
28
+ the browser flow uses (``set_current_user``, ``set_user_client``,
29
+ ``set_permission_context``), so downstream services (session manager,
30
+ permission service, MLflow, Google OAuth) see the caller's identity
31
+ without any MCP-specific plumbing.
35
32
  """
36
33
 
37
34
  from __future__ import annotations
@@ -46,6 +43,7 @@ from fastapi import Request
46
43
 
47
44
  from src.core.databricks_client import (
48
45
  get_or_create_user_client,
46
+ get_system_client,
49
47
  set_user_client,
50
48
  )
51
49
  from src.core.permission_context import (
@@ -152,24 +150,28 @@ def extract_mcp_identity(request: Request) -> MCPIdentity:
152
150
  def mcp_auth_scope(request: Request) -> Iterator[MCPIdentity]:
153
151
  """Authenticate an MCP request and bind identity ContextVars for the block.
154
152
 
155
- On entry: resolves identity and binds ``current_user`` and
156
- ``permission_context``. The ``user_client`` ContextVar is bound only when
157
- a real user token is present (priority 1/2); on the token-less priority-3
158
- app-to-app path it is deliberately left unset.
153
+ On entry: resolves identity, binds ``current_user``, ``user_client``,
154
+ and ``permission_context``.
159
155
 
160
156
  On exit: clears all three ContextVars, even if the wrapped block raised.
161
157
 
162
- Leaving ``user_client`` unset on priority 3 makes it true by construction
163
- that agent tools (which resolve their client via ``get_user_client()``)
164
- can never execute as tellr's service principal on the app-to-app path —
165
- they fail closed with ``UserClientRequiredError`` in production
166
- (SDR-4437 / F-CR-3). Code that legitimately needs SP credentials must call
167
- ``get_system_client()`` explicitly. Attribution (``created_by``) is
168
- unaffected: it uses ``user_name`` from the forwarded identity headers,
169
- which the proxy attests.
158
+ When the identity was resolved via priority 3 (no user token), the
159
+ bound ``user_client`` is tellr's service-principal client — downstream
160
+ services still function, but any SDK calls are made with SP credentials
161
+ rather than the user's own. Attribution (``created_by``) is unaffected:
162
+ it uses ``user_name`` from the forwarded identity headers, which the
163
+ proxy attests.
170
164
  """
171
165
  identity = extract_mcp_identity(request)
172
166
 
167
+ if identity.token is not None:
168
+ user_client = get_or_create_user_client(identity.token)
169
+ else:
170
+ # Priority-3 path: no user token, so downstream Databricks API
171
+ # calls use tellr's service principal. Safe because the app-to-app
172
+ # model explicitly delegates credentialing to the receiving app.
173
+ user_client = get_system_client()
174
+
173
175
  permission_ctx = build_permission_context(
174
176
  user_id=identity.user_id,
175
177
  user_name=identity.user_name,
@@ -177,22 +179,9 @@ def mcp_auth_scope(request: Request) -> Iterator[MCPIdentity]:
177
179
  )
178
180
 
179
181
  set_current_user(identity.user_name)
182
+ set_user_client(user_client)
180
183
  set_permission_context(permission_ctx)
181
184
 
182
- if identity.token is not None:
183
- # Priority 1/2: a real user token is present. Bind the OBO client so
184
- # downstream services (agent tools included) act as the user.
185
- set_user_client(get_or_create_user_client(identity.token))
186
- else:
187
- # Priority-3 (app-to-app) path: no user token is available. Do NOT
188
- # bind any client into the user-client ContextVar. Leaving it unset
189
- # makes it true by construction that agent tools — which resolve their
190
- # client via get_user_client() — can never run as the app service
191
- # principal on this path: they fail closed with UserClientRequiredError
192
- # in production (SDR-4437 / F-CR-3). Anything that legitimately needs
193
- # the SP here must call get_system_client() explicitly.
194
- set_user_client(None)
195
-
196
185
  logger.debug(
197
186
  "MCP auth scope entered",
198
187
  extra={
@@ -543,6 +543,18 @@ async def send_message_streaming(
543
543
  )
544
544
 
545
545
 
546
+ @router.get("/health")
547
+ async def health_check():
548
+ """Health check endpoint.
549
+
550
+ Returns:
551
+ Status information
552
+ """
553
+ return {
554
+ "status": "healthy",
555
+ "service": "AI Slide Generator",
556
+ }
557
+
546
558
 
547
559
  @router.post("/chat/async")
548
560
  async def submit_chat_async(
@@ -743,11 +743,28 @@ async def get_session_slides(session_id: str):
743
743
  ) from e
744
744
 
745
745
 
746
- # F-CR-16 (SDR-4437): the POST /cleanup endpoint was removed — it had no
747
- # authorization check and allowed any authenticated CAN_USE user to delete all
748
- # sessions older than 24h (cascading to decks, chat history, etc.). The endpoint
749
- # was unused (no frontend caller, no scheduler, no script), so removal was safer
750
- # than gating. See SDR-4437 for details.
746
+ @router.post("/cleanup")
747
+ async def cleanup_expired_sessions():
748
+ """Clean up expired sessions.
749
+
750
+ Returns:
751
+ Number of sessions deleted
752
+ """
753
+ try:
754
+ session_manager = get_session_manager()
755
+ count = await asyncio.to_thread(session_manager.cleanup_expired_sessions)
756
+
757
+ logger.info("Session cleanup completed", extra={"deleted_count": count})
758
+
759
+ return {"status": "completed", "deleted_count": count}
760
+
761
+ except Exception as e:
762
+ logger.error(f"Failed to cleanup sessions: {e}", exc_info=True)
763
+ raise HTTPException(
764
+ status_code=500,
765
+ detail="Cleanup failed",
766
+ ) from e
767
+
751
768
 
752
769
  # F-CR-10 (SDR-4437): the debug-only POST /{session_id}/export endpoint was
753
770
  # removed — it was unused by the frontend and dumped full session data (all chat
@@ -3,21 +3,7 @@
3
3
  CRUD + bundle import for org-shared design systems. Mirrors the slide-styles
4
4
  router (``slide_styles.py``): design systems are company-wide assets (everyone
5
5
  can view/use), ``created_by`` records authorship, and a single ``is_default``
6
- marks the org default.
7
-
8
- AUTHORIZATION (SDR-4437 F-CR-17): CREATE and IMPORT are ADMIN-ONLY. This
9
- supersedes the earlier "any user may contribute a design system" decision. The
10
- reason is the downstream blast radius rather than the write itself: a design
11
- system's ``compiled_style_content`` is injected into the generation system
12
- prompt of every user who selects it (``agent_factory._get_prompt_content`` ->
13
- ``prompt_modules.build_generation_system_prompt``), and that artifact embeds the
14
- bundle's README/SKILL.md **verbatim** as the BRAND MANUAL block. Contribution is
15
- therefore a write into other users' prompt context, not just into a shared
16
- library, so it is gated to the same ``require_admin`` primitive that already
17
- guards ``set-default``, the slide-style library and the deck-prompt library.
18
- Reads stay open; rename/delete remain CREATOR-OR-ADMIN (see
19
- ``_require_creator_or_admin``). The prompt-side hardening that complements this
20
- gate lives in ``design_system_compiler.DESIGN_SYSTEM_SCOPE_FIREWALL``. A design system compiles to ``compiled_style_content`` —
6
+ marks the org default. A design system compiles to ``compiled_style_content`` —
21
7
  the drop-in equivalent of ``slide_style_library.style_content`` — so it flows
22
8
  through the existing generation seam (see ``agent_factory._get_prompt_content``).
23
9
 
@@ -537,7 +523,6 @@ def list_design_systems(
537
523
  "/import",
538
524
  response_model=DesignSystemImportResult,
539
525
  status_code=status.HTTP_201_CREATED,
540
- dependencies=[Depends(require_admin)],
541
526
  )
542
527
  async def import_design_system(
543
528
  file: UploadFile = File(...),
@@ -598,12 +583,7 @@ async def import_design_system(
598
583
  )
599
584
 
600
585
 
601
- @router.post(
602
- "",
603
- response_model=DesignSystemDetail,
604
- status_code=status.HTTP_201_CREATED,
605
- dependencies=[Depends(require_admin)],
606
- )
586
+ @router.post("", response_model=DesignSystemDetail, status_code=status.HTTP_201_CREATED)
607
587
  def create_design_system(
608
588
  request: DesignSystemCreate,
609
589
  db: Session = Depends(get_db),
@@ -436,12 +436,12 @@ async def update_slide_verification(index: int, request: UpdateVerificationReque
436
436
  content_hash = compute_slide_hash(slide_html)
437
437
 
438
438
  if request.verification is not None:
439
- # Save verification by content hash
439
+ # Save verification by content hash (row-level merge)
440
440
  await asyncio.to_thread(
441
- session_manager.save_verification,
441
+ session_manager.write_slide_verification,
442
442
  request.session_id,
443
- content_hash,
444
- request.verification,
443
+ index,
444
+ {content_hash: request.verification},
445
445
  )
446
446
 
447
447
  logger.info(
@@ -195,10 +195,10 @@ async def verify_slide(slide_index: int, request: VerifySlideRequest):
195
195
 
196
196
  # Save this result by content hash (so it's remembered)
197
197
  await asyncio.to_thread(
198
- session_manager.save_verification,
198
+ session_manager.write_slide_verification,
199
199
  request.session_id,
200
- content_hash,
201
- unknown_result,
200
+ slide_index,
201
+ {content_hash: unknown_result},
202
202
  )
203
203
 
204
204
  return VerifySlideResponse(**unknown_result)
@@ -223,10 +223,10 @@ async def verify_slide(slide_index: int, request: VerifySlideRequest):
223
223
  "error": False,
224
224
  }
225
225
  await asyncio.to_thread(
226
- session_manager.save_verification,
226
+ session_manager.write_slide_verification,
227
227
  request.session_id,
228
- content_hash,
229
- unknown_result,
228
+ slide_index,
229
+ {content_hash: unknown_result},
230
230
  )
231
231
  return VerifySlideResponse(**unknown_result)
232
232
 
@@ -261,10 +261,10 @@ async def verify_slide(slide_index: int, request: VerifySlideRequest):
261
261
 
262
262
  # Save verification by content hash (survives deck regeneration)
263
263
  await asyncio.to_thread(
264
- session_manager.save_verification,
264
+ session_manager.write_slide_verification,
265
265
  request.session_id,
266
- content_hash,
267
- verification_result,
266
+ slide_index,
267
+ {content_hash: verification_result},
268
268
  )
269
269
 
270
270
  logger.info(
@@ -39,13 +39,9 @@ class VersionCheckResponse(BaseModel):
39
39
  package_name: str
40
40
 
41
41
 
42
- def get_installed_version() -> str:
42
+ def _get_installed_version() -> str:
43
43
  """Get the installed version of databricks-tellr-app.
44
44
 
45
- Shared with the ``/api/health`` handler in ``src.api.main``, which reports
46
- the same value. Returns "unknown" when running from a source checkout
47
- rather than an installed wheel.
48
-
49
45
  Returns:
50
46
  Version string or "unknown" if not installed
51
47
  """
@@ -133,7 +129,7 @@ async def check_version() -> VersionCheckResponse:
133
129
  - update_available: Whether an update is available
134
130
  - update_type: "patch" (redeploy) or "major" (run tellr.update())
135
131
  """
136
- installed = get_installed_version()
132
+ installed = _get_installed_version()
137
133
  latest = _get_latest_version_from_pypi()
138
134
 
139
135
  update_available = False