Skip to content
Open
Show file tree
Hide file tree
Changes from 85 commits
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
dd726b5
feat: integrate Switch transpiler with Lakebridge installer
hiroyukinakazato-db Sep 30, 2025
febb62d
Merge branch 'main' into feature/switch-installer-integration
hiroyukinakazato-db Sep 30, 2025
fa26b4c
fix: remove undefined URLError from exception handling
hiroyukinakazato-db Sep 30, 2025
6511e20
refactor: streamline SwitchInstaller deployment logic and update tests
hiroyukinakazato-db Oct 3, 2025
33ea7de
refactor: simplify SwitchInstaller test structure and improve assertions
hiroyukinakazato-db Oct 3, 2025
d0c63c3
Merge remote-tracking branch 'origin/main' into feature/switch-instal…
hiroyukinakazato-db Oct 3, 2025
7cb9ea9
feat: add Switch transpiler installer for Lakebridge integration
hiroyukinakazato-db Oct 7, 2025
467dea9
fix: support case-insensitive config lookup in SwitchInstaller
hiroyukinakazato-db Oct 8, 2025
57298b0
Merge branch 'main' into feature/switch-installer-integration
hiroyukinakazato-db Oct 8, 2025
09c0eb8
Merge branch 'main' into feature/switch-installer-integration
hiroyukinakazato-db Oct 9, 2025
8439314
refactor: separate Switch installation from workspace deployment
hiroyukinakazato-db Oct 9, 2025
5f66f3f
Merge branch 'main' into feature/switch-installer-integration
hiroyukinakazato-db Oct 9, 2025
fae9880
feat: add llm-transpile command with Switch integration
hiroyukinakazato-db Oct 7, 2025
2ee157f
refactor: encapsulate Switch package path resolution in SwitchDeployment
hiroyukinakazato-db Oct 9, 2025
9dc4b04
refactor: encapsulate Switch package path resolution in SwitchDeployment
hiroyukinakazato-db Oct 9, 2025
7637234
test: update Switch installation tests for refactored interface
hiroyukinakazato-db Oct 9, 2025
b736965
test: update Switch installation tests for refactored interface
hiroyukinakazato-db Oct 9, 2025
bacd5f6
fix: update error messages to include 'true' flag for install-transpi…
hiroyukinakazato-db Oct 9, 2025
729cb0d
Merge branch 'main' into feature/switch-installer-integration
hiroyukinakazato-db Oct 9, 2025
21b6629
Merge branch 'main' into feature/llm-transpile
hiroyukinakazato-db Oct 9, 2025
42ce0df
fix: exclude wait_for_completion from Switch job parameters
hiroyukinakazato-db Oct 10, 2025
81c32e5
fix: exclude wait_for_completion from Switch job parameters
hiroyukinakazato-db Oct 10, 2025
13bcc15
chore: update Switch wheel with wait_for_completion fix
hiroyukinakazato-db Oct 10, 2025
8dcf8f3
feat: add E2E test for Switch transpiler with environment variable co…
hiroyukinakazato-db Oct 14, 2025
83678b8
feat: enhance E2E testing for Switch with resource management and uni…
hiroyukinakazato-db Oct 14, 2025
f698470
Merge branch 'main' into feature/switch-installer-integration
hiroyukinakazato-db Oct 14, 2025
22cadc9
Defaults in `labs.yml` are strings.
asnare Oct 14, 2025
b3d2441
Update flag description to use placeholder syntax.
asnare Oct 14, 2025
ac7e2a4
Disable flag pending completion of integration.
asnare Oct 14, 2025
ee5c892
chore: merge main into feature/llm-transpile
hiroyukinakazato-db Oct 14, 2025
f0426e1
Leave pylint's max-args as-is.
asnare Oct 15, 2025
934c2e8
Remove unnecessary include_llm arguments.
asnare Oct 15, 2025
74923cc
Refactor Switch installation.
asnare Oct 16, 2025
084f90f
upgrade to latest switch plugin
sundarshankar89 Oct 21, 2025
61f796f
Merge branch 'main' into feature/switch-installer-integration
sundarshankar89 Oct 21, 2025
0c1d1d5
fixed package dependencies
sundarshankar89 Oct 21, 2025
6aeea25
Merge branch 'main' into feature/switch-installer-integration
sundarshankar89 Oct 22, 2025
468f8de
added additional configuration for making switch
sundarshankar89 Oct 22, 2025
6a57570
Latest Switch
sundarshankar89 Oct 22, 2025
2c3d153
Sorted List for FMAPI
sundarshankar89 Oct 22, 2025
f41dee8
setting logging level
sundarshankar89 Oct 22, 2025
950c1b8
setting logging level
sundarshankar89 Oct 22, 2025
6ca78ed
setting logging level
sundarshankar89 Oct 22, 2025
ba65df4
setting logging level
sundarshankar89 Oct 22, 2025
2e2abcb
setting logging level
sundarshankar89 Oct 22, 2025
bcbe4df
make default as first choice
sundarshankar89 Oct 22, 2025
486250f
fix tests
sundarshankar89 Oct 22, 2025
fc1ddca
fix tests
sundarshankar89 Oct 22, 2025
42c9c4e
fixes few bugs
sundarshankar89 Oct 23, 2025
1831076
update databricks-switch-plugin dependency to version 0.1.4
hiroyukinakazato-db Oct 26, 2025
01a0c87
Review Comments
sundarshankar89 Oct 27, 2025
ccce0f2
Review Comments
sundarshankar89 Oct 27, 2025
ac382d6
Merge branch 'main' into feature/llm-transpile
sundarshankar89 Oct 27, 2025
4600583
Merge branch 'feature/switch-installer-integration' into feature/llm-…
sundarshankar89 Oct 27, 2025
7f0eaa4
Rebased from switch installer integration
sundarshankar89 Oct 27, 2025
0e22abe
Rebased from switch installer integration
sundarshankar89 Oct 27, 2025
43cc0f5
Intermediate check in
sundarshankar89 Oct 27, 2025
bb7c3d6
Intermediate check in
sundarshankar89 Oct 27, 2025
bd70638
Intermediate check in
sundarshankar89 Oct 27, 2025
0eb1570
Intermediate check in
sundarshankar89 Oct 27, 2025
eae5997
Merge branch 'main' into feature/switch-installer-integration
sundarshankar89 Oct 28, 2025
9823201
Merge branch 'feature/switch-installer-integration' into feature/llm-…
sundarshankar89 Oct 28, 2025
eb46f24
initial tests
sundarshankar89 Oct 28, 2025
34c9f8f
Merge branch 'main' into feature/switch-installer-integration
sundarshankar89 Oct 28, 2025
c54e68f
Merge branch 'feature/switch-installer-integration' into feature/llm-…
sundarshankar89 Oct 28, 2025
23df37b
added tests for configurator
sundarshankar89 Oct 29, 2025
4a0bf49
added tests for installer
sundarshankar89 Oct 29, 2025
c49c5b3
added tests for installer
sundarshankar89 Oct 29, 2025
fab0e87
Merge branch 'feature/switch-installer-integration' into feature/llm-…
sundarshankar89 Oct 29, 2025
078a0bc
added tests for switch
sundarshankar89 Oct 29, 2025
1e10b60
added flag to fail if users use regular transpile after installing sw…
sundarshankar89 Oct 30, 2025
394ad9d
Merge branch 'feature/switch-installer-integration' into feature/llm-…
sundarshankar89 Oct 30, 2025
69f93b2
Merge branch 'main' into feature/switch-installer-integration
sundarshankar89 Oct 30, 2025
aeff475
Merge branch 'feature/switch-installer-integration' into feature/llm-…
sundarshankar89 Oct 30, 2025
7a336f9
added additional tests improved cuj
sundarshankar89 Oct 31, 2025
2602577
added user agent extra
sundarshankar89 Oct 31, 2025
b5bcbcd
Merge branch 'main' into feature/switch-installer-integration
asnare Nov 4, 2025
6132f04
removed interactive prompt with include_llm_transpiler
sundarshankar89 Nov 5, 2025
fb2ae71
Merge branch 'feature/switch-installer-integration' into feature/llm-…
sundarshankar89 Nov 5, 2025
53077ec
removed interactive prompt with include_llm_transpiler
sundarshankar89 Nov 5, 2025
186ab59
Merge branch 'main' into feature/switch-installer-integration
sundarshankar89 Nov 5, 2025
508d6c1
Merge branch 'feature/switch-installer-integration' into feature/llm-…
sundarshankar89 Nov 5, 2025
363a31d
execute llm transpile
sundarshankar89 Nov 5, 2025
c01d605
execute llm transpile
sundarshankar89 Nov 5, 2025
ebf969a
execute llm transpile
sundarshankar89 Nov 5, 2025
eb1d497
Merge branch 'main' into feature/switch-installer-integration
asnare Nov 6, 2025
52d6613
Log why the configuration questionnaire won't happen.
asnare Nov 6, 2025
11903f9
Logging tweaks.
asnare Nov 6, 2025
a62194d
Fix incorrect comment.
asnare Nov 6, 2025
24ad1b3
Style tweak, mark a method as static.
asnare Nov 6, 2025
4083dd6
Merge branch 'feature/switch-installer-integration' into feature/llm-…
asnare Nov 6, 2025
59fe56e
Merge branch 'main' into feature/switch-installer-integration
gueniai Nov 7, 2025
ab3851e
Merge branch 'feature/switch-installer-integration' into feature/llm-…
gueniai Nov 7, 2025
5a26f86
addressed review comments
sundarshankar89 Nov 7, 2025
efc3c64
Merge remote-tracking branch 'origin/feature/llm-transpile' into feat…
sundarshankar89 Nov 7, 2025
1a64612
addressed review comments
sundarshankar89 Nov 7, 2025
6ac2e68
addressed review comments
sundarshankar89 Nov 7, 2025
9799a23
addressed review comments
sundarshankar89 Nov 7, 2025
ddf7f1a
update latest switch plugin
sundarshankar89 Nov 7, 2025
0323ae0
Merge branch 'feature/switch-installer-integration' into feature/llm-…
sundarshankar89 Nov 7, 2025
cff62b1
removed duplicate
sundarshankar89 Nov 7, 2025
a5e06e3
Avoid raising DatabricksError ourselves.
asnare Nov 7, 2025
3ce1ffd
Avoid raising DatabricksError ourselves.
asnare Nov 7, 2025
df7b15c
Merge branch 'feature/switch-installer-integration' into feature/llm-…
asnare Nov 7, 2025
a659992
Update llm-transpile CLI description and help text.
asnare Nov 7, 2025
459d941
Foundational -> Foundation
asnare Nov 7, 2025
1aab9bf
Improve logging if there as issue locating the Switch job.
asnare Nov 7, 2025
c9bfda0
Simplify logic for computing the path where sources to convert are up…
asnare Nov 7, 2025
8ec00ca
Merge branch 'main' into feature/llm-transpile
asnare Nov 7, 2025
eefda07
Remove unnecessary exception wrapping.
asnare Nov 7, 2025
e0814c3
Reformat the legal disclaimer for LLM use, and adjust grammar.
asnare Nov 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ remorph_transpile/
/linter/src/main/antlr4/library/gen/
.databricks-login.json
.mypy_cache
.env
21 changes: 21 additions & 0 deletions labs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,24 @@ commands:
{{range .}}{{.total_files_processed}}\t{{.total_queries_processed}}\t{{.analysis_error_count}}\t{{.parsing_error_count}}\t{{.validation_error_count}}\t{{.generation_error_count}}\t{{.error_log_file}}
{{end}}

