sql-chatbot-agent 1.0.0 → 1.1.0

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 (46) hide show
  1. package/README.md +368 -0
  2. package/dist/cli.d.ts +40 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +184 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/config.d.ts +7 -0
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +25 -6
  9. package/dist/config.js.map +1 -1
  10. package/dist/index.d.ts +2 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +3 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/llm/client.d.ts.map +1 -1
  15. package/dist/llm/client.js +20 -3
  16. package/dist/llm/client.js.map +1 -1
  17. package/dist/middleware.d.ts.map +1 -1
  18. package/dist/middleware.js +40 -1
  19. package/dist/middleware.js.map +1 -1
  20. package/dist/prompts/answer.d.ts +1 -1
  21. package/dist/prompts/answer.d.ts.map +1 -1
  22. package/dist/prompts/answer.js +107 -44
  23. package/dist/prompts/answer.js.map +1 -1
  24. package/dist/prompts/classify.d.ts.map +1 -1
  25. package/dist/prompts/classify.js +1 -0
  26. package/dist/prompts/classify.js.map +1 -1
  27. package/dist/prompts/generate-sql.d.ts.map +1 -1
  28. package/dist/prompts/generate-sql.js +6 -0
  29. package/dist/prompts/generate-sql.js.map +1 -1
  30. package/dist/services/code-indexer.d.ts +6 -1
  31. package/dist/services/code-indexer.d.ts.map +1 -1
  32. package/dist/services/code-indexer.js +267 -13
  33. package/dist/services/code-indexer.js.map +1 -1
  34. package/dist/services/orchestrator.d.ts +1 -0
  35. package/dist/services/orchestrator.d.ts.map +1 -1
  36. package/dist/services/orchestrator.js +14 -1
  37. package/dist/services/orchestrator.js.map +1 -1
  38. package/dist/services/schema.d.ts +1 -0
  39. package/dist/services/schema.d.ts.map +1 -1
  40. package/dist/services/schema.js +100 -1
  41. package/dist/services/schema.js.map +1 -1
  42. package/dist/services/sql-executor.d.ts.map +1 -1
  43. package/dist/services/sql-executor.js +3 -0
  44. package/dist/services/sql-executor.js.map +1 -1
  45. package/package.json +17 -3
  46. package/widget/widget.js +15 -13
