databricks-tellr-app 0.4.3.dev3462__tar.gz → 0.4.3.dev3464__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/PKG-INFO +2 -2
  2. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/databricks_tellr_app/run.py +0 -17
  3. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/databricks_tellr_app.egg-info/PKG-INFO +2 -2
  4. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/databricks_tellr_app.egg-info/requires.txt +1 -1
  5. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/pyproject.toml +2 -2
  6. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/mcp_server.py +6 -17
  7. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/middleware/security_headers.py +8 -1
  8. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/chat.py +99 -13
  9. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/tour.py +5 -6
  10. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/requests.py +8 -1
  11. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/chat_service.py +40 -130
  12. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/session_manager.py +222 -67
  13. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/database.py +48 -0
  14. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/defaults.py +1 -1
  15. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/session.py +4 -0
  16. databricks_tellr_app-0.4.3.dev3464/src/domain/conversation_engine.py +36 -0
  17. databricks_tellr_app-0.4.3.dev3464/src/services/agent_definition_manifest_v1.py +3 -0
  18. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/conversation_pins.py +2 -76
  19. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/model_endpoint_catalog.py +64 -20
  20. databricks_tellr_app-0.4.3.dev3462/src/domain/conversation_engine.py +0 -57
  21. databricks_tellr_app-0.4.3.dev3462/src/services/agent_definition_manifest_v1.py +0 -3
  22. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/README.md +0 -0
  23. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/databricks_tellr_app/__init__.py +0 -0
  24. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/databricks_tellr_app.egg-info/SOURCES.txt +0 -0
  25. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/databricks_tellr_app.egg-info/dependency_links.txt +0 -0
  26. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/databricks_tellr_app.egg-info/top_level.txt +0 -0
  27. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/setup.cfg +0 -0
  28. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/setup.py +0 -0
  29. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/__init__.py +0 -0
  30. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/__init__.py +0 -0
  31. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/_otel_bootstrap.py +0 -0
  32. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/fixtures/tour_demo_deck.json +0 -0
  33. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/main.py +0 -0
  34. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/mcp_auth.py +0 -0
  35. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/middleware/__init__.py +0 -0
  36. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/middleware/csrf.py +0 -0
  37. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/middleware/request_logging.py +0 -0
  38. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/__init__.py +0 -0
  39. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/_authz.py +0 -0
  40. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/admin.py +0 -0
  41. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/admin_usage.py +0 -0
  42. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/agent_config.py +0 -0
  43. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/agent_definitions.py +0 -0
  44. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/deck_contributors.py +0 -0
  45. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/export.py +0 -0
  46. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/feedback.py +0 -0
  47. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/google_slides.py +0 -0
  48. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/images.py +0 -0
  49. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/local_version.py +0 -0
  50. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/profiles.py +0 -0
  51. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/sessions.py +0 -0
  52. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/settings/__init__.py +0 -0
  53. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/settings/contributors.py +0 -0
  54. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/settings/deck_prompts.py +0 -0
  55. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/settings/design_systems.py +0 -0
  56. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/settings/identities.py +0 -0
  57. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/settings/slide_styles.py +0 -0
  58. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/setup.py +0 -0
  59. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/slides.py +0 -0
  60. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/tools.py +0 -0
  61. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/verification.py +0 -0
  62. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/routes/version.py +0 -0
  63. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/__init__.py +0 -0
  64. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/agent_config.py +0 -0
  65. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/agent_definitions.py +0 -0
  66. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/feedback.py +0 -0
  67. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/graph_release_history.py +0 -0
  68. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/graph_releases.py +0 -0
  69. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/responses.py +0 -0
  70. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/settings/__init__.py +0 -0
  71. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/settings/requests.py +0 -0
  72. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/settings/responses.py +0 -0
  73. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/schemas/streaming.py +0 -0
  74. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/__init__.py +0 -0
  75. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/deck_level_writer.py +0 -0
  76. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/export_job_queue.py +0 -0
  77. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/feedback_service.py +0 -0
  78. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/job_queue.py +0 -0
  79. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/session_naming.py +0 -0
  80. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/slide_repository.py +0 -0
  81. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/slide_style_preview_queue.py +0 -0
  82. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/usage_events.py +0 -0
  83. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/services/usage_service.py +0 -0
  84. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/utils/__init__.py +0 -0
  85. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/api/utils/validation.py +0 -0
  86. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/__init__.py +0 -0
  87. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/backfill_session_slides_startup.py +0 -0
  88. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/checkpointer.py +0 -0
  89. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/config_loader.py +0 -0
  90. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/context_utils.py +0 -0
  91. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/databricks_client.py +0 -0
  92. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/encryption.py +0 -0
  93. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/init_default_profile.py +0 -0
  94. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/lakebase.py +0 -0
  95. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/migrate_profiles_to_agent_config.py +0 -0
  96. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/mlflow_agent_spans.py +0 -0
  97. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/mlflow_tracing.py +0 -0
  98. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/otel_logging.py +0 -0
  99. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/permission_context.py +0 -0
  100. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/prompt_modules.py +0 -0
  101. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/settings_db.py +0 -0
  102. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/__init__.py +0 -0
  103. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/architect.py +0 -0
  104. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/build_reviewer.py +0 -0
  105. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/builder.py +0 -0
  106. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/data_analyst.py +0 -0
  107. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/deck_reviewer.py +0 -0
  108. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/fix_reviewer.py +0 -0
  109. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/skills/fixer.py +0 -0
  110. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/strip_retired_prompt_keys.py +0 -0
  111. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/core/user_context.py +0 -0
  112. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/__init__.py +0 -0
  113. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/__init__.py +0 -0
  114. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/data_migration.py +0 -0
  115. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/deck_contributor.py +0 -0
  116. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/deck_review.py +0 -0
  117. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/design_system.py +0 -0
  118. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/encryption_key.py +0 -0
  119. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/feedback.py +0 -0
  120. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/genie_space.py +0 -0
  121. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/google_global_credentials.py +0 -0
  122. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/google_oauth_token.py +0 -0
  123. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/graph_checkpoint.py +0 -0
  124. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/graph_configuration.py +0 -0
  125. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/identity.py +0 -0
  126. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/image.py +0 -0
  127. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/profile.py +0 -0
  128. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/profile_contributor.py +0 -0
  129. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/prompts.py +0 -0
  130. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/request_log.py +0 -0
  131. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/slide_deck_prompt.py +0 -0
  132. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/slide_style_library.py +0 -0
  133. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/slide_style_preview.py +0 -0
  134. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/usage_event.py +0 -0
  135. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/models/user_preference.py +0 -0
  136. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/database/types.py +0 -0
  137. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/domain/__init__.py +0 -0
  138. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/domain/conversation_turns.py +0 -0
  139. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/domain/deck_spec.py +0 -0
  140. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/domain/deck_spec_slides.py +0 -0
  141. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/domain/finding.py +0 -0
  142. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/domain/finding_copy.py +0 -0
  143. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/domain/skill_io.py +0 -0
  144. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/domain/slide.py +0 -0
  145. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/domain/slide_alignment.py +0 -0
  146. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/domain/slide_deck.py +0 -0
  147. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/domain/slide_numbering.py +0 -0
  148. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/__init__.py +0 -0
  149. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent.py +0 -0
  150. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_factory.py +0 -0
  151. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_model_payload.py +0 -0
  152. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_resolution.py +0 -0
  153. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_runtime.py +0 -0
  154. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_runtime_identity.py +0 -0
  155. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_schema_registry.py +0 -0
  156. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_schema_types.py +0 -0
  157. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/agent_test_workbench.py +0 -0
  158. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/collaboration_history.py +0 -0
  159. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/config_service.py +0 -0
  160. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/config_validator.py +0 -0
  161. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/converter_jail/__init__.py +0 -0
  162. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/converter_jail/ast_guard.py +0 -0
  163. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/converter_jail/codeprep.py +0 -0
  164. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/converter_jail/gslides_runner.py +0 -0
  165. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/converter_jail/jail.py +0 -0
  166. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/converter_jail/pptx_runner.py +0 -0
  167. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/converter_jail/protocol.py +0 -0
  168. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/deck_css_aggregator.py +0 -0
  169. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/deck_review_store.py +0 -0
  170. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/design_system_compiler.py +0 -0
  171. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/design_system_service.py +0 -0
  172. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/design_system_templates.py +0 -0
  173. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/drive_uploader.py +0 -0
  174. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/evaluation/__init__.py +0 -0
  175. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/evaluation/llm_judge.py +0 -0
  176. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/foreman_service.py +0 -0
  177. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/gateway_openai.py +0 -0
  178. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/genie_service.py +0 -0
  179. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/google_slides_auth.py +0 -0
  180. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/google_slides_prompts_defaults.py +0 -0
  181. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/__init__.py +0 -0
  182. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/builder.py +0 -0
  183. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/event_emitter.py +0 -0
  184. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/nodes.py +0 -0
  185. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/progress.py +0 -0
  186. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/routers.py +0 -0
  187. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/state.py +0 -0
  188. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph/user_notices.py +0 -0
  189. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration.py +0 -0
  190. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration_bootstrap.py +0 -0
  191. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration_content.py +0 -0
  192. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration_draft.py +0 -0
  193. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration_publication.py +0 -0
  194. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration_rollback.py +0 -0
  195. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration_seed.py +0 -0
  196. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_configuration_workbench.py +0 -0
  197. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_definition_manifest.py +0 -0
  198. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_release_evidence.py +0 -0
  199. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/graph_release_history.py +0 -0
  200. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/html_to_google_slides.py +0 -0
  201. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/html_to_pptx.py +0 -0
  202. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/identity_provider.py +0 -0
  203. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/identity_providers/__init__.py +0 -0
  204. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/identity_providers/account_provider.py +0 -0
  205. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/identity_providers/local_provider.py +0 -0
  206. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/identity_providers/scim_filter.py +0 -0
  207. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/identity_providers/workspace_provider.py +0 -0
  208. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/image_service.py +0 -0
  209. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/image_tools.py +0 -0
  210. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/model_endpoint_probe.py +0 -0
  211. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/permission_service.py +0 -0
  212. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/persisted_graph_release.py +0 -0
  213. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/pptx_from_html_huashu.py +0 -0
  214. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/pptx_from_records.py +0 -0
  215. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/pptx_prompts_defaults.py +0 -0
  216. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/profile_service.py +0 -0
  217. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/prompt_assembler.py +0 -0
  218. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/shared_deck_attribution.py +0 -0
  219. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/slide_style_preview_fixture.py +0 -0
  220. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/slide_style_preview_storage.py +0 -0
  221. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/spec_sync.py +0 -0
  222. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/streaming_callback.py +0 -0
  223. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/svg_sanitizer.py +0 -0
  224. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/template_sections.py +0 -0
  225. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/tools/__init__.py +0 -0
  226. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/tools/agent_bricks_tool.py +0 -0
  227. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/tools/ds_asset_tool.py +0 -0
  228. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/tools/genie_tool.py +0 -0
  229. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/tools/mcp_tool.py +0 -0
  230. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/tools/model_endpoint_tool.py +0 -0
  231. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/tools/vector_tool.py +0 -0
  232. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/services/validator.py +0 -0
  233. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/utils/__init__.py +0 -0
  234. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/utils/css_utils.py +0 -0
  235. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/utils/ds_asset_utils.py +0 -0
  236. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/utils/error_handling.py +0 -0
  237. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/utils/graph_safety.py +0 -0
  238. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/utils/html_safety.py +0 -0
  239. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/utils/html_utils.py +0 -0
  240. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/utils/image_utils.py +0 -0
  241. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/utils/js_validator.py +0 -0
  242. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/utils/logging_config.py +0 -0
  243. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/utils/pi_filter.py +0 -0
  244. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/utils/slide_hash.py +0 -0
  245. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/utils/spotlight.py +0 -0
  246. {databricks_tellr_app-0.4.3.dev3462 → databricks_tellr_app-0.4.3.dev3464}/src/utils/text_caps.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: databricks-tellr-app
3
- Version: 0.4.3.dev3462
3
+ Version: 0.4.3.dev3464
4
4
  Summary: Tellr application package for Databricks Apps
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -42,7 +42,7 @@ Requires-Dist: google-auth-oauthlib==1.2.4
42
42
  Requires-Dist: google-auth-httplib2==0.3.0
43
43
  Requires-Dist: cryptography==46.0.3
44
44
  Requires-Dist: sse-starlette==3.0.3
45
- Requires-Dist: databricks-sdk==0.120.0
45
+ Requires-Dist: databricks-sdk==0.157.0
46
46
  Requires-Dist: mlflow[databricks]==3.14.0
47
47
  Requires-Dist: mlflow-skinny==3.14.0
48
48
  Requires-Dist: databricks-agents==1.11.0
@@ -68,23 +68,6 @@ def init_database(seed_databricks_defaults: bool = False) -> None:
68
68
  logger.error(f"Failed to bootstrap Graph Configuration: {e}\n{tb}")
69
69
  raise SystemExit(1) from e
70
70
 
71
- logger.info("Backfilling Conversation Pins...")
72
- try:
73
- from src.core.database import get_session_local
74
- from src.services.conversation_pins import backfill_conversation_pins
75
-
76
- result = backfill_conversation_pins(get_session_local())
77
- logger.info(
78
- "Conversation Pins ready: release_id=%s version=%s pinned=%s",
79
- result.graph_release_id,
80
- result.graph_version,
81
- result.pinned_count,
82
- )
83
- except Exception as e:
84
- tb = traceback.format_exc()
85
- logger.error(f"Failed to backfill Conversation Pins: {e}\n{tb}")
86
- raise SystemExit(1) from e
87
-
88
71
  # Data migrations/backfills that used to run in the FastAPI lifespan now run
89
72
  # HERE, once, before the server forks its workers — the uvicorn workers must
90
73
  # never execute migration code (4 of them racing the migration chain on boot
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: databricks-tellr-app
3
- Version: 0.4.3.dev3462
3
+ Version: 0.4.3.dev3464
4
4
  Summary: Tellr application package for Databricks Apps
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -42,7 +42,7 @@ Requires-Dist: google-auth-oauthlib==1.2.4
42
42
  Requires-Dist: google-auth-httplib2==0.3.0
43
43
  Requires-Dist: cryptography==46.0.3
44
44
  Requires-Dist: sse-starlette==3.0.3
45
- Requires-Dist: databricks-sdk==0.120.0
45
+ Requires-Dist: databricks-sdk==0.157.0
46
46
  Requires-Dist: mlflow[databricks]==3.14.0
47
47
  Requires-Dist: mlflow-skinny==3.14.0
48
48
  Requires-Dist: databricks-agents==1.11.0
@@ -36,7 +36,7 @@ google-auth-oauthlib==1.2.4
36
36
  google-auth-httplib2==0.3.0
37
37
  cryptography==46.0.3
38
38
  sse-starlette==3.0.3
39
- databricks-sdk==0.120.0
39
+ databricks-sdk==0.157.0
40
40
  mlflow[databricks]==3.14.0
41
41
  mlflow-skinny==3.14.0
42
42
  databricks-agents==1.11.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.dev3462"
7
+ version = "0.4.3.dev3464"
8
8
  description = "Tellr application package for Databricks Apps"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -86,7 +86,7 @@ dependencies = [
86
86
  # langgraph-prebuilt 1.0.10→1.1.0, added langgraph-sdk==0.4.2. These match
87
87
  # the repo-root requirements.txt and pyproject.toml. MUST be re-verified via
88
88
  # a devloop deploy on db-tellr-dev-pinfix or equivalent before PR3 ships.
89
- "databricks-sdk==0.120.0",
89
+ "databricks-sdk==0.157.0",
90
90
  "mlflow[databricks]==3.14.0",
91
91
  "mlflow-skinny==3.14.0",
92
92
  "databricks-agents==1.11.0",
@@ -33,7 +33,6 @@ from src.core.settings_db import (
33
33
  get_default_slide_style_id,
34
34
  get_default_template_id,
35
35
  )
36
- from src.domain.conversation_engine import with_legacy_marker
37
36
  from src.domain.slide_deck import SlideDeck
38
37
  from src.services.permission_service import get_permission_service
39
38
 
@@ -238,23 +237,14 @@ async def enqueue_create_job(
238
237
  #
239
238
  # MCP stays on the legacy monolith (its worker payload carries no engine
240
239
  # key, and the graph's one-shot path, spec §6.4, is not built).
241
- # Since 2026-10-12 the graph is the DEFAULT engine, derived from the
242
- # deck's first user message -- so a create_deck deck whose transcript
243
- # did not say otherwise would resolve to the graph the first time
244
- # someone chatted on it in the browser, and fail there
245
- # (ConversationPinMissingError: MCP sessions are unpinned). The
246
- # persisted first message therefore carries the LEGACY opt-out; the
247
- # prompt the worker runs (payload "message" below) is untouched.
248
- persisted_prompt = (
249
- with_legacy_marker(prompt)
250
- if mode == "generate" and is_first_message
251
- else prompt
252
- )
240
+ # create_deck stores that on the session it creates (deck_mode="legacy"),
241
+ # so no prompt has to say it: every prompt, create or edit, is persisted
242
+ # verbatim.
253
243
  await asyncio.to_thread(
254
244
  session_manager.add_message,
255
245
  session_id=session_id,
256
246
  role="user",
257
- content=persisted_prompt,
247
+ content=prompt,
258
248
  message_type="user_query",
259
249
  request_id=request_id,
260
250
  )
@@ -536,10 +526,9 @@ async def _create_deck_impl(
536
526
  session = session_manager.create_session(
537
527
  created_by=identity.user_name,
538
528
  agent_config=agent_config,
539
- # Legacy deck: unpinned, and enqueue_create_job persists the
540
- # first message with the USE LEGACY MODE opt-out so the
541
- # transcript-derived engine agrees in every surface.
529
+ # Legacy deck: unpinned, and locked to the monolith from creation.
542
530
  graph_capable=False,
531
+ deck_mode="legacy",
543
532
  )
544
533
  # create_session returns a dict (see SessionManager.create_session);
545
534
  # guard against a model-object return defensively so this stays
@@ -24,6 +24,13 @@ Content-Security-Policy differentiated by response type:
24
24
  Radix UI injects inline styles at runtime; CSP hashes apply to
25
25
  <style>/<script> *elements*, not style *attributes*, so
26
26
  ``style-src`` needs 'unsafe-inline'.
27
+ 3. Monaco: the editors load from jsDelivr via @monaco-editor/react, the
28
+ JS through ``script-src`` and ``editor.main.css`` as a stylesheet
29
+ link, so ``style-src`` also allows ``https://cdn.jsdelivr.net``.
30
+ Without it the sheet is blocked and the editor renders broken (its
31
+ input textarea shows as a stray box above the text). Given
32
+ 'unsafe-inline' already, the origin adds no real style-injection
33
+ surface; ``script-src`` already trusts it.
27
34
 
28
35
  ``script-src 'unsafe-inline'`` + CDNs is a deliberate, documented
29
36
  trade-off forced by srcdoc inheritance: slides remain confined by the
@@ -83,7 +90,7 @@ from starlette.responses import Response
83
90
  DOCUMENT_CSP = (
84
91
  "default-src 'self'; "
85
92
  "script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdn.tailwindcss.com; "
86
- "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; "
93
+ "style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://fonts.googleapis.com; "
87
94
  "img-src 'self' data:; "
88
95
  "font-src 'self' data: https://cdn.jsdelivr.net https://fonts.gstatic.com; "
89
96
  "connect-src 'self'; "
@@ -37,7 +37,11 @@ from src.api.services.job_queue import (
37
37
  is_pinned_graph_configuration_error_event,
38
38
  pinned_graph_configuration_error_event_payload,
39
39
  )
40
- from src.api.services.session_manager import SessionNotFoundError, get_session_manager
40
+ from src.api.services.session_manager import (
41
+ DeckModeLockedError,
42
+ SessionNotFoundError,
43
+ get_session_manager,
44
+ )
41
45
  from src.core.context_utils import run_in_thread_with_context
42
46
  from src.core.database import get_db
43
47
  from src.core.permission_context import get_permission_context
@@ -48,7 +52,6 @@ from src.core.settings_db import (
48
52
  )
49
53
  from src.core.user_context import get_current_user
50
54
  from src.database.models.profile_contributor import PermissionLevel
51
- from src.domain.conversation_engine import selects_graph_engine
52
55
  from src.services.agent import UnsafeContentError
53
56
  from src.services.conversation_pins import ActiveGraphReleaseUnavailableError
54
57
  from src.services.permission_service import PERMISSION_PRIORITY, get_permission_service
@@ -75,6 +78,34 @@ class _EngineModeUnresolvedError(Exception):
75
78
  """The async route's engine-mode resolution (and nothing else) failed closed."""
76
79
 
77
80
 
81
+ DECK_MODE_LOCKED_CODE = "deck_mode_locked"
82
+
83
+ _DECK_MODE_LABELS = {"agent": "Agent mode", "legacy": "Legacy mode"}
84
+
85
+
86
+ def _deck_mode_locked(exc: DeckModeLockedError) -> HTTPException:
87
+ """The 409 for a message asking for a Deck Mode other than the deck's locked one."""
88
+ label = _DECK_MODE_LABELS.get(exc.deck_mode, exc.deck_mode)
89
+ return HTTPException(
90
+ status_code=409,
91
+ detail={
92
+ "code": DECK_MODE_LOCKED_CODE,
93
+ "message": f"This deck's mode is already set to {label}, and it can't be changed.",
94
+ "deck_mode": exc.deck_mode,
95
+ },
96
+ )
97
+
98
+
99
+ async def _mark_chat_request_error(session_manager, request_id: str, code: str) -> None:
100
+ """Best effort: a failed status write must never mask the 409/503 being raised."""
101
+ try:
102
+ await asyncio.to_thread(
103
+ session_manager.update_chat_request_status, request_id, "error", code
104
+ )
105
+ except Exception:
106
+ logger.warning("Failed to mark chat request %s as errored", request_id, exc_info=True)
107
+
108
+
78
109
  def _engine_mode_unavailable() -> HTTPException:
79
110
  return HTTPException(status_code=503, detail=dict(ENGINE_MODE_UNAVAILABLE_DETAIL))
80
111
 
@@ -344,7 +375,7 @@ def _maybe_create_session(request: ChatRequest, session_manager) -> bool:
344
375
  _without_template_pin(_seeded_for_new_session(agent_config_data))
345
376
  ),
346
377
  created_by=current_user,
347
- graph_capable=selects_graph_engine(request.message),
378
+ graph_capable=True,
348
379
  )
349
380
  logger.info(
350
381
  "Created session from client-generated ID",
@@ -382,7 +413,7 @@ def _maybe_create_session(request: ChatRequest, session_manager) -> bool:
382
413
  _without_template_pin(_seeded_for_new_session(agent_config_data))
383
414
  ),
384
415
  created_by=current_user,
385
- graph_capable=selects_graph_engine(request.message),
416
+ graph_capable=True,
386
417
  )
387
418
  request.session_id = session["session_id"]
388
419
  return True
@@ -555,6 +586,42 @@ async def send_message_streaming(
555
586
  detail="Session is currently processing another request. Please wait.",
556
587
  )
557
588
 
589
+ # The user message is saved BEFORE the engine is resolved: the resolver
590
+ # reads the deck's owner column, which this save locks atomically with the
591
+ # message. Nothing has started streaming yet, so every failure here must
592
+ # release the lock taken above itself.
593
+ try:
594
+ session_data = await asyncio.to_thread(
595
+ session_manager.get_session, request.session_id
596
+ )
597
+ is_first_message = session_data.get("message_count", 0) == 0
598
+ await asyncio.to_thread(
599
+ session_manager.add_user_message,
600
+ request.session_id,
601
+ request.message,
602
+ message_type="user_input",
603
+ requested_deck_mode=request.deck_mode,
604
+ )
605
+ except SessionNotFoundError as e:
606
+ await asyncio.to_thread(session_manager.release_session_lock, request.session_id)
607
+ raise HTTPException(
608
+ status_code=404,
609
+ detail=f"Session not found: {request.session_id}",
610
+ ) from e
611
+ except DeckModeLockedError as e:
612
+ await asyncio.to_thread(session_manager.release_session_lock, request.session_id)
613
+ raise _deck_mode_locked(e) from e
614
+ except ActiveGraphReleaseUnavailableError as e:
615
+ await asyncio.to_thread(session_manager.release_session_lock, request.session_id)
616
+ raise HTTPException(
617
+ status_code=503,
618
+ detail="No active Graph Release available",
619
+ ) from e
620
+ except Exception as e:
621
+ await asyncio.to_thread(session_manager.release_session_lock, request.session_id)
622
+ logger.error(f"Failed to save streaming chat message: {e}")
623
+ raise HTTPException(status_code=500, detail="Internal server error") from e
624
+
558
625
  # ws4d D2 — the engine for this turn is resolved HERE, in the chat route,
559
626
  # and passed down. Not in send_message_streaming and not in the job queue:
560
627
  # MCP's enqueue_create_job drains through the same worker as POST
@@ -606,6 +673,8 @@ async def send_message_streaming(
606
673
  else None,
607
674
  image_ids=request.image_ids,
608
675
  engine_mode=engine_mode,
676
+ is_first_message_override=is_first_message,
677
+ user_message_persisted=True,
609
678
  ):
610
679
  event_queue.put(event)
611
680
  except Exception as e:
@@ -746,26 +815,26 @@ async def submit_chat_async(
746
815
  )
747
816
 
748
817
  # Capture first-message flag BEFORE persisting the user message,
749
- # because add_message increments message_count.
818
+ # because saving the message increments message_count.
750
819
  session_data = await asyncio.to_thread(
751
820
  session_manager.get_session, request.session_id
752
821
  )
753
822
  is_first_message = session_data.get("message_count", 0) == 0
754
823
 
755
- # Persist user message
824
+ # Persist user message (locks the deck's mode atomically with it)
756
825
  await asyncio.to_thread(
757
- session_manager.add_message,
758
- session_id=request.session_id,
759
- role="user",
760
- content=request.message,
826
+ session_manager.add_user_message,
827
+ request.session_id,
828
+ request.message,
761
829
  message_type="user_query",
762
830
  request_id=request_id,
831
+ requested_deck_mode=request.deck_mode,
763
832
  )
764
833
 
765
834
  # ws4d D2 — resolved AFTER the user message is persisted just above,
766
- # because resolve_engine_mode reads the deck's EARLIEST role='user'
767
- # message: on turn 1 that row has to exist already or a USE LEGACY MODE
768
- # opt-out in the very first message would resolve to the default
835
+ # because resolve_engine_mode reads the deck owner's `deck_mode`
836
+ # column, which that save locks: on turn 1 the column has to be set
837
+ # already or a legacy first message would resolve to the NULL default
769
838
  # (graph) engine.
770
839
  #
771
840
  # FAIL CLOSED (#271 C24/C47): a failure of THIS call (and only this call)
@@ -815,6 +884,23 @@ async def submit_chat_async(
815
884
  session_manager.release_session_lock, request.session_id
816
885
  )
817
886
  raise _engine_mode_unavailable() from e.__cause__
887
+ except DeckModeLockedError as e:
888
+ await asyncio.to_thread(
889
+ session_manager.release_session_lock, request.session_id
890
+ )
891
+ await _mark_chat_request_error(session_manager, request_id, DECK_MODE_LOCKED_CODE)
892
+ raise _deck_mode_locked(e) from e
893
+ except ActiveGraphReleaseUnavailableError as e:
894
+ await asyncio.to_thread(
895
+ session_manager.release_session_lock, request.session_id
896
+ )
897
+ await _mark_chat_request_error(
898
+ session_manager, request_id, "no_active_graph_release"
899
+ )
900
+ raise HTTPException(
901
+ status_code=503,
902
+ detail="No active Graph Release available",
903
+ ) from e
818
904
  except Exception as e:
819
905
  # Release lock on failure
820
906
  await asyncio.to_thread(
@@ -65,16 +65,15 @@ def _phase1_create_session(created_by: str) -> dict:
65
65
  fixture = _load_fixture()
66
66
  sm = get_session_manager()
67
67
 
68
- # Graph-capable (pinned): the fixture's chat_prompt carries no
69
- # USE LEGACY MODE opt-out, so since 2026-10-12 the tour deck resolves to
70
- # the graph like any other deck, and a graph turn on an unpinned session
71
- # raises ConversationPinMissingError. The fixture already ships a
72
- # deck_spec for exactly this (ws4d), so a user who keeps chatting after the
73
- # tour gets the default engine.
68
+ # Graph-capable (pinned) and locked to the agent engine from creation, so
69
+ # a user who keeps chatting after the tour stays on the graph. A graph
70
+ # turn on an unpinned session raises ConversationPinMissingError. The
71
+ # fixture already ships a deck_spec for exactly this (ws4d).
74
72
  session = sm.create_session(
75
73
  title=fixture["title"],
76
74
  created_by=created_by,
77
75
  graph_capable=True,
76
+ deck_mode="agent",
78
77
  )
79
78
  session_id = session["session_id"]
80
79
 
@@ -1,6 +1,6 @@
1
1
  """Request schemas for the API."""
2
2
 
3
- from typing import Optional
3
+ from typing import Literal, Optional
4
4
 
5
5
  from pydantic import BaseModel, Field, field_validator, model_validator
6
6
 
@@ -82,6 +82,13 @@ class ChatRequest(BaseModel):
82
82
  default=None,
83
83
  description="Agent configuration for session creation (tools, style, prompts)",
84
84
  )
85
+ deck_mode: Optional[Literal["agent", "legacy"]] = Field(
86
+ default=None,
87
+ description=(
88
+ "Deck Mode to lock the deck to with its first message. Ignored once the "
89
+ "deck is locked, unless it differs from the stored mode (then 409)."
90
+ ),
91
+ )
85
92
 
86
93
  @field_validator("session_id", mode="before")
87
94
  @classmethod