Repository navigation
Expand file tree
/
Copy pathcli.py
More file actions
105 lines (97 loc) · 3.21 KB
/
Copy pathcli.py
File metadata and controls
105 lines (97 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
from __future__ import annotations
import asyncio
import logging
import sys
import typer
from .web.launcher import SqlroomsHttpServer
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)
app = typer.Typer(
add_completion=False,
pretty_exceptions_enable=False,
invoke_without_command=True,
)
@app.callback(invoke_without_command=True)
def main(
db_path: str | None = typer.Argument(
None,
help="DuckDB database to use (positional). Pass a filepath to persist, or ':memory:' for an in-memory DB (no file).",
),
db_path_option: str = typer.Option(
":memory:",
"--db-path",
"-d",
help="DuckDB database to use (flag). Defaults to ':memory:'.",
show_default=True,
),
host: str = typer.Option("127.0.0.1", "--host", help="HTTP host for the UI."),
port: int = typer.Option(4173, "--port", help="HTTP port for the UI."),
ws_port: int | None = typer.Option(
None,
"--ws-port",
help="WebSocket port for DuckDB queries. If omitted, a free port is chosen automatically.",
),
llm_provider: str = typer.Option(
"openai", "--llm-provider", help="Default LLM provider (e.g. openai, ollama)."
),
llm_model: str = typer.Option(
"gpt-4o-mini",
"--llm-model",
help="Default model name passed to the AI tools.",
),
api_key: str = typer.Option(
None,
"--api-key",
envvar="SQLROOMS_API_KEY",
help="API key for the chosen LLM provider.",
),
no_open_browser: bool = typer.Option(
False, "--no-open-browser", help="Skip automatically opening the browser."
),
ui: str = typer.Option(
None,
"--ui",
help="Optional path to a custom UI bundle directory (Vite dist). If omitted, uses the bundled default UI.",
),
sync: bool = typer.Option(
False,
"--sync",
help="Enable optional sync (CRDT) over WebSocket (Loro).",
),
meta_db: str | None = typer.Option(
None,
"--meta-db",
help="Optional path to a dedicated DuckDB file for SQLRooms meta state (UI state + CRDT snapshots). If omitted, stores meta tables in the main DB.",
),
meta_namespace: str = typer.Option(
"__sqlrooms",
"--meta-namespace",
help="Namespace used for SQLRooms meta tables. If --meta-db is provided, this is the ATTACH alias; otherwise it's a schema in the main DB.",
),
):
"""
Start the SQLRooms local experience:
- Boots a DuckDB websocket server (sqlrooms-server).
- Serves the AI example UI with persisted state stored in DuckDB.
"""
resolved_db_path = db_path if db_path is not None else db_path_option
server = SqlroomsHttpServer(
db_path=resolved_db_path,
host=host,
port=port,
ws_port=ws_port,
sync_enabled=sync,
meta_db=meta_db,
meta_namespace=meta_namespace,
llm_provider=llm_provider,
llm_model=llm_model,
api_key=api_key,
open_browser=not no_open_browser,
ui_dir=ui,
)
try:
asyncio.run(server.start())
except KeyboardInterrupt:
sys.stderr.write("\nShutting down...\n")