1313from typing import Any
1414
1515import click
16- import llm
17- from llm .cli import cli
16+
17+ try :
18+ import llm
19+
20+ LLM_IMPORTED = True
21+ except ImportError :
22+ llm = None
23+ LLM_IMPORTED = False
24+
25+ try :
26+ from llm .cli import cli
27+
28+ LLM_CLI_IMPORTED = True
29+ except ImportError :
30+ cli = None
31+ LLM_CLI_IMPORTED = False
1832
1933from . import export
2034from .main import Verbosity , parse_special_command
2337log = logging .getLogger (__name__ )
2438
2539LLM_TEMPLATE_NAME = "litecli-llm-template"
26- LLM_CLI_COMMANDS : list [str ] = list (cli .commands .keys ())
40+ LLM_CLI_COMMANDS : list [str ] = list (cli .commands .keys ()) if LLM_CLI_IMPORTED else []
2741# Mapping of model_id to None used for completion tree leaves.
2842# the file name is llm.py and module name is llm, hence ty is complaining that get_models is missing.
29- MODELS : dict [str , None ] = {x .model_id : None for x in llm .get_models ()} # type: ignore[attr-defined]
43+ MODELS : dict [str , None ] = {x .model_id : None for x in llm .get_models ()} if LLM_IMPORTED else {} # type: ignore[attr-defined]
3044
3145
3246def run_external_cmd (
@@ -110,7 +124,7 @@ def build_command_tree(cmd: click.Command) -> dict[str, Any] | None:
110124
111125
112126# Generate the tree
113- COMMAND_TREE : dict [str , Any ] | None = build_command_tree (cli )
127+ COMMAND_TREE : dict [str , Any ] | None = build_command_tree (cli ) if LLM_CLI_IMPORTED else {}
114128
115129
116130def get_completions (tokens : list [str ], tree : dict [str , Any ] | None = COMMAND_TREE ) -> list [str ]:
@@ -123,6 +137,8 @@ def get_completions(tokens: list[str], tree: dict[str, Any] | None = COMMAND_TRE
123137 Returns:
124138 list[str]: List of possible completions.
125139 """
140+ if not LLM_CLI_IMPORTED :
141+ return []
126142 for token in tokens :
127143 if token .startswith ("-" ):
128144 # Skip options (flags)
@@ -171,6 +187,18 @@ def __init__(self, results: Any | None = None) -> None:
171187# https://llm.datasette.io/en/stable/plugins/directory.html
172188"""
173189
190+ NEED_DEPENDENCIES = """
191+ To enable LLM features you need to install litecli with AI support:
192+
193+ pip install 'litecli[ai]'
194+
195+ or install LLM libraries separately
196+
197+ pip install llm
198+
199+ This is required to use the \\ llm command.
200+ """
201+
174202_SQL_CODE_FENCE = r"```sql\n(.*?)\n```"
175203PROMPT = """
176204You are a helpful assistant who is a SQLite expert. You are embedded in a SQLite
@@ -230,6 +258,10 @@ def handle_llm(text: str, cur: DBCursor) -> tuple[str, str | None, float]:
230258 is_verbose = mode is Verbosity .VERBOSE
231259 is_succinct = mode is Verbosity .SUCCINCT
232260
261+ if not LLM_IMPORTED :
262+ output = [(None , None , None , NEED_DEPENDENCIES )]
263+ raise FinishIteration (output )
264+
233265 if not arg .strip (): # No question provided. Print usage and bail.
234266 output = [(None , None , None , USAGE )]
235267 raise FinishIteration (output )
0 commit comments