nttp 1.4.11 → 1.4.15

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.
package/docs/api.md ADDED
@@ -0,0 +1,571 @@
1
+ # API Reference
2
+
3
+ Complete API documentation for NTTP.
4
+
5
+ ## Table of Contents
6
+
7
+ - [NTTP Class](#nttp-class)
8
+ - [Constructor](#constructor)
9
+ - [Static Methods](#static-methods)
10
+ - [Instance Methods](#instance-methods)
11
+ - [Types](#types)
12
+ - [Errors](#errors)
13
+
14
+ ---
15
+
16
+ ## NTTP Class
17
+
18
+ ### Constructor
19
+
20
+ #### `new NTTP(config: NTTPConfig)`
21
+
22
+ Creates a new NTTP instance with manual configuration.
23
+
24
+ **Parameters:**
25
+
26
+ ```typescript
27
+ interface NTTPConfig {
28
+ database: DatabaseConfig;
29
+ llm: LLMConfig;
30
+ cache?: CacheConfig;
31
+ limits?: LimitsConfig;
32
+ }
33
+ ```
34
+
35
+ **Example:**
36
+
37
+ ```typescript
38
+ import { NTTP } from 'nttp';
39
+
40
+ const nttp = new NTTP({
41
+ database: {
42
+ client: 'pg',
43
+ connection: 'postgresql://user:pass@localhost:5432/mydb'
44
+ },
45
+ llm: {
46
+ provider: 'anthropic',
47
+ model: 'claude-sonnet-4-5-20250929',
48
+ apiKey: process.env.ANTHROPIC_API_KEY
49
+ },
50
+ cache: {
51
+ l1: { enabled: true, maxSize: 1000 },
52
+ l2: { enabled: true, provider: 'openai', apiKey: process.env.OPENAI_API_KEY },
53
+ redis: { url: 'redis://localhost:6379' }
54
+ }
55
+ });
56
+ ```
57
+
58
+ See [Configuration](./configuration.md) for all config options.
59
+
60
+ ---
61
+
62
+ ### Static Methods
63
+
64
+ #### `NTTP.fromEnv(): Promise<NTTP>`
65
+
66
+ Creates an NTTP instance from environment variables. This is the recommended way to initialize NTTP.
67
+
68
+ **Environment Variables Required:**
69
+
70
+ ```bash
71
+ DATABASE_TYPE=pg
72
+ DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
73
+ LLM_PROVIDER=anthropic
74
+ LLM_MODEL=claude-sonnet-4-5-20250929
75
+ ANTHROPIC_API_KEY=sk-ant-...
76
+ ```
77
+
78
+ **Optional Environment Variables:**
79
+
80
+ ```bash
81
+ REDIS_URL=redis://localhost:6379
82
+ OPENAI_API_KEY=sk-... # For L2 semantic cache
83
+ ```
84
+
85
+ **Example:**
86
+
87
+ ```typescript
88
+ import { NTTP } from 'nttp';
89
+
90
+ // Automatically reads from .env file (using dotenv)
91
+ const nttp = await NTTP.fromEnv();
92
+ const result = await nttp.query("show me users");
93
+ await nttp.close();
94
+ ```
95
+
96
+ **Returns:** `Promise<NTTP>` - Initialized NTTP instance (already called `init()`)
97
+
98
+ **Throws:** `Error` if required environment variables are missing
99
+
100
+ See [Configuration](./configuration.md#environment-variables) for complete env var reference.
101
+
102
+ ---
103
+
104
+ ### Instance Methods
105
+
106
+ #### `init(): Promise<void>`
107
+
108
+ Initializes the NTTP instance by connecting to the database and building the schema cache.
109
+
110
+ **Required:** Must be called before any queries (unless using `fromEnv()`, which calls this automatically).
111
+
112
+ **Example:**
113
+
114
+ ```typescript
115
+ const nttp = new NTTP({ /* config */ });
116
+ await nttp.init(); // Connect to database, build schema cache
117
+ ```
118
+
119
+ **Throws:** `Error` if database connection fails
120
+
121
+ ---
122
+
123
+ #### `query(query: string, options?: QueryOptions): Promise<QueryResult>`
124
+
125
+ Execute a natural language query against the database.
126
+
127
+ **Parameters:**
128
+
129
+ - `query` (string): Natural language query (e.g., "show me active users")
130
+ - `options` (optional):
131
+ ```typescript
132
+ interface QueryOptions {
133
+ useCache?: boolean; // Default: true
134
+ forceNewSchema?: boolean; // Default: false
135
+ }
136
+ ```
137
+
138
+ **Returns:**
139
+
140
+ ```typescript
141
+ interface QueryResult {
142
+ query: string; // Original natural language query
143
+ data: any[]; // Query results (array of objects)
144
+ schemaId: string; // Cache key (16-char hash)
145
+ cacheHit: boolean; // true if result came from cache
146
+ intent: Intent; // Parsed intent structure
147
+ sql?: string; // Generated SQL (for debugging)
148
+ params?: any[]; // SQL parameters (for debugging)
149
+ meta?: { // Cache metadata (v2 only)
150
+ cacheLayer: 1 | 2 | 3; // Which cache layer was hit
151
+ cost: number; // Estimated cost in USD
152
+ latency: number; // Query latency in ms
153
+ similarity?: number; // Semantic similarity (L2 only)
154
+ };
155
+ }
156
+ ```
157
+
158
+ **Examples:**
159
+
160
+ ```typescript
161
+ // Basic query
162
+ const result = await nttp.query("show me 5 users");
163
+ console.log(result.data); // Array of user objects
164
+
165
+ // Filtered query
166
+ const active = await nttp.query("active users from California");
167
+
168
+ // Aggregation
169
+ const count = await nttp.query("count pending orders");
170
+
171
+ // With options
172
+ const fresh = await nttp.query("show products", {
173
+ useCache: false, // Skip cache, always generate new SQL
174
+ forceNewSchema: true // Force new schema generation
175
+ });
176
+
177
+ // Check cache performance
178
+ const result = await nttp.query("show users");
179
+ if (result.meta) {
180
+ console.log(`Cache: L${result.meta.cacheLayer}, Cost: $${result.meta.cost}, Latency: ${result.meta.latency}ms`);
181
+ }
182
+ ```
183
+
184
+ **Automatic Error Correction:**
185
+
186
+ If the generated SQL fails to execute, NTTP automatically:
187
+ 1. Sends the error back to the LLM
188
+ 2. Asks it to analyze and fix the issue
189
+ 3. Retries with corrected SQL (up to 3 attempts total)
190
+
191
+ This significantly improves success rate for queries with minor issues like:
192
+ - Wrong column names (LLM checks schema and corrects)
193
+ - Syntax errors (LLM fixes syntax)
194
+ - Type mismatches (LLM adjusts types)
195
+
196
+ **Throws:**
197
+ - `IntentParseError` - Failed to parse natural language query
198
+ - `SQLGenerationError` - Failed to generate SQL from intent
199
+ - `SQLExecutionError` - Database query execution failed after all retry attempts
200
+
201
+ See [Examples](./examples.md) for comprehensive query examples.
202
+
203
+ ---
204
+
205
+ #### `explain(query: string): Promise<ExplanationResult>`
206
+
207
+ Explains what SQL would be generated for a query without executing it. Useful for debugging and understanding how NTTP interprets queries.
208
+
209
+ **Parameters:**
210
+
211
+ - `query` (string): Natural language query to explain
212
+
213
+ **Returns:**
214
+
215
+ ```typescript
216
+ interface ExplanationResult {
217
+ query: string; // Original query
218
+ intent: Intent; // Parsed intent
219
+ sql: string; // Generated SQL
220
+ params: any[]; // SQL parameters
221
+ schemaId: string; // Cache key
222
+ cachedSchema: SchemaDefinition | null; // Cached schema if exists
223
+ }
224
+ ```
225
+
226
+ **Example:**
227
+
228
+ ```typescript
229
+ const explanation = await nttp.explain("top 10 expensive products");
230
+
231
+ console.log('Intent:', explanation.intent);
232
+ // { entity: 'products', operation: 'list', sort: 'price:desc', limit: 10, ... }
233
+
234
+ console.log('SQL:', explanation.sql);
235
+ // SELECT * FROM products ORDER BY price DESC LIMIT ?
236
+
237
+ console.log('Params:', explanation.params);
238
+ // [10]
239
+ ```
240
+
241
+ ---
242
+
243
+ #### `close(): Promise<void>`
244
+
245
+ Closes the database connection and cleans up resources. Always call this when done using NTTP.
246
+
247
+ **Example:**
248
+
249
+ ```typescript
250
+ const nttp = await NTTP.fromEnv();
251
+ try {
252
+ const result = await nttp.query("show users");
253
+ console.log(result.data);
254
+ } finally {
255
+ await nttp.close(); // Clean up
256
+ }
257
+ ```
258
+
259
+ ---
260
+
261
+ ### Schema Management
262
+
263
+ #### `listSchemas(): Promise<SchemaDefinition[]>`
264
+
265
+ Lists all cached schemas (query patterns).
266
+
267
+ **Returns:** Array of schema definitions with metadata
268
+
269
+ **Example:**
270
+
271
+ ```typescript
272
+ const schemas = await nttp.listSchemas();
273
+ schemas.forEach(schema => {
274
+ console.log(`${schema.schema_id}: ${schema.intent_pattern}`);
275
+ console.log(` Used ${schema.use_count} times`);
276
+ console.log(` Example: ${schema.example_queries[0]}`);
277
+ });
278
+ ```
279
+
280
+ ---
281
+
282
+ #### `getSchema(schemaId: string): Promise<SchemaDefinition | null>`
283
+
284
+ Retrieves a specific cached schema by ID.
285
+
286
+ **Parameters:**
287
+
288
+ - `schemaId` (string): 16-character schema hash
289
+
290
+ **Returns:** Schema definition or null if not found
291
+
292
+ **Example:**
293
+
294
+ ```typescript
295
+ const schema = await nttp.getSchema('a1b2c3d4e5f6g7h8');
296
+ if (schema) {
297
+ console.log('SQL:', schema.generated_sql);
298
+ console.log('Used:', schema.use_count);
299
+ }
300
+ ```
301
+
302
+ ---
303
+
304
+ #### `deleteSchema(schemaId: string): Promise<void>`
305
+
306
+ Deletes a cached schema.
307
+
308
+ **Parameters:**
309
+
310
+ - `schemaId` (string): Schema to delete
311
+
312
+ **Example:**
313
+
314
+ ```typescript
315
+ await nttp.deleteSchema('a1b2c3d4e5f6g7h8');
316
+ ```
317
+
318
+ ---
319
+
320
+ #### `pinSchema(schemaId: string): Promise<void>`
321
+
322
+ Pins a schema to prevent it from being evicted from cache.
323
+
324
+ **Parameters:**
325
+
326
+ - `schemaId` (string): Schema to pin
327
+
328
+ **Example:**
329
+
330
+ ```typescript
331
+ // Pin frequently used query pattern
332
+ await nttp.pinSchema('a1b2c3d4e5f6g7h8');
333
+ ```
334
+
335
+ ---
336
+
337
+ #### `unpinSchema(schemaId: string): Promise<void>`
338
+
339
+ Unpins a previously pinned schema.
340
+
341
+ **Parameters:**
342
+
343
+ - `schemaId` (string): Schema to unpin
344
+
345
+ ---
346
+
347
+ #### `getCacheStats(): Promise<CacheStats>`
348
+
349
+ Gets cache statistics and performance metrics.
350
+
351
+ **Returns:**
352
+
353
+ ```typescript
354
+ interface CacheStats {
355
+ totalSchemas: number;
356
+ pinnedSchemas: number;
357
+ totalUseCount: number;
358
+ averageUseCount: number;
359
+ oldestSchema: Date;
360
+ newestSchema: Date;
361
+ }
362
+ ```
363
+
364
+ **Example:**
365
+
366
+ ```typescript
367
+ const stats = await nttp.getCacheStats();
368
+ console.log(`Total cached patterns: ${stats.totalSchemas}`);
369
+ console.log(`Average uses per pattern: ${stats.averageUseCount}`);
370
+ ```
371
+
372
+ ---
373
+
374
+ ### Database Inspection
375
+
376
+ #### `getTables(): Promise<string[]>`
377
+
378
+ Gets list of all tables in the database.
379
+
380
+ **Returns:** Array of table names
381
+
382
+ **Example:**
383
+
384
+ ```typescript
385
+ const tables = await nttp.getTables();
386
+ console.log('Available tables:', tables);
387
+ // ['users', 'products', 'orders', ...]
388
+ ```
389
+
390
+ ---
391
+
392
+ #### `getTableSchema(tableName: string): Promise<TableSchema>`
393
+
394
+ Gets the schema (columns, types, etc.) for a specific table.
395
+
396
+ **Parameters:**
397
+
398
+ - `tableName` (string): Name of table to inspect
399
+
400
+ **Returns:** Table schema with column definitions
401
+
402
+ **Example:**
403
+
404
+ ```typescript
405
+ const schema = await nttp.getTableSchema('users');
406
+ console.log('Columns:', schema.columns);
407
+ // [{ name: 'id', type: 'integer' }, { name: 'email', type: 'string' }, ...]
408
+ ```
409
+
410
+ ---
411
+
412
+ #### `getSchemaDescription(): string`
413
+
414
+ Gets a human-readable description of the database schema. This is what's sent to the LLM for context.
415
+
416
+ **Returns:** Formatted schema description string
417
+
418
+ **Example:**
419
+
420
+ ```typescript
421
+ const description = nttp.getSchemaDescription();
422
+ console.log(description);
423
+ // Tables:
424
+ // - users (id: integer, email: string, name: string, ...)
425
+ // - products (id: integer, name: string, price: decimal, ...)
426
+ ```
427
+
428
+ ---
429
+
430
+ ## Types
431
+
432
+ ### Intent
433
+
434
+ Structured representation of parsed natural language query.
435
+
436
+ ```typescript
437
+ interface Intent {
438
+ entity: string; // Table name
439
+ operation: OperationType; // 'list' | 'count' | 'aggregate' | 'filter'
440
+ filters: Record<string, any>; // Filter conditions
441
+ limit?: number | null; // Result limit
442
+ fields?: string[] | null; // Specific fields to select
443
+ sort?: string | null; // Sort specification (e.g., 'price:desc')
444
+ normalized_text: string; // Normalized representation for caching
445
+ }
446
+ ```
447
+
448
+ ---
449
+
450
+ ### SchemaDefinition
451
+
452
+ Cached query pattern.
453
+
454
+ ```typescript
455
+ interface SchemaDefinition {
456
+ schema_id: string; // 16-char hash
457
+ intent_pattern: string; // Normalized intent
458
+ generated_sql: string; // Cached SQL
459
+ sql_params: any[]; // SQL parameters
460
+ result_schema: Record<string, any>; // Result structure
461
+ use_count: number; // Times this pattern was used
462
+ created_at: Date; // When cached
463
+ last_used_at: Date; // Last access time
464
+ example_queries: string[]; // Example natural language queries
465
+ pinned: boolean; // Prevent eviction?
466
+ }
467
+ ```
468
+
469
+ ---
470
+
471
+ ## Errors
472
+
473
+ All NTTP errors include helpful suggestions for resolving issues.
474
+
475
+ ### IntentParseError
476
+
477
+ Thrown when the LLM cannot parse the natural language query.
478
+
479
+ ```typescript
480
+ try {
481
+ await nttp.query("ambiguous query");
482
+ } catch (error) {
483
+ if (error instanceof IntentParseError) {
484
+ console.error(error.message);
485
+ console.log('Suggestions:', error.suggestions);
486
+ }
487
+ }
488
+ ```
489
+
490
+ **Common causes:**
491
+ - Query references unknown tables/fields
492
+ - Query is too vague or ambiguous
493
+ - LLM API unavailable or quota exceeded
494
+
495
+ ---
496
+
497
+ ### SQLGenerationError
498
+
499
+ Thrown when SQL generation fails or violates safety rules.
500
+
501
+ ```typescript
502
+ try {
503
+ await nttp.query("complex query");
504
+ } catch (error) {
505
+ if (error instanceof SQLGenerationError) {
506
+ console.error(error.message);
507
+ console.log('Suggestions:', error.suggestions);
508
+ }
509
+ }
510
+ ```
511
+
512
+ **Common causes:**
513
+ - Complex query requires missing table relationships
514
+ - Generated SQL violates safety rules
515
+ - Schema description incomplete
516
+
517
+ ---
518
+
519
+ ### SQLExecutionError
520
+
521
+ Thrown when the database rejects the generated SQL.
522
+
523
+ ```typescript
524
+ try {
525
+ await nttp.query("show users");
526
+ } catch (error) {
527
+ if (error instanceof SQLExecutionError) {
528
+ console.error(error.message);
529
+ console.log('Generated SQL:', error.sql);
530
+ console.log('Suggestions:', error.suggestions);
531
+ }
532
+ }
533
+ ```
534
+
535
+ **Common causes:**
536
+ - Database connection issues
537
+ - Table/column doesn't exist (schema mismatch)
538
+ - Type mismatch in WHERE clause
539
+ - Insufficient permissions
540
+
541
+ ---
542
+
543
+ ### LLMError
544
+
545
+ Thrown when LLM API calls fail.
546
+
547
+ **Common causes:**
548
+ - Invalid or expired API key
549
+ - Rate limit or quota exceeded
550
+ - Network connectivity issues
551
+ - Provider service outage
552
+
553
+ ---
554
+
555
+ ### CacheError
556
+
557
+ Thrown when cache operations fail.
558
+
559
+ **Common causes:**
560
+ - Redis connection failed
561
+ - Redis authentication error
562
+ - Embedding API failure (L2 cache)
563
+ - Out of memory
564
+
565
+ ---
566
+
567
+ ## See Also
568
+
569
+ - [Configuration](./configuration.md) - Complete configuration reference
570
+ - [Examples](./examples.md) - Comprehensive usage examples
571
+ - [Troubleshooting](./troubleshooting.md) - Common issues and solutions