databricks-tellr-app 0.4.3.dev35__tar.gz → 0.4.3.dev37__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 (230) hide show
  1. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/PKG-INFO +1 -1
  2. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/databricks_tellr_app.egg-info/PKG-INFO +1 -1
  3. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/pyproject.toml +1 -1
  4. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/agent_definitions.py +1 -0
  5. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/schemas/agent_definitions.py +3 -0
  6. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/services/chat_service.py +33 -4
  7. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/services/session_naming.py +3 -1
  8. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/agent_runtime.py +43 -4
  9. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph/nodes.py +4 -3
  10. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/html_to_google_slides.py +0 -1
  11. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/html_to_pptx.py +0 -1
  12. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/model_endpoint_probe.py +114 -2
  13. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/README.md +0 -0
  14. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/databricks_tellr_app/__init__.py +0 -0
  15. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/databricks_tellr_app/run.py +0 -0
  16. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/databricks_tellr_app.egg-info/SOURCES.txt +0 -0
  17. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/databricks_tellr_app.egg-info/dependency_links.txt +0 -0
  18. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/databricks_tellr_app.egg-info/requires.txt +0 -0
  19. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/databricks_tellr_app.egg-info/top_level.txt +0 -0
  20. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/setup.cfg +0 -0
  21. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/setup.py +0 -0
  22. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/__init__.py +0 -0
  23. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/__init__.py +0 -0
  24. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/_otel_bootstrap.py +0 -0
  25. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/fixtures/tour_demo_deck.json +0 -0
  26. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/main.py +0 -0
  27. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/mcp_auth.py +0 -0
  28. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/mcp_server.py +0 -0
  29. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/middleware/__init__.py +0 -0
  30. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/middleware/csrf.py +0 -0
  31. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/middleware/request_logging.py +0 -0
  32. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/middleware/security_headers.py +0 -0
  33. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/__init__.py +0 -0
  34. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/_authz.py +0 -0
  35. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/admin.py +0 -0
  36. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/admin_usage.py +0 -0
  37. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/agent_config.py +0 -0
  38. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/chat.py +0 -0
  39. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/deck_contributors.py +0 -0
  40. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/export.py +0 -0
  41. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/feedback.py +0 -0
  42. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/google_slides.py +0 -0
  43. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/images.py +0 -0
  44. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/local_version.py +0 -0
  45. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/profiles.py +0 -0
  46. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/sessions.py +0 -0
  47. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/settings/__init__.py +0 -0
  48. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/settings/contributors.py +0 -0
  49. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/settings/deck_prompts.py +0 -0
  50. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/settings/design_systems.py +0 -0
  51. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/settings/identities.py +0 -0
  52. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/settings/slide_styles.py +0 -0
  53. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/setup.py +0 -0
  54. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/slides.py +0 -0
  55. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/tools.py +0 -0
  56. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/tour.py +0 -0
  57. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/verification.py +0 -0
  58. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/routes/version.py +0 -0
  59. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/schemas/__init__.py +0 -0
  60. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/schemas/agent_config.py +0 -0
  61. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/schemas/feedback.py +0 -0
  62. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/schemas/graph_release_history.py +0 -0
  63. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/schemas/graph_releases.py +0 -0
  64. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/schemas/requests.py +0 -0
  65. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/schemas/responses.py +0 -0
  66. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/schemas/settings/__init__.py +0 -0
  67. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/schemas/settings/requests.py +0 -0
  68. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/schemas/settings/responses.py +0 -0
  69. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/schemas/streaming.py +0 -0
  70. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/services/__init__.py +0 -0
  71. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/services/deck_level_writer.py +0 -0
  72. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/services/export_job_queue.py +0 -0
  73. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/services/feedback_service.py +0 -0
  74. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/services/job_queue.py +0 -0
  75. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/services/session_manager.py +0 -0
  76. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/services/slide_repository.py +0 -0
  77. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/services/usage_events.py +0 -0
  78. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/services/usage_service.py +0 -0
  79. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/utils/__init__.py +0 -0
  80. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/api/utils/validation.py +0 -0
  81. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/__init__.py +0 -0
  82. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/backfill_session_slides_startup.py +0 -0
  83. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/checkpointer.py +0 -0
  84. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/config_loader.py +0 -0
  85. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/context_utils.py +0 -0
  86. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/database.py +0 -0
  87. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/databricks_client.py +0 -0
  88. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/defaults.py +0 -0
  89. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/encryption.py +0 -0
  90. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/init_default_profile.py +0 -0
  91. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/lakebase.py +0 -0
  92. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/migrate_profiles_to_agent_config.py +0 -0
  93. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/mlflow_agent_spans.py +0 -0
  94. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/mlflow_tracing.py +0 -0
  95. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/otel_logging.py +0 -0
  96. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/permission_context.py +0 -0
  97. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/prompt_modules.py +0 -0
  98. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/settings_db.py +0 -0
  99. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/skills/__init__.py +0 -0
  100. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/skills/architect.py +0 -0
  101. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/skills/build_reviewer.py +0 -0
  102. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/skills/builder.py +0 -0
  103. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/skills/data_analyst.py +0 -0
  104. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/skills/deck_reviewer.py +0 -0
  105. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/skills/fix_reviewer.py +0 -0
  106. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/skills/fixer.py +0 -0
  107. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/strip_retired_prompt_keys.py +0 -0
  108. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/core/user_context.py +0 -0
  109. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/__init__.py +0 -0
  110. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/__init__.py +0 -0
  111. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/deck_contributor.py +0 -0
  112. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/deck_review.py +0 -0
  113. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/design_system.py +0 -0
  114. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/encryption_key.py +0 -0
  115. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/feedback.py +0 -0
  116. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/genie_space.py +0 -0
  117. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/google_global_credentials.py +0 -0
  118. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/google_oauth_token.py +0 -0
  119. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/graph_checkpoint.py +0 -0
  120. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/graph_configuration.py +0 -0
  121. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/identity.py +0 -0
  122. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/image.py +0 -0
  123. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/profile.py +0 -0
  124. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/profile_contributor.py +0 -0
  125. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/prompts.py +0 -0
  126. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/request_log.py +0 -0
  127. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/session.py +0 -0
  128. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/slide_deck_prompt.py +0 -0
  129. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/slide_style_library.py +0 -0
  130. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/usage_event.py +0 -0
  131. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/models/user_preference.py +0 -0
  132. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/database/types.py +0 -0
  133. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/domain/__init__.py +0 -0
  134. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/domain/conversation_engine.py +0 -0
  135. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/domain/deck_spec.py +0 -0
  136. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/domain/finding.py +0 -0
  137. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/domain/skill_io.py +0 -0
  138. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/domain/slide.py +0 -0
  139. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/domain/slide_deck.py +0 -0
  140. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/__init__.py +0 -0
  141. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/agent.py +0 -0
  142. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/agent_definition_manifest_v1.py +0 -0
  143. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/agent_factory.py +0 -0
  144. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/agent_model_payload.py +0 -0
  145. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/agent_resolution.py +0 -0
  146. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/agent_runtime_identity.py +0 -0
  147. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/agent_schema_registry.py +0 -0
  148. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/agent_schema_types.py +0 -0
  149. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/agent_test_workbench.py +0 -0
  150. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/collaboration_history.py +0 -0
  151. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/config_service.py +0 -0
  152. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/config_validator.py +0 -0
  153. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/conversation_pins.py +0 -0
  154. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/converter_jail/__init__.py +0 -0
  155. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/converter_jail/ast_guard.py +0 -0
  156. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/converter_jail/codeprep.py +0 -0
  157. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/converter_jail/gslides_runner.py +0 -0
  158. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/converter_jail/jail.py +0 -0
  159. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/converter_jail/pptx_runner.py +0 -0
  160. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/converter_jail/protocol.py +0 -0
  161. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/deck_css_aggregator.py +0 -0
  162. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/deck_review_store.py +0 -0
  163. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/design_system_compiler.py +0 -0
  164. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/design_system_service.py +0 -0
  165. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/design_system_templates.py +0 -0
  166. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/drive_uploader.py +0 -0
  167. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/evaluation/__init__.py +0 -0
  168. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/evaluation/llm_judge.py +0 -0
  169. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/foreman_service.py +0 -0
  170. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/gateway_openai.py +0 -0
  171. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/genie_service.py +0 -0
  172. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/google_slides_auth.py +0 -0
  173. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/google_slides_prompts_defaults.py +0 -0
  174. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph/__init__.py +0 -0
  175. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph/builder.py +0 -0
  176. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph/event_emitter.py +0 -0
  177. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph/routers.py +0 -0
  178. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph/state.py +0 -0
  179. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph_configuration.py +0 -0
  180. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph_configuration_bootstrap.py +0 -0
  181. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph_configuration_content.py +0 -0
  182. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph_configuration_draft.py +0 -0
  183. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph_configuration_publication.py +0 -0
  184. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph_configuration_rollback.py +0 -0
  185. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph_configuration_seed.py +0 -0
  186. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph_configuration_workbench.py +0 -0
  187. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph_definition_manifest.py +0 -0
  188. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph_release_evidence.py +0 -0
  189. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/graph_release_history.py +0 -0
  190. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/identity_provider.py +0 -0
  191. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/identity_providers/__init__.py +0 -0
  192. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/identity_providers/account_provider.py +0 -0
  193. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/identity_providers/local_provider.py +0 -0
  194. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/identity_providers/workspace_provider.py +0 -0
  195. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/image_service.py +0 -0
  196. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/image_tools.py +0 -0
  197. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/model_endpoint_catalog.py +0 -0
  198. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/permission_service.py +0 -0
  199. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/persisted_graph_release.py +0 -0
  200. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/pptx_from_html_huashu.py +0 -0
  201. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/pptx_from_records.py +0 -0
  202. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/pptx_prompts_defaults.py +0 -0
  203. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/profile_service.py +0 -0
  204. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/prompt_assembler.py +0 -0
  205. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/shared_deck_attribution.py +0 -0
  206. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/spec_sync.py +0 -0
  207. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/streaming_callback.py +0 -0
  208. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/template_sections.py +0 -0
  209. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/tools/__init__.py +0 -0
  210. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/tools/agent_bricks_tool.py +0 -0
  211. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/tools/ds_asset_tool.py +0 -0
  212. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/tools/genie_tool.py +0 -0
  213. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/tools/mcp_tool.py +0 -0
  214. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/tools/model_endpoint_tool.py +0 -0
  215. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/tools/vector_tool.py +0 -0
  216. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/services/validator.py +0 -0
  217. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/utils/__init__.py +0 -0
  218. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/utils/css_utils.py +0 -0
  219. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/utils/ds_asset_utils.py +0 -0
  220. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/utils/error_handling.py +0 -0
  221. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/utils/graph_safety.py +0 -0
  222. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/utils/html_safety.py +0 -0
  223. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/utils/html_utils.py +0 -0
  224. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/utils/image_utils.py +0 -0
  225. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/utils/js_validator.py +0 -0
  226. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/utils/logging_config.py +0 -0
  227. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/utils/pi_filter.py +0 -0
  228. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/utils/slide_hash.py +0 -0
  229. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/src/utils/spotlight.py +0 -0
  230. {databricks_tellr_app-0.4.3.dev35 → databricks_tellr_app-0.4.3.dev37}/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.dev35