- name: llm-transpile
description: Transpile source code to Databricks using LLM Transpiler (Switch)
flags:
- name: input-source
description: Input Script Folder or File (local path)
- name: output-ws-folder
description: Output folder path (Databricks Workspace path starting with /Workspace/)
- name: source-dialect
description: Source dialect name (e.g., 'snowflake', 'teradata')
- name: catalog-name
description: Databricks Catalog name (already existing with relevant permission)
- name: schema-name
description: Databricks Schema name (already existing with relevant permission)
- name: volume
description: Databricks UC Volume name (already existing with relevant permission)
- name: foundational-model
description: Databricks Model Serving Endpoint

- name: reconcile
description: Reconcile source and target data residing on Databricks

Expand All @@ -63,6 +81,9 @@ commands:
- name: interactive
description: (Optional) Whether installing in interactive mode (`true|false|auto`); configuration settings are prompted for when interactive
default: auto
- name: include-llm-transpiler
description: (Optional) Whether to include LLM-based transpiler in installation (`true|false`)
default: "false"

- name: describe-transpile
description: Describe installed transpilers
Expand Down
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ dependencies = [
"SQLAlchemy~=2.0.40",
"pygls~=2.0.0a2",
"duckdb~=1.2.2",
"databricks-switch-plugin~=0.1.4", # Temporary, until Switch is migrated to be a transpiler (LSP) plugin.
"requests>=2.28.1,<3" # Matches databricks-sdk (and 'types-requests' below), to avoid conflicts.

]