package/README.md ADDED
@@ -0,0 +1,368 @@
1
+ # sql-chatbot-agent
2
+
3
+ AI-powered database chatbot that runs as a **standalone CLI** or **Express middleware**. Point it at any PostgreSQL database and get an AI assistant that can query your data, explain your code, and help users navigate your app.
4
+
5
+ **Zero configuration required** -- it auto-discovers your database schema, indexes your codebase, and serves a chat widget.
6
+
7
+ ## Quick Start (CLI)
8
+
9
+ The fastest way to get started is the standalone CLI. No existing Express app needed.
10
+
11
+ ### Install globally
12
+
13
+ ```bash
14
+ npm install -g sql-chatbot-agent
15
+ ```
16
+
17
+ ### Initialize a config file
18
+
19
+ ```bash
20
+ sql-chatbot-agent init
21
+ ```
22
+
23
+ This creates a `chatbot.config.json` in the current directory and adds it to `.gitignore`.
24
+
25
+ Edit the file with your database URL, then start the chatbot:
26
+
27
+ ```bash
28
+ sql-chatbot-agent
29
+ ```
30
+
31
+ The chatbot will be running at `http://localhost:3456` with a chat widget ready to use.
32
+
33
+ By default, it uses **OpenRouter** (free models, requires a free API key from [openrouter.ai/keys](https://openrouter.ai/keys)). See [Providers](#providers) for other options.
34
+
35
+ ### One-liner with npx
36
+
37
+ ```bash
38
+ # OpenRouter (free models -- get key at https://openrouter.ai/keys)
39
+ npx sql-chatbot-agent --db postgresql://localhost/mydb --key sk-or-v1-xxx --code ./app
40
+
41
+ # With Groq (cloud, faster)
42
+ npx sql-chatbot-agent --db postgresql://localhost/mydb --provider groq --key gsk_xxx --code ./app
43
+
44
+ # Or use environment variables
45
+ export OPENROUTER_API_KEY=sk-or-v1-xxx
46
+ npx sql-chatbot-agent --db postgresql://localhost/mydb --code ./app
47
+ ```
48
+
49
+ ## Configuration
50
+
51
+ ### chatbot.config.json
52
+
53
+ Created by `sql-chatbot-agent init`:
54
+
55
+ ```json
56
+ {
57
+ "databaseUrl": "postgresql://user:password@localhost:5432/your_database",
58
+ "provider": "openrouter",
59
+ "llmApiKey": "",
60
+ "codePaths": ["./src"],
61
+ "port": 3456,
62
+ "secret": ""
63
+ }
64
+ ```
65
+
66
+ | Field | Type | Description |
67
+ |-------|------|-------------|
68
+ | `databaseUrl` | string | PostgreSQL connection URL (required) |
69
+ | `provider` | string | LLM provider: `openrouter`, `groq`, `ollama`, or `openai` (default: auto-detect) |
70
+ | `llmApiKey` | string | API key for the LLM provider (not needed for OpenRouter or Ollama) |
71
+ | `llmModel` | string | Model name override (default: provider-specific) |
72
+ | `llmBaseUrl` | string | API base URL override (default: provider-specific) |
73
+ | `codePaths` | string[] | Directories to index for code questions (default: `["./src"]`) |
74
+ | `port` | number | Port for the standalone server (default: `3456`) |
75
+ | `secret` | string | Secret token for authentication (optional, recommended for production) |
76
+
77
+ > **Backward compat:** `groqApiKey` is still accepted and mapped to `llmApiKey` automatically.
78
+
79
+ ### CLI Flags
80
+
81
+ | Flag | Short | Description |
82
+ |------|-------|-------------|
83
+ | `--db` | | PostgreSQL connection URL |
84
+ | `--provider` | | LLM provider: `ollama`, `groq`, or `openai` |
85
+ | `--key` | | API key for the LLM provider |
86
+ | `--model` | | Model name override |
87
+ | `--base-url` | | API base URL override |
88
+ | `--code` | | Directory to index (single path) |
89
+ | `--port` | `-p` | Port for the standalone server |
90
+ | `--secret` | | Secret token for authentication |
91
+
92
+ ### Environment Variables
93
+
94
+ | Variable | Description |
95
+ |----------|-------------|
96
+ | `DATABASE_URL` | PostgreSQL connection URL |
97
+ | `LLM_PROVIDER` | LLM provider: `ollama`, `groq`, or `openai` |
98
+ | `LLM_API_KEY` | API key for the LLM provider |
99
+ | `OPENROUTER_API_KEY` | OpenRouter API key (auto-detects provider) |
100
+ | `LLM_MODEL` | Model name override |
101
+ | `LLM_BASE_URL` | API base URL override |
102
+ | `GROQ_API_KEY` | Groq API key (backward compat, same as `LLM_API_KEY`) |
103
+ | `CHATBOT_SECRET` | Secret token for authentication |
104
+ | `PORT` | Port for the standalone server |
105
+
106
+ ### Priority Order
107
+
108
+ Configuration is resolved in this order (highest priority first):
109
+
110
+ 1. **CLI flags** (`--db`, `--key`, etc.)
111
+ 2. **Environment variables** (`DATABASE_URL`, `GROQ_API_KEY`, etc.)
112
+ 3. **Config file** (`chatbot.config.json`)
113
+
114
+ ## Providers
115
+
116
+ sql-chatbot-agent works with any OpenAI-compatible LLM API. Four providers are preconfigured:
117
+
118
+ | Provider | Type | API Key | Default Model | Rate Limits |
119
+ |----------|------|---------|---------------|-------------|
120
+ | **OpenRouter** | Cloud | Required ([openrouter.ai/keys](https://openrouter.ai/keys)) | `openrouter/free` | 50 req/day free, 1000/day with $10 credit |
121
+ | **Groq** | Cloud | Required ([console.groq.com](https://console.groq.com)) | `llama-3.3-70b-versatile` | Free tier: 100K tokens/day |
122
+ | **Ollama** | Local | Not needed | `llama3.1:8b` | None (runs on your machine) |
123
+ | **OpenAI** | Cloud | Required ([platform.openai.com](https://platform.openai.com)) | `gpt-4o-mini` | Pay-per-use |
124
+
125
+ ### Auto-detection
126
+
127
+ If you don't specify `--provider`, the chatbot auto-detects:
128
+ - **`OPENROUTER_API_KEY` set** → uses `openrouter`
129
+ - **Other API key provided** → uses `groq`
130
+
131
+ ### OpenRouter (Default)
132
+
133
+ OpenRouter provides free access to 29+ models. Get a free API key at [openrouter.ai/keys](https://openrouter.ai/keys).
134
+
135
+ ```bash
136
+ # Set your key via env var or --key flag
137
+ export OPENROUTER_API_KEY=sk-or-v1-xxx
138
+ npx sql-chatbot-agent --db postgresql://localhost/mydb --code ./src
139
+ ```
140
+
141
+ **Rate limits:** 50 free model requests/day without credits. Add $10 credit (not consumed by free models) to unlock 1000/day. Resets daily at midnight UTC.
142
+
143
+ To use a specific free model from [OpenRouter's free collection](https://openrouter.ai/collections/free-models):
144
+
145
+ ```bash
146
+ npx sql-chatbot-agent --db postgresql://localhost/mydb --key sk-or-v1-xxx --model google/gemma-3-1b-it:free
147
+ ```
148
+
149
+ ### Groq (Cloud, Free Tier)
150
+
151
+ Faster than OpenRouter but requires a free API key.
152
+
153
+ ```bash
154
+ npx sql-chatbot-agent --db postgresql://localhost/mydb --provider groq --key gsk_xxx
155
+ ```
156
+
157
+ ### Ollama (Local, Offline)
158
+
159
+ For fully offline use. Requires [installing Ollama](https://ollama.com) and pulling a model.
160
+
161
+ ```bash
162
+ ollama pull llama3.1:8b && ollama serve
163
+ npx sql-chatbot-agent --db postgresql://localhost/mydb --provider ollama
164
+ ```
165
+
166
+ ### OpenAI
167
+
168
+ ```bash
169
+ npx sql-chatbot-agent --db postgresql://localhost/mydb --provider openai --key sk-xxx
170
+ ```
171
+
172
+ ### Any OpenAI-Compatible API
173
+
174
+ Use `--base-url` and `--model` to connect to any OpenAI-compatible API:
175
+
176
+ ```bash
177
+ npx sql-chatbot-agent --db postgresql://localhost/mydb \
178
+ --base-url http://my-llm-server:8080/v1 \
179
+ --key my-api-key \
180
+ --model my-model-name
181
+ ```
182
+
183
+ ## Authentication
184
+
185
+ For production use, set a secret token to protect the chatbot API.
186
+
187
+ ### Setup
188
+
189
+ Provide a secret via any configuration method:
190
+
191
+ ```bash
192
+ # CLI flag
193
+ sql-chatbot-agent --secret my-secret-token
194
+
195
+ # Environment variable
196
+ CHATBOT_SECRET=my-secret-token sql-chatbot-agent
197
+
198
+ # Or in chatbot.config.json
199
+ # { "secret": "my-secret-token" }
200
+ ```
201
+
202
+ ### How It Works
203
+
204
+ When a secret is configured:
205
+
206
+ 1. **Widget script** (`/chatbot/widget.js`) -- sets a `chatbot_token` cookie on load
207
+ 2. **API endpoints** (`/chatbot/api/ask`, `/chatbot/api/refresh`) -- validate the cookie or a `Bearer` token in the `Authorization` header
208
+ 3. **Health endpoint** (`/chatbot/api/health`) -- remains open (no sensitive data)
209
+
210
+ Requests without a valid token receive a `401 Unauthorized` response.
211
+
212
+ ### Without a Secret
213
+
214
+ If no secret is configured, the chatbot API is open to anyone. The CLI prints a warning on startup:
215
+
216
+ ```
217
+ Warning: No secret configured. The chatbot API is open to anyone.
218
+ ```
219
+
220
+ This is fine for local development but should not be used in production.
221
+
222
+ ### .gitignore
223
+
224
+ Add `chatbot.config.json` to your `.gitignore` to avoid committing secrets. The `init` command does this automatically.
225
+
226
+ ## Express Middleware (Advanced)
227
+
228
+ If you already have an Express app and want to embed the chatbot into it, use the middleware directly:
229
+
230
+ ### 1. Install
231
+
232
+ ```bash
233
+ npm install sql-chatbot-agent
234
+ ```
235
+
236
+ ### 2. Add to your Express app
237
+
238
+ ```js
239
+ const express = require('express');
240
+ const { sqlChatbot } = require('sql-chatbot-agent');
241
+
242
+ const app = express();
243
+
244
+ app.use('/chatbot', sqlChatbot({
245
+ databaseUrl: process.env.DATABASE_URL,
246
+ provider: 'openrouter', // or 'groq', 'ollama', 'openai'
247
+ llmApiKey: process.env.LLM_API_KEY, // not needed for openrouter/ollama
248
+ codePaths: ['./src'],
249
+ secret: process.env.CHATBOT_SECRET,
250
+ }));
251
+
252
+ app.listen(3000);
253
+ ```
254
+
255
+ ### 3. Add the widget to your HTML
256
+
257
+ ```html
258
+ <script src="/chatbot/widget.js"></script>
259
+ ```
260
+
261
+ A chat bubble appears in the bottom-right corner of your page.
262
+
263
+ ## How It Works
264
+
265
+ When a user asks a question, the chatbot:
266
+
267
+ 1. **Classifies** the question (data query, code question, navigation, etc.)
268
+ 2. **Routes** to the right handler:
269
+ - **Data questions** -- generates SQL, executes it read-only, explains the results
270
+ - **Code questions** -- searches your indexed codebase, explains the relevant code
271
+ - **Navigation** -- uses detected routes and page context to guide the user
272
+ 3. **Streams** the answer back via Server-Sent Events (SSE)
273
+
274
+ ```
275
+ User: "How many active users signed up this month?"
276
+ -> Classifies as "data" question
277
+ -> Generates: SELECT COUNT(*) FROM users WHERE active = true AND created_at >= '2026-02-01'
278
+ -> Executes read-only
279
+ -> Streams: "There are 142 active users who signed up this month."
280
+ ```
281
+
282
+ ## API Endpoints
283
+
284
+ When mounted at `/chatbot` (or running standalone), the following endpoints are available:
285
+
286
+ | Endpoint | Method | Description |
287
+ |----------|--------|-------------|
288
+ | `/chatbot/widget.js` | GET | Serves the chat widget bundle |
289
+ | `/chatbot/api/ask` | POST | Main chat endpoint (SSE streaming) |
290
+ | `/chatbot/api/health` | GET | Health check with table/file counts |
291
+ | `/chatbot/api/refresh` | POST | Re-discover schema and re-index code |
292
+
293
+ ### POST /api/ask
294
+
295
+ Request body:
296
+ ```json
297
+ {
298
+ "question": "How many users are there?",
299
+ "pageContext": "{\"url\": \"...\", \"title\": \"...\"}",
300
+ "history": [
301
+ { "role": "user", "content": "previous question" },
302
+ { "role": "assistant", "content": "previous answer" }
303
+ ]
304
+ }
305
+ ```
306
+
307
+ Response: SSE stream with events:
308
+ ```
309
+ data: {"type":"classifying"}
310
+ data: {"type":"classified","questionType":"data","confidence":0.9}
311
+ data: {"type":"sql","sql":"SELECT COUNT(*) FROM users"}
312
+ data: {"type":"executing"}
313
+ data: {"type":"token","content":"There"}
314
+ data: {"type":"token","content":" are"}
315
+ data: {"type":"token","content":" 1,234"}
316
+ data: {"type":"token","content":" users."}
317
+ data: {"type":"done"}
318
+ ```
319
+
320
+ ### GET /api/health
321
+
322
+ ```json
323
+ {
324
+ "status": "ok",
325
+ "tables": 25,
326
+ "codeFiles": 150
327
+ }
328
+ ```
329
+
330
+ ## Features
331
+
332
+ - **CLI standalone mode** -- run as a standalone server with zero boilerplate
333
+ - **Built-in authentication** -- secret token authentication with cookie and Bearer token support
334
+ - **Auto-discovers your database schema** -- tables, columns, types, foreign keys, indexes
335
+ - **Indexes your codebase** -- scans JS/TS/Ruby/Python files, detects Express/React/Next.js/Rails routes
336
+ - **SQL safety** -- validates queries against blocklists, executes in READ ONLY transactions, blocks destructive operations
337
+ - **Sensitive data filtering** -- automatically hides columns matching patterns like `password`, `secret`, `api_key`, `ssn`
338
+ - **Chat widget with Shadow DOM** -- no CSS conflicts with your app
339
+ - **Conversation history** -- the widget sends message history for contextual follow-ups
340
+ - **Multi-provider** -- Ollama (local, free), Groq (cloud, free tier), OpenAI, or any OpenAI-compatible API
341
+ - **Lazy initialization** -- schema discovery and code indexing happen on first request, not at startup
342
+
343
+ ## Supported Frameworks
344
+
345
+ The code indexer detects routes from:
346
+ - Express.js (`app.get`, `router.post`, etc.)
347
+ - React Router (`<Route path="...">`)
348
+ - Next.js (pages/ and app/ directory conventions)
349
+ - Rails (`resources`, `get`, `post` in routes.rb)
350
+
351
+ ## Security
352
+
353
+ - All SQL queries run inside `SET TRANSACTION READ ONLY` -- no writes possible
354
+ - Dangerous SQL keywords (`DROP`, `DELETE`, `TRUNCATE`, `ALTER`, etc.) are blocked before execution
355
+ - System catalogs (`pg_catalog`, `information_schema`) are blocked from queries
356
+ - Sensitive columns are automatically filtered from the schema summary sent to the LLM
357
+ - Built-in secret token authentication for production deployments
358
+ - `chatbot.config.json` is automatically added to `.gitignore` by the `init` command
359
+
360
+ ## Requirements
361
+
362
+ - Node.js >= 18
363
+ - PostgreSQL database
364
+ - An LLM provider: [OpenRouter](https://openrouter.ai/keys) (free key), [Groq](https://console.groq.com) (cloud, free tier), [Ollama](https://ollama.com) (local, free), [OpenAI](https://platform.openai.com), or any OpenAI-compatible API
365
+
366
+ ## License
367
+
368
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ import type { LLMProvider } from './config.js';
3
+ export interface CliFlags {
4
+ db?: string;
5
+ key?: string;
6
+ code?: string;
7
+ port?: string;
8
+ secret?: string;
9
+ provider?: string;
10
+ model?: string;
11
+ 'base-url'?: string;
12
+ subcommand?: string;
13
+ }
14
+ export interface FileConfig {
15
+ databaseUrl?: string;
16
+ groqApiKey?: string;
17
+ llmApiKey?: string;
18
+ provider?: LLMProvider;
19
+ llmModel?: string;
20
+ llmBaseUrl?: string;
21
+ codePaths?: string[];
22
+ port?: number;
23
+ secret?: string;
24
+ }
25
+ export interface MergedConfig {
26
+ databaseUrl?: string;
27
+ llmApiKey?: string;
28
+ provider?: LLMProvider;
29
+ llmModel?: string;
30
+ llmBaseUrl?: string;
31
+ codePaths: string[];
32
+ port: number;
33
+ secret?: string;
34
+ }
35
+ export declare function parseCliArgs(argv: string[]): CliFlags;
36
+ export declare function loadConfigFile(dir: string): FileConfig;
37
+ export declare function mergeConfig(file: FileConfig, env: Record<string, string | undefined>, flags: CliFlags): MergedConfig;
38
+ export declare function runInit(dir: string): void;
39
+ export declare function checkOllamaConnection(baseUrl: string): Promise<boolean>;
40
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,MAAM,WAAW,QAAQ;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,CAqBrD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAKtD;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EACvC,KAAK,EAAE,QAAQ,GACd,YAAY,CAiBd;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CA+BzC;AAED,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO7E"}
package/dist/cli.js ADDED
@@ -0,0 +1,184 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.parseCliArgs = parseCliArgs;
8
+ exports.loadConfigFile = loadConfigFile;
9
+ exports.mergeConfig = mergeConfig;
10
+ exports.runInit = runInit;
11
+ exports.checkOllamaConnection = checkOllamaConnection;
12
+ const node_util_1 = require("node:util");
13
+ const node_fs_1 = __importDefault(require("node:fs"));
14
+ const node_path_1 = __importDefault(require("node:path"));
15
+ const config_js_1 = require("./config.js");
16
+ function parseCliArgs(argv) {
17
+ if (argv[0] && !argv[0].startsWith('-')) {
18
+ return { subcommand: argv[0] };
19
+ }
20
+ const { values } = (0, node_util_1.parseArgs)({
21
+ args: argv,
22
+ options: {
23
+ db: { type: 'string' },
24
+ key: { type: 'string' },
25
+ code: { type: 'string' },
26
+ port: { type: 'string', short: 'p' },
27
+ secret: { type: 'string' },
28
+ provider: { type: 'string' },
29
+ model: { type: 'string' },
30
+ 'base-url': { type: 'string' },
31
+ },
32
+ strict: false,
33
+ });
34
+ return values;
35
+ }
36
+ function loadConfigFile(dir) {
37
+ const configPath = node_path_1.default.join(dir, 'chatbot.config.json');
38
+ if (!node_fs_1.default.existsSync(configPath))
39
+ return {};
40
+ const raw = node_fs_1.default.readFileSync(configPath, 'utf-8');
41
+ return JSON.parse(raw);
42
+ }
43
+ function mergeConfig(file, env, flags) {
44
+ // Resolve API key: flags --key > env > file (llmApiKey or groqApiKey for backward compat)
45
+ const llmApiKey = flags.key || env.LLM_API_KEY || env.GROQ_API_KEY || env.OPENROUTER_API_KEY || file.llmApiKey || file.groqApiKey;
46
+ // Resolve provider: flags > env > file > auto-detect (has key → groq, no key → ollama)
47
+ const provider = (flags.provider || env.LLM_PROVIDER || file.provider || undefined);
48
+ return {
49
+ databaseUrl: flags.db || env.DATABASE_URL || file.databaseUrl,
50
+ llmApiKey,
51
+ provider,
52
+ llmModel: flags.model || env.LLM_MODEL || file.llmModel,
53
+ llmBaseUrl: flags['base-url'] || env.LLM_BASE_URL || file.llmBaseUrl,
54
+ codePaths: flags.code ? [flags.code] : file.codePaths || ['./src'],
55
+ port: flags.port ? parseInt(flags.port, 10) : env.PORT ? parseInt(env.PORT, 10) : file.port || 3456,
56
+ secret: flags.secret || env.CHATBOT_SECRET || file.secret,
57
+ };
58
+ }
59
+ function runInit(dir) {
60
+ const configPath = node_path_1.default.join(dir, 'chatbot.config.json');
61
+ if (node_fs_1.default.existsSync(configPath)) {
62
+ console.log('chatbot.config.json already exists, skipping.');
63
+ }
64
+ else {
65
+ const template = {
66
+ databaseUrl: 'postgresql://user:password@localhost:5432/your_database',
67
+ provider: 'openrouter',
68
+ llmApiKey: '',
69
+ codePaths: ['./src'],
70
+ port: 3456,
71
+ secret: '',
72
+ };
73
+ node_fs_1.default.writeFileSync(configPath, JSON.stringify(template, null, 2) + '\n');
74
+ console.log('Created chatbot.config.json');
75
+ }
76
+ const gitignorePath = node_path_1.default.join(dir, '.gitignore');
77
+ const entry = 'chatbot.config.json';
78
+ if (node_fs_1.default.existsSync(gitignorePath)) {
79
+ const content = node_fs_1.default.readFileSync(gitignorePath, 'utf-8');
80
+ if (!content.includes(entry)) {
81
+ node_fs_1.default.appendFileSync(gitignorePath, '\n' + entry + '\n');
82
+ console.log('Added chatbot.config.json to .gitignore');
83
+ }
84
+ else {
85
+ console.log('chatbot.config.json already in .gitignore');
86
+ }
87
+ }
88
+ else {
89
+ node_fs_1.default.writeFileSync(gitignorePath, entry + '\n');
90
+ console.log('Created .gitignore with chatbot.config.json');
91
+ }
92
+ }
93
+ async function checkOllamaConnection(baseUrl) {
94
+ try {
95
+ const response = await fetch(baseUrl.replace(/\/v1$/, '/api/tags'), { signal: AbortSignal.timeout(3000) });
96
+ return response.ok;
97
+ }
98
+ catch {
99
+ return false;
100
+ }
101
+ }
102
+ function main() {
103
+ // Dynamic imports to avoid loading express/cors at test time
104
+ const flags = parseCliArgs(process.argv.slice(2));
105
+ if (flags.subcommand === 'init') {
106
+ runInit(process.cwd());
107
+ return;
108
+ }
109
+ const fileConfig = loadConfigFile(process.cwd());
110
+ const config = mergeConfig(fileConfig, process.env, flags);
111
+ if (!config.databaseUrl) {
112
+ console.error('Error: Database URL is required.');
113
+ console.error('Provide --db flag, set DATABASE_URL env var, or add databaseUrl to chatbot.config.json');
114
+ process.exit(1);
115
+ }
116
+ // API key is required for all providers except ollama
117
+ if (!config.llmApiKey && config.provider !== 'ollama') {
118
+ console.error('Error: API key is required.');
119
+ console.error('Provide --key flag, set LLM_API_KEY or OPENROUTER_API_KEY env var.');
120
+ console.error('Get a free OpenRouter key at: https://openrouter.ai/keys');
121
+ process.exit(1);
122
+ }
123
+ if (!config.secret) {
124
+ console.warn('Warning: No secret configured. The chatbot API is open to anyone.');
125
+ console.warn('Set --secret flag, CHATBOT_SECRET env var, or add secret to chatbot.config.json');
126
+ }
127
+ // Detect effective provider for connectivity check
128
+ const effectiveProvider = config.provider || (config.llmApiKey ? 'groq' : 'openrouter');
129
+ const ollamaBaseUrl = config.llmBaseUrl || config_js_1.PROVIDER_PRESETS.ollama.baseUrl;
130
+ // Import express and cors dynamically to keep test imports clean
131
+ (async () => {
132
+ // Check Ollama connectivity before starting server
133
+ if (effectiveProvider === 'ollama') {
134
+ const ok = await checkOllamaConnection(ollamaBaseUrl);
135
+ if (!ok) {
136
+ console.error('\nError: Ollama is not running at ' + ollamaBaseUrl);
137
+ console.error('Start it with: ollama serve');
138
+ console.error('Then pull a model: ollama pull llama3.1:8b\n');
139
+ process.exit(1);
140
+ }
141
+ }
142
+ const expressModule = await import('express');
143
+ const express = expressModule.default;
144
+ const corsModule = await import('cors');
145
+ const cors = corsModule.default;
146
+ const { sqlChatbot } = await import('./middleware.js');
147
+ const app = express();
148
+ app.use(cors());
149
+ app.use('/chatbot', sqlChatbot({
150
+ databaseUrl: config.databaseUrl,
151
+ llmApiKey: config.llmApiKey,
152
+ llmBaseUrl: config.llmBaseUrl,
153
+ llmModel: config.llmModel,
154
+ provider: config.provider,
155
+ codePaths: config.codePaths,
156
+ secret: config.secret,
157
+ }));
158
+ app.get('/', (_req, res) => {
159
+ res.send(`<!DOCTYPE html>
160
+ <html>
161
+ <head><title>SQL Chatbot</title></head>
162
+ <body>
163
+ <h1>SQL Chatbot</h1>
164
+ <p>The chat widget should appear in the bottom-right corner.</p>
165
+ <script src="/chatbot/widget.js"></script>
166
+ </body>
167
+ </html>`);
168
+ });
169
+ const providerLabel = config.provider || (config.llmApiKey ? 'groq' : 'openrouter');
170
+ app.listen(config.port, () => {
171
+ console.log(`\nSQL Chatbot Agent running at http://localhost:${config.port}`);
172
+ console.log(` Provider: ${providerLabel}`);
173
+ console.log(` Chat widget: http://localhost:${config.port}`);
174
+ console.log(` Health check: http://localhost:${config.port}/chatbot/api/health`);
175
+ console.log(` Auth: ${config.secret ? 'enabled' : 'DISABLED (no secret)'}\n`);
176
+ });
177
+ })();
178
+ }
179
+ // Only run main when executed directly (not when imported for testing)
180
+ const isDirectRun = process.argv[1]?.endsWith('cli.js') || process.argv[1]?.endsWith('cli.ts');
181
+ if (isDirectRun) {
182
+ main();
183
+ }
184
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -1,9 +1,16 @@
1
+ export type LLMProvider = 'groq' | 'ollama' | 'openai' | 'openrouter';
2
+ export declare const PROVIDER_PRESETS: Record<LLMProvider, {
3
+ baseUrl: string;
4
+ model: string;
5
+ }>;
1
6
  export interface AgentConfig {
2
7
  databaseUrl: string;
3
8
  codePaths: string[];
4
9
  llmBaseUrl: string;
5
10
  llmApiKey: string;
6
11
  llmModel: string;
12
+ provider?: LLMProvider;
13
+ secret?: string;
7
14
  }
8
15
  export declare function resolveConfig(userConfig: Partial<AgentConfig> & {
9
16
  databaseUrl: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,aAAa,CAC3B,UAAU,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9E,WAAW,CAwBb"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEtE,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,WAAW,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAKpF,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,aAAa,CAC3B,UAAU,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9E,WAAW,CAwCb"}