3
+ Version: 0.4.3.dev37
4
4
  Summary: Tellr application package for Databricks Apps
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: databricks-tellr-app
3
- Version: 0.4.3.dev35
3
+ Version: 0.4.3.dev37
4
4
  Summary: Tellr application package for Databricks Apps
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
@@ -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.dev35"
7
+ version = "0.4.3.dev37"
8
8
  description = "Tellr application package for Databricks Apps"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -260,6 +260,7 @@ def _probe_result_response(
260
260
  endpoint_name=identity.endpoint_name,
261
261
  candidate_hash=identity.candidate_hash,
262
262
  lock_version=identity.lock_version,
263
+ provider_detail=failure.provider_detail,
263
264
  )
264
265
  return JSONResponse(
265
266
  status_code=_PROBE_FAILURE_STATUS[failure.code],
@@ -508,6 +508,9 @@ class StructuredOutputProbeFailureResponse(BaseModel):
508
508
  endpoint_name: str
509
509
  candidate_hash: str = Field(pattern=_LOWERCASE_SHA256)
510
510
  lock_version: int
511
+ #: Sanitised provider reason, present only on the probe route (admin workbench only).
512
+ #: Never included on runtime graph-turn error paths.
513
+ provider_detail: str | None = None
511
514
 
512
515
 
513
516
  # --- Agent Test Cases (#267) -------------------------------------------------
@@ -286,6 +286,25 @@ def resolve_engine_mode_or_unavailable(session_id: Optional[str]) -> str:
286
286
  ) from exc
