recursive-llm-ts 4.4.0 → 4.4.1

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/README.md CHANGED
@@ -15,6 +15,7 @@ TypeScript/JavaScript package for [Recursive Language Models (RLM)](https://gith
15
15
  🔍 **Structured Outputs** - Extract typed data with Zod schemas and parallel execution
16
16
  🧠 **Meta-Agent Mode** - Automatically optimize queries for better results
17
17
  📊 **Observability** - OpenTelemetry tracing, Langfuse integration, and debug logging
18
+ 📁 **File Storage** - Process local directories or S3/MinIO/LocalStack buckets as LLM context
18
19
 
19
20
  ## Installation
20
21
 
@@ -281,6 +282,123 @@ LANGFUSE_SECRET_KEY=sk-...
281
282
  LANGFUSE_HOST=https://cloud.langfuse.com
282
283
  ```
283
284
 
285
+ ### File Storage Context
286
+
287
+ Process files from local directories or S3-compatible storage as LLM context. Supports recursive directory traversal, filtering, and automatic context formatting.
288
+
289
+ #### Local Files
290
+
291
+ ```typescript
292
+ import { RLM } from 'recursive-llm-ts';
293
+
294
+ const rlm = new RLM('gpt-4o-mini', {
295
+ api_key: process.env.OPENAI_API_KEY
296
+ });
297
+
298
+ // Process all TypeScript files in a directory
299
+ const result = await rlm.completionFromFiles(
300
+ 'Summarize the architecture of this codebase',
301
+ {
302
+ type: 'local',
303
+ path: '/path/to/project/src',
304
+ extensions: ['.ts', '.tsx'],
305
+ excludePatterns: ['*.test.ts', '*.spec.ts'],
306
+ maxFileSize: 100_000, // Skip files over 100KB
307
+ }
308
+ );
309
+
310
+ console.log(result.result);
311
+ console.log(`Files processed: ${result.fileStorage?.files.length}`);
312
+ ```
313
+
314
+ #### S3 / Object Storage
315
+
316
+ Works with AWS S3, MinIO, LocalStack, DigitalOcean Spaces, and Backblaze B2.
317
+
318
+ ```typescript
319
+ // AWS S3 with explicit credentials
320
+ const result = await rlm.completionFromFiles(
321
+ 'What are the key findings in these reports?',
322
+ {
323
+ type: 's3',
324
+ path: 'my-bucket', // Bucket name
325
+ prefix: 'reports/2024/', // Folder prefix
326
+ extensions: ['.md', '.txt'],
327
+ credentials: {
328
+ accessKeyId: 'AKIA...',
329
+ secretAccessKey: '...',
330
+ },
331
+ region: 'us-west-2',
332
+ }
333
+ );
334
+
335
+ // S3 with environment variable credentials
336
+ // Uses AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN
337
+ const result2 = await rlm.completionFromFiles(
338
+ 'Summarize these documents',
339
+ { type: 's3', path: 'my-bucket', prefix: 'docs/' }
340
+ );
341
+
342
+ // MinIO / LocalStack
343
+ const result3 = await rlm.completionFromFiles(
344
+ 'Analyze the data',
345
+ {
346
+ type: 's3',
347
+ path: 'local-bucket',
348
+ endpoint: 'http://localhost:9000', // MinIO
349
+ credentials: { accessKeyId: 'minioadmin', secretAccessKey: 'minioadmin' },
350
+ }
351
+ );
352
+ ```
353
+
354
+ **Credential Resolution Order:**
355
+ 1. Explicit `credentials` in config
356
+ 2. Environment variables: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_SESSION_TOKEN`
357
+ 3. AWS SDK default credential chain (IAM roles, `~/.aws/credentials`, ECS task role, etc.)
358
+
359
+ #### Structured Extraction from Files
360
+
361
+ ```typescript
362
+ import { z } from 'zod';
363
+
364
+ const schema = z.object({
365
+ summary: z.string(),
366
+ mainTopics: z.array(z.string()),
367
+ sentiment: z.enum(['positive', 'negative', 'neutral']),
368
+ });
369
+
370
+ const result = await rlm.structuredCompletionFromFiles(
371
+ 'Extract a summary, main topics, and overall sentiment',
372
+ { type: 'local', path: './docs', extensions: ['.md'] },
373
+ schema
374
+ );
375
+
376
+ console.log(result.result.mainTopics); // string[]
377
+ ```
378
+
379
+ #### Preview Files Before Processing
380
+
381
+ ```typescript
382
+ import { FileContextBuilder } from 'recursive-llm-ts';
383
+
384
+ const builder = new FileContextBuilder({
385
+ type: 'local',
386
+ path: './src',
387
+ extensions: ['.ts'],
388
+ excludePatterns: ['node_modules/**'],
389
+ });
390
+
391
+ // List matching files without reading content
392
+ const files = await builder.listMatchingFiles();
393
+ console.log('Would process:', files);
394
+
395
+ // Build full context
396
+ const ctx = await builder.buildContext();
397
+ console.log(`Total size: ${ctx.totalSize} bytes`);
398
+ console.log(`Files included: ${ctx.files.length}`);
399
+ console.log(`Files skipped: ${ctx.skipped.length}`);
400
+ ```
401
+
284
402
  ## API
285
403
 
286
404
  ### `RLM`
@@ -330,6 +448,21 @@ const result = await rlm.structuredCompletion('Analyze', doc, schema);
330
448
  // result.result is typed as { score: number, summary: string }
331
449
  ```
332
450
 
451
+ #### `completionFromFiles(query: string, fileConfig: FileStorageConfig): Promise<RLMResult & { fileStorage?: FileStorageResult }>`
452
+
453
+ Process a query using files from local or S3 storage as context.
454
+
455
+ **Parameters:**
456
+ - `query`: The question or task to perform
457
+ - `fileConfig`: File storage configuration (local path or S3 bucket)
458
+
459
+ **Returns:**
460
+ - Result with `fileStorage` metadata (files included, skipped, total size)
461
+
462
+ #### `structuredCompletionFromFiles<T>(query: string, fileConfig: FileStorageConfig, schema: ZodSchema<T>, options?): Promise<StructuredRLMResult<T> & { fileStorage?: FileStorageResult }>`
463
+
464
+ Extract structured data from file-based context.
465
+
333
466
  #### `cleanup(): Promise<void>`
334
467
 
335
468
  Clean up the bridge and free resources.
@@ -423,6 +556,33 @@ interface TraceEvent {
423
556
  trace_id?: string;
424
557
  span_id?: string;
425
558
  }
559
+
560
+ interface FileStorageConfig {
561
+ type: 'local' | 's3'; // Storage provider type
562
+ path: string; // Local directory path or S3 bucket name
563
+ prefix?: string; // S3 key prefix (folder path)
564
+ region?: string; // AWS region (default: AWS_REGION env or 'us-east-1')
565
+ credentials?: { // S3 explicit credentials (optional)
566
+ accessKeyId: string;
567
+ secretAccessKey: string;
568
+ sessionToken?: string;
569
+ };
570
+ endpoint?: string; // Custom S3 endpoint (MinIO, LocalStack, etc.)
571
+ forcePathStyle?: boolean; // Force path-style S3 URLs (auto-enabled with endpoint)
572
+ extensions?: string[]; // File extensions to include (e.g., ['.ts', '.md'])
573
+ includePatterns?: string[]; // Glob patterns to include
574
+ excludePatterns?: string[]; // Glob patterns to exclude
575
+ maxFileSize?: number; // Max individual file size in bytes (default: 1MB)
576
+ maxTotalSize?: number; // Max total context size in bytes (default: 10MB)
577
+ maxFiles?: number; // Max number of files (default: 1000)
578
+ }
579
+
580
+ interface FileStorageResult {
581
+ context: string; // Built context string with file contents
582
+ files: Array<{ relativePath: string; size: number }>;
583
+ totalSize: number;
584
+ skipped: Array<{ relativePath: string; reason: string }>;
585
+ }
426
586
  ```
427
587
 
428
588
  ## Environment Variables
@@ -441,6 +601,17 @@ const rlm = new RLM('gpt-4o-mini', {
441
601
  });
442
602
  ```
443
603
 
604
+ ### S3 File Storage
605
+
606
+ When using S3 file storage without explicit credentials, these environment variables are checked:
607
+
608
+ ```bash
609
+ export AWS_ACCESS_KEY_ID='your-access-key'
610
+ export AWS_SECRET_ACCESS_KEY='your-secret-key'
611
+ export AWS_SESSION_TOKEN='optional-session-token'
612
+ export AWS_REGION='us-east-1'
613
+ ```
614
+
444
615
  ## Custom Providers
445
616
 
446
617
  The Go binary uses an **OpenAI-compatible chat completion API** and works seamlessly with
package/bin/rlm-go CHANGED
Binary file
@@ -49,6 +49,51 @@ export interface RLMConfig {
49
49
  debug?: boolean;
50
50
  [key: string]: any;
51
51
  }
52
+ export interface FileStorageConfig {
53
+ /** Storage type: 'local' or 's3' */
54
+ type: 'local' | 's3';
55
+ /** For local: root directory path. For S3: bucket name */
56
+ path: string;
57
+ /** For S3: the prefix (folder path) within the bucket */
58
+ prefix?: string;
59
+ /** For S3: AWS region (falls back to AWS_REGION env var, then 'us-east-1') */
60
+ region?: string;
61
+ /**
62
+ * For S3: explicit credentials.
63
+ * Resolution order:
64
+ * 1. This field (explicit credentials)
65
+ * 2. Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN
66
+ * 3. AWS SDK default credential chain (IAM role, ~/.aws/credentials, ECS task role, etc.)
67
+ */
68
+ credentials?: {
69
+ accessKeyId: string;
70
+ secretAccessKey: string;
71
+ sessionToken?: string;
72
+ };
73
+ /**
74
+ * For S3: custom endpoint URL.
75
+ * Use for S3-compatible services: MinIO, LocalStack, DigitalOcean Spaces, Backblaze B2.
76
+ * When set, forcePathStyle is automatically enabled.
77
+ */
78
+ endpoint?: string;
79
+ /**
80
+ * For S3: force path-style addressing (bucket in path, not subdomain).
81
+ * Automatically true when endpoint is set.
82
+ */
83
+ forcePathStyle?: boolean;
84
+ /** Glob patterns to include (e.g. ['*.ts', '*.md']) */
85
+ includePatterns?: string[];
86
+ /** Glob patterns to exclude (e.g. ['node_modules/**']) */
87
+ excludePatterns?: string[];
88
+ /** Maximum file size in bytes to include (default: 1MB) */
89
+ maxFileSize?: number;
90
+ /** Maximum total context size in bytes (default: 10MB) */
91
+ maxTotalSize?: number;
92
+ /** Maximum number of files to include (default: 1000) */
93
+ maxFiles?: number;
94
+ /** File extensions to include (e.g. ['.ts', '.md', '.txt']) */
95
+ extensions?: string[];
96
+ }
52
97
  export interface PythonBridge {
53
98
  completion(model: string, query: string, context: string, rlmConfig: RLMConfig): Promise<RLMResult>;
54
99
  cleanup(): Promise<void>;
@@ -0,0 +1,122 @@
1
+ import { FileStorageConfig } from './bridge-interface';
2
+ /**
3
+ * Custom error class for S3 storage operations.
4
+ * Provides actionable error messages for common failure modes.
5
+ */
6
+ export declare class S3StorageError extends Error {
7
+ readonly code: string;
8
+ readonly bucket: string;
9
+ readonly key?: string;
10
+ readonly originalError?: Error;
11
+ constructor(opts: {
12
+ message: string;
13
+ code: string;
14
+ bucket: string;
15
+ key?: string;
16
+ originalError?: Error;
17
+ });
18
+ }
19
+ export { FileStorageConfig } from './bridge-interface';
20
+ export interface FileEntry {
21
+ /** Relative path from the root of the storage source */
22
+ relativePath: string;
23
+ /** File content as a string */
24
+ content: string;
25
+ /** Size in bytes */
26
+ size: number;
27
+ }
28
+ export interface FileStorageResult {
29
+ /** The built context string containing all file contents */
30
+ context: string;
31
+ /** List of files that were included */
32
+ files: Array<{
33
+ relativePath: string;
34
+ size: number;
35
+ }>;
36
+ /** Total size of all file contents */
37
+ totalSize: number;
38
+ /** Files that were skipped and why */
39
+ skipped: Array<{
40
+ relativePath: string;
41
+ reason: string;
42
+ }>;
43
+ }
44
+ export interface FileStorageProvider {
45
+ listFiles(): Promise<string[]>;
46
+ readFile(relativePath: string): Promise<string>;
47
+ getFileSize(relativePath: string): Promise<number>;
48
+ }
49
+ export declare class LocalFileStorage implements FileStorageProvider {
50
+ private rootPath;
51
+ constructor(rootPath: string);
52
+ listFiles(): Promise<string[]>;
53
+ private walkDir;
54
+ readFile(relativePath: string): Promise<string>;
55
+ getFileSize(relativePath: string): Promise<number>;
56
+ }
57
+ /**
58
+ * S3FileStorage uses the AWS SDK v3 via dynamic import.
59
+ * If @aws-sdk/client-s3 is not installed, it throws a clear error.
60
+ *
61
+ * Supports:
62
+ * - AWS S3
63
+ * - MinIO (set endpoint to MinIO URL)
64
+ * - LocalStack (set endpoint to LocalStack URL, typically http://localhost:4566)
65
+ * - DigitalOcean Spaces, Backblaze B2, and other S3-compatible services
66
+ *
67
+ * Credential resolution order:
68
+ * 1. Explicit credentials in FileStorageConfig.credentials
69
+ * 2. Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN
70
+ * 3. AWS SDK default credential chain (IAM role, ~/.aws/credentials, ECS task role, etc.)
71
+ */
72
+ export declare class S3FileStorage implements FileStorageProvider {
73
+ private bucket;
74
+ private prefix;
75
+ private region;
76
+ private credentials?;
77
+ private endpoint?;
78
+ private forcePathStyle;
79
+ private s3Client;
80
+ constructor(config: FileStorageConfig);
81
+ /**
82
+ * Returns the credential source being used for debugging/logging.
83
+ */
84
+ getCredentialSource(): string;
85
+ private getClient;
86
+ private buildKey;
87
+ listFiles(): Promise<string[]>;
88
+ readFile(relativePath: string): Promise<string>;
89
+ getFileSize(relativePath: string): Promise<number>;
90
+ }
91
+ /**
92
+ * FileContextBuilder reads files from a storage provider, applies filters,
93
+ * and builds a structured context string for LLM consumption.
94
+ */
95
+ export declare class FileContextBuilder {
96
+ private provider;
97
+ private config;
98
+ constructor(config: FileStorageConfig);
99
+ private createProvider;
100
+ /**
101
+ * Build a structured context string from all matching files.
102
+ * Files are formatted with clear delimiters so the LLM can reference them.
103
+ */
104
+ buildContext(): Promise<FileStorageResult>;
105
+ /**
106
+ * Build a file tree overview for the LLM to understand the folder structure.
107
+ */
108
+ private buildFileTree;
109
+ /**
110
+ * Format a single file's content with clear delimiters.
111
+ */
112
+ private formatFileBlock;
113
+ /**
114
+ * Get just the list of files without reading content.
115
+ * Useful for previewing what would be included.
116
+ */
117
+ listMatchingFiles(): Promise<string[]>;
118
+ }
119
+ /**
120
+ * Convenience function to build context from a file storage config.
121
+ */
122
+ export declare function buildFileContext(config: FileStorageConfig): Promise<FileStorageResult>;