[project.urls]
Expand Down Expand Up @@ -447,7 +449,7 @@ bad-functions = ["map", "input"]
# ignored-parents =

# Maximum number of arguments for function / method.
max-args = 12
max-args = 13

# Maximum number of attributes for a class (see R0902).
max-attributes = 13
Expand Down
148 changes: 146 additions & 2 deletions src/databricks/labs/lakebridge/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@
from databricks.labs.lakebridge.transpiler.lsp.lsp_engine import LSPEngine
from databricks.labs.lakebridge.transpiler.repository import TranspilerRepository
from databricks.labs.lakebridge.transpiler.sqlglot.sqlglot_engine import SqlglotEngine
from databricks.labs.lakebridge.transpiler.switch_runner import SwitchRunner
from databricks.labs.lakebridge.transpiler.transpile_engine import TranspileEngine

from databricks.labs.lakebridge.transpiler.transpile_status import ErrorSeverity
from databricks.labs.switch.lsp import get_switch_dialects


# Subclass to allow controlled access to protected methods.
Expand Down Expand Up @@ -92,7 +94,7 @@ def _remove_warehouse(ws: WorkspaceClient, warehouse_id: str):


@lakebridge.command
def transpile( # pylint: disable=too-many-arguments
def transpile(
*,
w: WorkspaceClient,
transpiler_config_path: str | None = None,
Expand Down Expand Up @@ -240,6 +242,14 @@ def use_transpiler_config_path(self, transpiler_config_path: str | None) -> None
)
self._config = dataclasses.replace(self._config, transpiler_config_path=transpiler_config_path)

# Switch is installed inside "/Users/<>/.lakebridge/transpilers/Switch/lsp/config.yml
if (
self._config.transpiler_config_path is not None
and Path(self._config.transpiler_config_path).parent.parent.name == "Switch"
):
msg = "Switch transpiler is not supported through `transpile` run `llm-transpile` instead."
raise RuntimeError(msg)

def use_source_dialect(self, source_dialect: str | None) -> None:
if source_dialect is not None:
# Defer validation: depends on the transpiler config path, we'll deal with this later.
Expand Down Expand Up @@ -730,6 +740,7 @@ def install_transpile(
w: WorkspaceClient,
artifact: str | None = None,
interactive: str | None = None,
include_llm_transpiler: bool = False,
transpiler_repository: TranspilerRepository = TranspilerRepository.user_home(),
) -> None:
"""Install or upgrade the Lakebridge transpilers."""
Expand All @@ -738,9 +749,15 @@ def install_transpile(
ctx.add_user_agent_extra("cmd", "install-transpile")
if artifact:
ctx.add_user_agent_extra("artifact-overload", Path(artifact).name)
if include_llm_transpiler:
ctx.add_user_agent_extra("include-llm-transpiler", "true")
# Decision was made not to prompt when include_llm_transpiler is set, and we expect users to use llm-transpile and pass all the arguments
is_interactive = False
user = w.current_user
logger.debug(f"User: {user}")
transpile_installer = installer(w, transpiler_repository, is_interactive=is_interactive)
transpile_installer = installer(
w, transpiler_repository, is_interactive=is_interactive, include_llm=include_llm_transpiler
)
transpile_installer.run(module="transpile", artifact=artifact)


Expand Down Expand Up @@ -818,6 +835,133 @@ def analyze(
logger.debug(f"User: {ctx.current_user}")


def _validate_llm_transpile_args(
input_source: str | None,
output_ws_folder: str | None,
source_dialect: str | None,
prompts: Prompts,
) -> tuple[str, str, str]:

_switch_dialects = get_switch_dialects()

# Validate presence after attempting to source from config
if not input_source:
input_source = prompts.question("Enter input SQL path")
if not output_ws_folder:
output_ws_folder = prompts.question("Enter output workspace folder must start with /Workspace/")
if not source_dialect:
source_dialect = prompts.choice("Select the source dialect", sorted(_switch_dialects))

# Validate input_source path exists (local path)
if not Path(input_source).exists():
raise_validation_exception(f"Invalid path for '--input-source': Path '{input_source}' does not exist.")

# Validate output_ws_folder is a workspace path
if not str(output_ws_folder).startswith("/Workspace/"):
raise_validation_exception(
f"Invalid value for '--output-ws-folder': workspace output path must start with /Workspace/. Got: {output_ws_folder!r}"
)

if source_dialect not in _switch_dialects:
raise_validation_exception(
f"Invalid value for '--source-dialect': {source_dialect!r} must be one of: {', '.join(sorted(_switch_dialects))}"
)

return input_source, output_ws_folder, source_dialect


@lakebridge.command
def llm_transpile(
*,
w: WorkspaceClient,
input_source: str | None = None,
output_ws_folder: str | None = None,
source_dialect: str | None = None,
catalog_name: str | None = None,
schema_name: str | None = None,
volume: str | None = None,
foundational_model: str | None = None,
ctx: ApplicationContext | None = None,
) -> None:
"""Transpile source code to Databricks using LLM Transpiler (Switch)"""
if ctx is None:
ctx = ApplicationContext(w)
del w
ctx.add_user_agent_extra("cmd", "llm-transpile")
user = ctx.current_user
logger.debug(f"User: {user}")

logger.info(
"""Please read and accept the following comments before proceeding:\n
This Feature leverages a large language model (LLM) to analyse and convert your provided content, code and data.\n
You consent to your content being transmitted to, processed by, and returned from the LLM hosted by Databricks foundational models or other external models you may configure during the runtime.\n
The outputs of the LLM are generated automatically without human review, and may contain inaccuracies or errors. \n
You are responsible for reviewing and validating all outputs before relying on them for any critical or production use. \n
By running this feature you accept these conditions.
"""
)

prompts = ctx.prompts
resource_configurator = ctx.resource_configurator

# If CLI args are missing, try to read them from config.yml
input_source, output_ws_folder, source_dialect = _validate_llm_transpile_args(
input_source,
output_ws_folder,
source_dialect,
prompts,
)

if catalog_name is None:
catalog_name = resource_configurator.prompt_for_catalog_setup(default_catalog_name="lakebridge")

if schema_name is None:
schema_name = resource_configurator.prompt_for_schema_setup(catalog=catalog_name, default_schema_name="switch")

if volume is None:
volume = resource_configurator.prompt_for_volume_setup(
catalog=catalog_name, schema=schema_name, default_volume_name="switch_volume"
)

resource_configurator.has_necessary_access(catalog_name, schema_name, volume)

if foundational_model is None:
foundational_model = resource_configurator.prompt_for_foundation_model_choice()

job_list = ctx.install_state.jobs
if "Switch" not in job_list:
raise RuntimeError(
"Switch Job ID not found. "
"Please run 'databricks labs lakebridge install-transpile --include-llm-transpiler true' first."
)
logger.debug("Switch job ID found in InstallState")
job_id = int(job_list["Switch"])

try:
ctx.add_user_agent_extra("transpiler_source_dialect", source_dialect)
job_runner = SwitchRunner(ctx.workspace_client, ctx.installation)
volume_input_path = job_runner.upload_to_volume(
local_path=Path(input_source),
catalog=catalog_name,
schema=schema_name,
volume=volume,
)

response = job_runner.run(
volume_input_path=volume_input_path,
output_ws_folder=output_ws_folder,
source_tech=source_dialect,
catalog=catalog_name,
schema=schema_name,
volume=volume,
foundational_model=foundational_model,
job_id=job_id,
)
json.dump(response, sys.stdout, indent=2)
except Exception as ex:
raise RuntimeError(ex) from ex
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'm not sure what this is for?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case there is an error while running the job!!



if __name__ == "__main__":
app = lakebridge
logger = app.get_logger()
Expand Down
7 changes: 5 additions & 2 deletions src/databricks/labs/lakebridge/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ class TranspileConfig:
error_file_path: str | None = None
sdk_config: dict[str, str] | None = None
skip_validation: bool = False
include_llm: bool = False
catalog_name: str = "remorph"
schema_name: str = "transpiler"
transpiler_options: JsonValue = None
Expand Down Expand Up @@ -274,5 +275,7 @@ class ReconcileConfig:

@dataclass
class LakebridgeConfiguration:
transpile: TranspileConfig | None = None
reconcile: ReconcileConfig | None = None
transpile: TranspileConfig | None
reconcile: ReconcileConfig | None
# Temporary flag, indicating whether to include the LLM-based Switch transpiler.
include_switch: bool = False
12 changes: 12 additions & 0 deletions src/databricks/labs/lakebridge/contexts/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from databricks.labs.lakebridge.deployment.dashboard import DashboardDeployment
from databricks.labs.lakebridge.deployment.installation import WorkspaceInstallation
from databricks.labs.lakebridge.deployment.recon import TableDeployment, JobDeployment, ReconDeployment
from databricks.labs.lakebridge.deployment.switch import SwitchDeployment
from databricks.labs.lakebridge.helpers.metastore import CatalogOperations

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -119,13 +120,24 @@ def recon_deployment(self) -> ReconDeployment:
self.dashboard_deployment,
)

@cached_property
def switch_deployment(self) -> SwitchDeployment:
return SwitchDeployment(
self.workspace_client,
self.installation,
self.install_state,
self.product_info,
self.job_deployment,
)

@cached_property
def workspace_installation(self) -> WorkspaceInstallation:
return WorkspaceInstallation(
self.workspace_client,
self.prompts,
self.installation,
self.recon_deployment,
self.switch_deployment,
self.product_info,
self.upgrades,
)
Expand Down
36 changes: 35 additions & 1 deletion src/databricks/labs/lakebridge/deployment/configurator.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import logging
import time

from collections.abc import Iterator

from databricks.labs.blueprint.tui import Prompts
from databricks.sdk import WorkspaceClient
from databricks.sdk.errors import DatabricksError
from databricks.sdk.service.catalog import Privilege, SecurableType
from databricks.sdk.service.sql import (
CreateWarehouseRequestWarehouseType,
EndpointInfoWarehouseType,
SpotInstancePolicy,
)
from databricks.sdk.service.serving import ServingEndpoint

from databricks.labs.lakebridge.helpers.metastore import CatalogOperations

Expand All @@ -29,8 +33,9 @@ def __init__(self, ws: WorkspaceClient, prompts: Prompts, catalog_ops: CatalogOp

def prompt_for_catalog_setup(
self,
default_catalog_name: str = "remorph",
) -> str:
catalog_name = self._prompts.question("Enter catalog name", default="remorph")
catalog_name = self._prompts.question("Enter catalog name", default=default_catalog_name)
catalog = self._catalog_ops.get_catalog(catalog_name)
if catalog:
logger.info(f"Found existing catalog `{catalog_name}`")
Expand Down Expand Up @@ -103,6 +108,35 @@ def warehouse_type(_):
raise SystemExit("Cannot continue installation, without a valid warehouse. Aborting the installation.")
return warehouse_id

def prompt_for_foundation_model_choice(self, default_choice: str = "databricks-claude-sonnet-4-5") -> str:
"""
List Serving Endpoints that expose a foundation model and prompt the user to pick one.
Returns the selected endpoint name
"""
endpoints: Iterator[ServingEndpoint] = self._ws.serving_endpoints.list()

model_endpoints = [
ep
for ep in endpoints
if ep.name
and ep.config
and ep.config.served_entities
and any(getattr(se, "foundation_model", None) is not None for se in ep.config.served_entities)
]

foundational_model_names = [ep.name for ep in model_endpoints if ep.name]

if foundational_model_names is None:
raise DatabricksError("No Foundation Model serving endpoints found. Aborting the installation.")
# This logic is implemented to make the default choice always to appear first in the list
other_models = sorted(set(foundational_model_names) - {default_choice})
choices = [f"[Recommended] {default_choice}", *other_models]
selected = self._prompts.choice("Select a Foundation Model serving endpoint:", choices, sort=True)

if selected.startswith("[Recommended]"):
selected = default_choice
return selected

def has_necessary_catalog_access(
self, catalog_name: str, user_name: str, privilege_sets: tuple[set[Privilege], ...]
):
Expand Down
Loading
Loading