287
287
 
288
288
 
289
+ #: The one client-facing text for a graph turn that failed for any reason other
290
+ #: than a typed pinned-configuration failure. Code-owned: the exception's own
291
+ #: text can carry model output (a parser error names the provider-chosen tool,
292
+ #: a ``ValidationError`` echoes the provider's arguments), so it never reaches
293
+ #: the stream event, the re-raised error or a route's error text (ws2a
294
+ #: follow-up A, fix round 1).
295
+ GRAPH_TURN_FAILED_MESSAGE = "The request could not be completed. Please try again."
296
+
297
+
298
+ class GraphTurnFailedError(RuntimeError):
299
+ """A failed graph turn, re-raised with a code-owned message.
300
+
301
+ The original exception is kept only as ``__cause__`` (for server logs).
302
+ """
303
+
304
+ def __init__(self) -> None:
305
+ super().__init__(GRAPH_TURN_FAILED_MESSAGE)
306
+
307
+
289
308
  def _pinned_graph_configuration_error_event() -> StreamEvent:
290
309
  """The one safe, typed event for an unavailable pinned graph configuration."""
291
310
  return StreamEvent(
@@ -1970,14 +1989,24 @@ class ChatService:
1970
1989
  error_container["error"] = graph_error
1971
1990
  event_queue.put(_pinned_graph_configuration_error_event())
1972
1991
  except Exception as e:
1992
+ # The traceback (server-side only) keeps the cause; the client
1993
+ # gets the code-owned message, never ``str(e)``.
1973
1994
  logger.error(
1974
- f"Graph turn failed: {e}",
1975
- extra={"session_id": session_id},
1995
+ "Graph turn failed",
1996
+ extra={"session_id": session_id, "error_class": type(e).__name__},
1976
1997
  exc_info=True,
1977
1998
  )
1978
- error_container["error"] = e
1999
+ if isinstance(e, SessionNotFoundError):
2000
+ # The routes map this type to their own code-owned text.
2001
+ error_container["error"] = e
2002
+ else:
2003
+ failure = GraphTurnFailedError()
2004
+ failure.__cause__ = e
2005
+ error_container["error"] = failure
1979
2006
  event_queue.put(
1980
- StreamEvent(type=StreamEventType.ERROR, error=str(e))
2007
+ StreamEvent(
2008
+ type=StreamEventType.ERROR, error=GRAPH_TURN_FAILED_MESSAGE
2009
+ )
1981
2010
  )
1982
2011
  finally:
1983
2012
  # Signal completion by putting None
@@ -100,6 +100,9 @@ def build_session_title_model():
100
100
  sends the same user message to the Gateway as the service principal, so
101
101
  this adds no new data exposure. Per-user identity on Gateway calls is
102
102
  workstream 2b (it needs the ``ai-gateway`` user scope and user re-consent).
103
+
104
+ No sampling parameter is sent: newer Claude models on the Gateway reject
105
+ ``temperature`` with a 400 (ws2a follow-up A).
103
106
  """
104
107
  from databricks_langchain import ChatDatabricks
105
108
 
@@ -110,7 +113,6 @@ def build_session_title_model():
110
113
  model=SESSION_TITLE_MODEL,
111
114
  use_ai_gateway=True,
112
115
  max_tokens=50,
113
- temperature=0.3,
114
116
  workspace_client=get_system_client(),
115
117
  )
116
118
 
@@ -121,6 +121,14 @@ class ProtectedPromptIdentity:
121
121
 
122
122
  @dataclass(frozen=True)
123
123
  class AgentModelConfiguration:
124
+ """One role's saved model configuration.
125
+
126
+ ``temperature`` and ``top_p`` are stored, hashed and published as saved, but
127
+ they are NOT sent to the model (ws2a follow-up A): newer Claude models on
128
+ Unity AI Gateway reject sampling parameters with a 400. Only
129
+ ``endpoint_name`` and ``max_tokens`` reach the provider.
130
+ """
131
+
124
132
  endpoint_name: str
125
133
  temperature: float
126
134
  max_tokens: int
@@ -223,6 +231,17 @@ def bind_structured_output_model(
223
231
  test-run adapter built by ``get_agent_test_runtime``. The production
224
232
  runtime adapter passes none.
225
233
 
234
+ What is sent (ws2a follow-up A): the model is constructed with the endpoint
235
+ and ``max_tokens`` only. The saved ``temperature`` / ``top_p`` are never
236
+ sent — newer Claude models reject them ("does not support the temperature
237
+ parameter"). ``schema`` is bound as the one tool with
238
+ ``tool_choice="auto"``: this is ``ChatDatabricks.with_structured_output``'s
239
+ function-calling branch, whose forced tool choice (``type "tool"``) newer
240
+ models also reject. Under ``auto`` a model may reply without calling the
241
+ tool; the parser then yields ``None`` and :func:`_require_structured_output`
242
+ raises ``OutputParserException``, the same parse-error class a malformed
243
+ tool call raises (see ``_is_provider_parse_error``).
244
+
226
245
  Only while a #267 test run's model call is in flight (its ``RunObservation``
227
246
  is the observed run) is the bound model given a callback that records the
228
247
  provider's reported token usage onto that observation. The binding itself
@@ -230,21 +249,41 @@ def bind_structured_output_model(
230
249
  production's; production ``run`` observes nothing and gets exactly
231
250
  the plain structured-output binding of ``schema``.
232
251
  """
252
+ # Imported lazily, like the chat model itself: the module stays import-light.
253
+ from langchain_core.output_parsers.openai_tools import PydanticToolsParser
254
+ from langchain_core.runnables import RunnableLambda
255
+
233
256
  model = model_factory(
234
257
  model=configuration.endpoint_name,
235
- temperature=configuration.temperature,
236
258
  max_tokens=configuration.max_tokens,
237
- top_p=configuration.top_p,
238
259
  workspace_client=workspace_client,
239
260
  **(transport_options or {}),
240
261
  )
241
- structured_model = model.with_structured_output(schema)
262
+ structured_model = (
263
+ model.bind_tools([schema], tool_choice="auto")
264
+ | PydanticToolsParser(tools=[schema], first_tool_only=True)
265
+ | RunnableLambda(_require_structured_output)
266
+ )
242
267
  observation = _OBSERVED_TEST_RUN.get()
243
268
  if observation is None:
244
269
  return structured_model
245
270
  return structured_model.with_config(callbacks=[_token_usage_callback(observation)])
246
271
 
247
272
 
273
+ def _require_structured_output(parsed: Any) -> Any:
274
+ """Refuse a reply that called no tool (``tool_choice="auto"`` permits one).
275
+
276
+ The message is code-owned: provider text never reaches it.
277
+ """
278
+ if parsed is None:
279
+ from langchain_core.exceptions import OutputParserException
280
+
281
+ raise OutputParserException(
282
+ "the model replied without calling the structured-output tool"
283
+ )
284
+ return parsed
285
+
286
+
248
287
  def _token_count(value: Any) -> int | None:
249
288
  """A provider-reported count, or ``None``: only a non-negative ``int`` is a count."""
250
289
  if isinstance(value, int) and not isinstance(value, bool) and value >= 0:
@@ -301,7 +340,7 @@ def _token_usage_callback(observation: RunObservation) -> Any:
301
340
 
302
341
 
303
342
  class DatabricksModelAdapter:
304
- """Invoke one structured Databricks model without binding any tools."""
343
+ """Invoke one structured Databricks model; the output schema is its only tool."""
305
344
 
306
345
  def __init__(
307
346
  self,
@@ -716,9 +716,10 @@ def _design_system_library() -> List[dict]:
716
716
  """Every live design system with its templates — §M1, delivered as payload.
717
717
 
718
718
  §M1 asks for "the architect's tool manifest" to carry the design-system
719
- library. **There is no manifest.** ``TOOL_GRANTS`` is ``[]``, ``bind_tools``
720
- appears nowhere under ``src/``, and AgentRuntime invokes the architect with
721
- structured output and no tools bound at all, so a library wired into
719
+ library. **There is no manifest.** ``TOOL_GRANTS`` is ``[]``, the one
720
+ ``bind_tools`` under ``src/`` binds only the output schema (the structured-
721
+ output binding in ``agent_runtime``), and AgentRuntime invokes the architect
722
+ with structured output and no other tool bound, so a library wired into
722
723
  ``tool_grants`` would be read by nothing. The operator ratified delivering
723
724
  §M1 through the architect's **payload** instead, beside
724
725
  ``available_design_contract`` and ``template_sections`` — the only channel
@@ -834,7 +834,6 @@ class HtmlToGoogleSlidesConverter:
834
834
  {"role": "system", "content": system_prompt},
835
835
  {"role": "user", "content": user_prompt},
836
836
  ],
837
- temperature=0.2,
838
837
  max_tokens=16384,
839
838
  timeout=300,
840
839
  extra_body={"thinking": {"type": "enabled", "budget_tokens": thinking_budget}},
@@ -527,7 +527,6 @@ class HtmlToPptxConverterV3:
527
527
  {"role": "system", "content": system_prompt},
528
528
  {"role": "user", "content": user_prompt}
529
529
  ],
530
- temperature=0.2,
531
530
  max_tokens=16384,
532
531
  timeout=300,
533
532
  extra_body={
@@ -16,13 +16,15 @@ Ownership boundaries:
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
+ import json
19
20
  import logging
21
+ import re
20
22
  from collections.abc import Callable, Iterable
21
23
  from dataclasses import dataclass
22
24
  from typing import Any, Literal, Protocol
23
25
 
24
26
  import openai
25
- from databricks.sdk.errors import PermissionDenied
27
+ from databricks.sdk.errors import DatabricksError, PermissionDenied
26
28
  from pydantic import BaseModel, ConfigDict
27
29
  from sqlalchemy.orm import Session
28
30
 
@@ -55,11 +57,14 @@ class StructuredOutputProbeFailure(RuntimeError): # noqa: N818 - stable public
55
57
  code: StructuredOutputProbeCode,
56
58
  message: str,
57
59
  retryable: bool,
60
+ *,
61
+ provider_detail: str | None = None,
58
62
  ) -> None:
59
63
  super().__init__(message)
60
64
  self.code = code
61
65
  self.message = message
62
66
  self.retryable = retryable
67
+ self.provider_detail = provider_detail
63
68
 
64
69
 
65
70
  _UNSUPPORTED = (
@@ -187,6 +192,110 @@ class DatabricksStructuredOutputProbe:
187
192
  raise _failure(_FAILED, None)
188
193
 
189
194
 
195
+ #: Dashed-UUID pattern (8-4-4-4-12) preserved for support diagnostics (e.g. ReqId).
196
+ _DASHED_UUID_RE = re.compile(
197
+ r"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"
198
+ )
199
+ _UUID_PLACEHOLDER = "\x00UUID\x00"
200
+ #: Strip URLs, bearer/dapi/JWT-like tokens, and long undashed hex/base64 runs.
201
+ #: Dashed UUIDs are excluded via pre/post substitution in _sanitise_provider_detail.
202
+ _URL_RE = re.compile(r"https?://\S+")
203
+ _TOKEN_RE = re.compile(r"\b(?:Bearer|dapi)[^\s,;\"']+", re.IGNORECASE)
204
+ _HEX_BASE64_RE = re.compile(r"[A-Za-z0-9+/=_\-]{32,}")
205
+ _WHITESPACE_RE = re.compile(r"\s+")
206
+ _PROVIDER_DETAIL_CAP = 300
207
+
208
+
209
+ def _sanitise_provider_detail(raw: str) -> str:
210
+ """Sanitise a provider error string for safe display.
211
+
212
+ Attempts to extract a message string from a JSON body, supporting:
213
+ - ``{"message": ...}`` (Gateway body; the value may itself be nested JSON)
214
+ - ``{"error": {"message": ...}}`` (openai-style error body)
215
+
216
+ After extraction, strips URLs, bearer/dapi tokens, and long undashed hex/base64
217
+ runs (≥32 chars). Dashed UUIDs (8-4-4-4-12 hex, e.g. request IDs) are preserved.
218
+ Collapses whitespace and caps at 300 characters.
219
+ """
220
+ # Try to parse as JSON and extract the message field.
221
+ text = raw
222
+ try:
223
+ obj = json.loads(raw)
224
+ if isinstance(obj, dict):
225
+ # Prefer top-level "message" (Gateway body shape).
226
+ msg: str | None = None
227
+ if isinstance(obj.get("message"), str):
228
+ msg = obj["message"]
229
+ # Fall back to openai-style {"error": {"message": ...}}.
230
+ elif isinstance(obj.get("error"), dict):
231
+ err = obj["error"]
232
+ if isinstance(err.get("message"), str):
233
+ msg = err["message"]
234
+ if msg is not None:
235
+ # Try one level of nested JSON (Gateway body shape).
236
+ try:
237
+ inner = json.loads(msg)
238
+ if isinstance(inner, dict) and isinstance(inner.get("message"), str):
239
+ text = inner["message"]
240
+ else:
241
+ text = msg
242
+ except (json.JSONDecodeError, ValueError):
243
+ text = msg
244
+ except (json.JSONDecodeError, ValueError):
245
+ pass
246
+
247
+ # Strip URLs.
248
+ text = _URL_RE.sub("", text)
249
+ # Strip bearer/dapi tokens.
250
+ text = _TOKEN_RE.sub("", text)
251
+ # Preserve dashed UUIDs (8-4-4-4-12) before stripping long hex/base64 runs.
252
+ # They carry request IDs useful for support diagnostics.
253
+ uuids = _DASHED_UUID_RE.findall(text)
254
+ text = _DASHED_UUID_RE.sub(_UUID_PLACEHOLDER, text)
255
+ # Strip long undashed hex/base64 runs (>= 32 chars).
256
+ text = _HEX_BASE64_RE.sub("", text)
257
+ # Restore dashed UUIDs.
258
+ for uuid in uuids:
259
+ text = text.replace(_UUID_PLACEHOLDER, uuid, 1)
260
+ # Collapse whitespace.
261
+ text = _WHITESPACE_RE.sub(" ", text).strip()
262
+ # Cap at 300 characters.
263
+ if len(text) > _PROVIDER_DETAIL_CAP:
264
+ text = text[:_PROVIDER_DETAIL_CAP] + "…"
265
+ return text
266
+
267
+
268
+ def _extract_provider_detail(error: BaseException) -> str | None:
269
+ """Extract a sanitised provider detail string from an error, if available.
270
+
271
+ Tries to find a JSON body (openai errors carry ``response.text`` or
272
+ ``body``), falling back to ``str(error)``. Returns ``None`` when the
273
+ error carries no useful provider text (e.g. connection errors without a
274
+ body).
275
+ """
276
+ # openai errors carry the raw response body.
277
+ body: str | None = None
278
+ if isinstance(error, openai.APIStatusError):
279
+ # openai >= 1.x: .response.text is the raw body; .body is the parsed dict.
280
+ try:
281
+ body = error.response.text
282
+ except Exception: # noqa: BLE001
283
+ pass
284
+ if not body:
285
+ try:
286
+ body = json.dumps(error.body) if error.body else None
287
+ except Exception: # noqa: BLE001
288
+ pass
289
+ elif isinstance(error, DatabricksError):
290
+ body = str(error) or None
291
+
292
+ if not body:
293
+ return None
294
+
295
+ detail = _sanitise_provider_detail(body)
296
+ return detail if detail else None
297
+
298
+
190
299
  def _failure(
191
300
  outcome: tuple[StructuredOutputProbeCode, str, bool],
192
301
  error: BaseException | None,
@@ -198,7 +307,10 @@ def _failure(
198
307
  code,
199
308
  type(error).__name__ if error is not None else "unexpected_output",
200
309
  )
201
- return StructuredOutputProbeFailure(code, message, retryable)
310
+ detail: str | None = None
311
+ if error is not None and isinstance(error, (openai.APIStatusError, DatabricksError)):
312
+ detail = _extract_provider_detail(error)
313
+ return StructuredOutputProbeFailure(code, message, retryable, provider_detail=detail)
202
314
 
203
315
 
204
316
  class FakeStructuredOutputProbe: