lazlo-ai 1.0.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 (126) hide show
  1. package/.env.example +9 -0
  2. package/README.md +278 -0
  3. package/dist/cache/semantic.d.ts +39 -0
  4. package/dist/cache/semantic.d.ts.map +1 -0
  5. package/dist/cache/semantic.js +134 -0
  6. package/dist/cache/semantic.js.map +1 -0
  7. package/dist/chains/llmchain.d.ts +65 -0
  8. package/dist/chains/llmchain.d.ts.map +1 -0
  9. package/dist/chains/llmchain.js +137 -0
  10. package/dist/chains/llmchain.js.map +1 -0
  11. package/dist/chains/rag.d.ts +23 -0
  12. package/dist/chains/rag.d.ts.map +1 -0
  13. package/dist/chains/rag.js +47 -0
  14. package/dist/chains/rag.js.map +1 -0
  15. package/dist/core/types.d.ts +130 -0
  16. package/dist/core/types.d.ts.map +1 -0
  17. package/dist/core/types.js +8 -0
  18. package/dist/core/types.js.map +1 -0
  19. package/dist/document_loaders/index.d.ts +61 -0
  20. package/dist/document_loaders/index.d.ts.map +1 -0
  21. package/dist/document_loaders/index.js +183 -0
  22. package/dist/document_loaders/index.js.map +1 -0
  23. package/dist/embeddings/google.d.ts +43 -0
  24. package/dist/embeddings/google.d.ts.map +1 -0
  25. package/dist/embeddings/google.js +90 -0
  26. package/dist/embeddings/google.js.map +1 -0
  27. package/dist/embeddings/local.d.ts +64 -0
  28. package/dist/embeddings/local.d.ts.map +1 -0
  29. package/dist/embeddings/local.js +95 -0
  30. package/dist/embeddings/local.js.map +1 -0
  31. package/dist/evals/judge.d.ts +22 -0
  32. package/dist/evals/judge.d.ts.map +1 -0
  33. package/dist/evals/judge.js +77 -0
  34. package/dist/evals/judge.js.map +1 -0
  35. package/dist/index.d.ts +28 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +84 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/memory/buffer.d.ts +64 -0
  40. package/dist/memory/buffer.d.ts.map +1 -0
  41. package/dist/memory/buffer.js +168 -0
  42. package/dist/memory/buffer.js.map +1 -0
  43. package/dist/parsers/output.d.ts +64 -0
  44. package/dist/parsers/output.d.ts.map +1 -0
  45. package/dist/parsers/output.js +148 -0
  46. package/dist/parsers/output.js.map +1 -0
  47. package/dist/prompts/registry.d.ts +65 -0
  48. package/dist/prompts/registry.d.ts.map +1 -0
  49. package/dist/prompts/registry.js +170 -0
  50. package/dist/prompts/registry.js.map +1 -0
  51. package/dist/providers/ollama.d.ts +30 -0
  52. package/dist/providers/ollama.d.ts.map +1 -0
  53. package/dist/providers/ollama.js +104 -0
  54. package/dist/providers/ollama.js.map +1 -0
  55. package/dist/providers/openai.d.ts +46 -0
  56. package/dist/providers/openai.d.ts.map +1 -0
  57. package/dist/providers/openai.js +228 -0
  58. package/dist/providers/openai.js.map +1 -0
  59. package/dist/retrievers/index.d.ts +71 -0
  60. package/dist/retrievers/index.d.ts.map +1 -0
  61. package/dist/retrievers/index.js +130 -0
  62. package/dist/retrievers/index.js.map +1 -0
  63. package/dist/router/smartrouter.d.ts +36 -0
  64. package/dist/router/smartrouter.d.ts.map +1 -0
  65. package/dist/router/smartrouter.js +132 -0
  66. package/dist/router/smartrouter.js.map +1 -0
  67. package/dist/text_splitters/index.d.ts +28 -0
  68. package/dist/text_splitters/index.d.ts.map +1 -0
  69. package/dist/text_splitters/index.js +109 -0
  70. package/dist/text_splitters/index.js.map +1 -0
  71. package/dist/tools/decorator.d.ts +26 -0
  72. package/dist/tools/decorator.d.ts.map +1 -0
  73. package/dist/tools/decorator.js +102 -0
  74. package/dist/tools/decorator.js.map +1 -0
  75. package/dist/tools/index.d.ts +7 -0
  76. package/dist/tools/index.d.ts.map +1 -0
  77. package/dist/tools/index.js +6 -0
  78. package/dist/tools/index.js.map +1 -0
  79. package/dist/tools/keiro.d.ts +20 -0
  80. package/dist/tools/keiro.d.ts.map +1 -0
  81. package/dist/tools/keiro.js +67 -0
  82. package/dist/tools/keiro.js.map +1 -0
  83. package/dist/tracing/tracer.d.ts +56 -0
  84. package/dist/tracing/tracer.d.ts.map +1 -0
  85. package/dist/tracing/tracer.js +125 -0
  86. package/dist/tracing/tracer.js.map +1 -0
  87. package/dist/utils/logger.d.ts +25 -0
  88. package/dist/utils/logger.d.ts.map +1 -0
  89. package/dist/utils/logger.js +50 -0
  90. package/dist/utils/logger.js.map +1 -0
  91. package/dist/utils/pricing.d.ts +31 -0
  92. package/dist/utils/pricing.d.ts.map +1 -0
  93. package/dist/utils/pricing.js +108 -0
  94. package/dist/utils/pricing.js.map +1 -0
  95. package/dist/vectorstores/index.d.ts +62 -0
  96. package/dist/vectorstores/index.d.ts.map +1 -0
  97. package/dist/vectorstores/index.js +244 -0
  98. package/dist/vectorstores/index.js.map +1 -0
  99. package/package.json +48 -0
  100. package/src/cache/semantic.ts +175 -0
  101. package/src/chains/llmchain.ts +194 -0
  102. package/src/chains/rag.ts +65 -0
  103. package/src/core/types.ts +178 -0
  104. package/src/document_loaders/index.ts +223 -0
  105. package/src/embeddings/google.ts +119 -0
  106. package/src/embeddings/local.ts +118 -0
  107. package/src/evals/judge.ts +99 -0
  108. package/src/index.ts +121 -0
  109. package/src/memory/buffer.ts +222 -0
  110. package/src/parsers/output.ts +195 -0
  111. package/src/prompts/registry.ts +205 -0
  112. package/src/providers/ollama.ts +151 -0
  113. package/src/providers/openai.ts +320 -0
  114. package/src/retrievers/index.ts +182 -0
  115. package/src/router/smartrouter.ts +172 -0
  116. package/src/text_splitters/index.ts +145 -0
  117. package/src/tools/decorator.ts +145 -0
  118. package/src/tools/index.ts +7 -0
  119. package/src/tools/keiro.ts +92 -0
  120. package/src/tracing/tracer.ts +178 -0
  121. package/src/utils/logger.ts +62 -0
  122. package/src/utils/pricing.ts +133 -0
  123. package/src/vectorstores/index.ts +338 -0
  124. package/test-full.mjs +552 -0
  125. package/test.mjs +74 -0
  126. package/tsconfig.json +30 -0
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Document Loaders
3
+ *
4
+ * Load documents from various sources: PDF, text, CSV, JSON, HTML
5
+ */
6
+
7
+ import { readFile } from 'fs/promises';
8
+ import { readFileSync } from 'fs';
9
+ import { join, extname } from 'path';
10
+
11
+ export interface Document {
12
+ pageContent: string;
13
+ metadata: Record<string, unknown>;
14
+ }
15
+
16
+ export interface BaseLoader {
17
+ load(): Promise<Document[]>;
18
+ loadSync(): Document[];
19
+ }
20
+
21
+ /**
22
+ * Text File Loader
23
+ */
24
+ export class TextLoader implements BaseLoader {
25
+ constructor(private filePath: string) {}
26
+
27
+ async load(): Promise<Document[]> {
28
+ const content = await readFile(this.filePath, 'utf-8');
29
+ return this.parseContent(content);
30
+ }
31
+
32
+ loadSync(): Document[] {
33
+ const content = readFileSync(this.filePath, 'utf-8');
34
+ return this.parseContent(content);
35
+ }
36
+
37
+ private parseContent(content: string): Document[] {
38
+ return [{
39
+ pageContent: content,
40
+ metadata: {
41
+ source: this.filePath,
42
+ type: 'text',
43
+ },
44
+ }];
45
+ }
46
+ }
47
+
48
+ /**
49
+ * CSV File Loader
50
+ */
51
+ export class CSVLoader implements BaseLoader {
52
+ constructor(
53
+ private filePath: string,
54
+ private options: {
55
+ delimiter?: string;
56
+ headers?: string[];
57
+ skipEmptyLines?: boolean;
58
+ } = {}
59
+ ) {}
60
+
61
+ async load(): Promise<Document[]> {
62
+ const content = await readFile(this.filePath, 'utf-8');
63
+ return this.parseCSV(content);
64
+ }
65
+
66
+ loadSync(): Document[] {
67
+ const content = readFileSync(this.filePath, 'utf-8');
68
+ return this.parseCSV(content);
69
+ }
70
+
71
+ private parseCSV(content: string): Document[] {
72
+ const delimiter = this.options.delimiter || ',';
73
+ const lines = content.split('\n').filter(line => line.trim());
74
+
75
+ if (lines.length === 0) return [];
76
+
77
+ const headers = this.options.headers || this.parseLine(lines[0], delimiter);
78
+ const documents: Document[] = [];
79
+
80
+ const startIndex = this.options.headers ? 0 : 1;
81
+
82
+ for (let i = startIndex; i < lines.length; i++) {
83
+ const values = this.parseLine(lines[i], delimiter);
84
+ if (this.options.skipEmptyLines && values.every(v => !v.trim())) continue;
85
+
86
+ const obj: Record<string, string> = {};
87
+ headers.forEach((header, idx) => {
88
+ obj[header.trim()] = values[idx] || '';
89
+ });
90
+
91
+ documents.push({
92
+ pageContent: JSON.stringify(obj),
93
+ metadata: {
94
+ source: this.filePath,
95
+ type: 'csv',
96
+ row: i - startIndex + 1,
97
+ },
98
+ });
99
+ }
100
+
101
+ return documents;
102
+ }
103
+
104
+ private parseLine(line: string, delimiter: string): string[] {
105
+ const result: string[] = [];
106
+ let current = '';
107
+ let inQuotes = false;
108
+
109
+ for (const char of line) {
110
+ if (char === '"') {
111
+ inQuotes = !inQuotes;
112
+ } else if (char === delimiter && !inQuotes) {
113
+ result.push(current);
114
+ current = '';
115
+ } else {
116
+ current += char;
117
+ }
118
+ }
119
+ result.push(current);
120
+ return result;
121
+ }
122
+ }
123
+
124
+ /**
125
+ * JSON File Loader
126
+ */
127
+ export class JSONLoader implements BaseLoader {
128
+ constructor(
129
+ private filePath: string,
130
+ private options: {
131
+ key?: string; // If specified, extract array items from this key
132
+ } = {}
133
+ ) {}
134
+
135
+ async load(): Promise<Document[]> {
136
+ const content = await readFile(this.filePath, 'utf-8');
137
+ return this.parseJSON(content);
138
+ }
139
+
140
+ loadSync(): Document[] {
141
+ const content = readFileSync(this.filePath, 'utf-8');
142
+ return this.parseJSON(content);
143
+ }
144
+
145
+ private parseJSON(content: string): Document[] {
146
+ const data = JSON.parse(content);
147
+
148
+ if (this.options.key) {
149
+ const array = data[this.options.key];
150
+ if (Array.isArray(array)) {
151
+ return array.map((item, idx) => ({
152
+ pageContent: typeof item === 'string' ? item : JSON.stringify(item),
153
+ metadata: {
154
+ source: this.filePath,
155
+ type: 'json',
156
+ key: this.options.key,
157
+ index: idx,
158
+ },
159
+ }));
160
+ }
161
+ }
162
+
163
+ if (Array.isArray(data)) {
164
+ return data.map((item, idx) => ({
165
+ pageContent: typeof item === 'string' ? item : JSON.stringify(item),
166
+ metadata: {
167
+ source: this.filePath,
168
+ type: 'json',
169
+ index: idx,
170
+ },
171
+ }));
172
+ }
173
+
174
+ return [{
175
+ pageContent: JSON.stringify(data),
176
+ metadata: {
177
+ source: this.filePath,
178
+ type: 'json',
179
+ },
180
+ }];
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Auto-detect file type and load
186
+ */
187
+ export async function loadDocument(filePath: string, options?: any): Promise<Document[]> {
188
+ const ext = extname(filePath).toLowerCase();
189
+
190
+ switch (ext) {
191
+ case '.txt':
192
+ case '.md':
193
+ case '.text':
194
+ return new TextLoader(filePath).load();
195
+
196
+ case '.csv':
197
+ return new CSVLoader(filePath, options?.csv).load();
198
+
199
+ case '.json':
200
+ return new JSONLoader(filePath, options?.json).load();
201
+
202
+ default:
203
+ // Default to text loader
204
+ return new TextLoader(filePath).load();
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Load multiple files
210
+ */
211
+ export async function loadDocuments(
212
+ filePaths: string[],
213
+ options?: any
214
+ ): Promise<Document[]> {
215
+ const documents: Document[] = [];
216
+
217
+ for (const filePath of filePaths) {
218
+ const docs = await loadDocument(filePath, options);
219
+ documents.push(...docs);
220
+ }
221
+
222
+ return documents;
223
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Google Embeddings
3
+ *
4
+ * Google AI Gemini embeddings for text vectorization
5
+ */
6
+
7
+ import axios from 'axios';
8
+ import { logger } from '../utils/logger.js';
9
+
10
+ export interface GoogleEmbeddingsOptions {
11
+ apiKey?: string;
12
+ model?: string;
13
+ taskType?: 'RETRIEVAL_QUERY' | 'RETRIEVAL_DOCUMENT' | 'SEMANTIC_SIMILARITY' | 'CLASSIFICATION' | 'CLUSTERING';
14
+ title?: string;
15
+ }
16
+
17
+ export interface EmbeddingResponse {
18
+ embedding: {
19
+ values: number[];
20
+ };
21
+ }
22
+
23
+ /**
24
+ * Google Embeddings
25
+ *
26
+ * Uses Google's Generative Language API for embeddings
27
+ */
28
+ export class GoogleEmbeddings {
29
+ readonly model: string;
30
+ readonly taskType: string;
31
+ readonly title?: string;
32
+ private apiKey: string;
33
+ private apiUrl = 'https://generativelanguage.googleapis.com/v1beta';
34
+
35
+ constructor(options: GoogleEmbeddingsOptions = {}) {
36
+ this.apiKey = options.apiKey || (typeof process !== 'undefined' ? (process as any).env?.GEMINI_API_KEY : '') || '';
37
+ this.model = options.model || 'text-embedding-004';
38
+ this.taskType = options.taskType || 'RETRIEVAL_DOCUMENT';
39
+ this.title = options.title;
40
+
41
+ if (!this.apiKey) {
42
+ logger.warn('[GoogleEmbeddings] No API key provided. Set GEMINI_API_KEY env var or pass apiKey option.');
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Embed a single text
48
+ */
49
+ async embedQuery(text: string): Promise<number[]> {
50
+ return this.embed([text]).then(res => res[0]);
51
+ }
52
+
53
+ /**
54
+ * Embed multiple texts
55
+ */
56
+ async embedDocuments(texts: string[]): Promise<number[][]> {
57
+ return this.embed(texts);
58
+ }
59
+
60
+ private async embed(texts: string[]): Promise<number[][]> {
61
+ if (!this.apiKey) {
62
+ throw new Error('Google API key required. Set GEMINI_API_KEY or pass apiKey option.');
63
+ }
64
+
65
+ const embeddings: number[][] = [];
66
+
67
+ // Google API allows up to 100 inputs per request
68
+ const batchSize = 100;
69
+
70
+ for (let i = 0; i < texts.length; i += batchSize) {
71
+ const batch = texts.slice(i, i + batchSize);
72
+
73
+ try {
74
+ const requests = batch.map((content, idx) => ({
75
+ model: `models/${this.model}`,
76
+ content: { role: 'user', parts: [{ text: content }] },
77
+ taskType: this.taskType,
78
+ title: this.title,
79
+ }));
80
+
81
+ const response = await axios.post(
82
+ `${this.apiUrl}/embedContent:batchEmbedContents?key=${this.apiKey}`,
83
+ { requests },
84
+ {
85
+ headers: { 'Content-Type': 'application/json' },
86
+ timeout: 60000,
87
+ }
88
+ );
89
+
90
+ const results = response.data.embeddings || [];
91
+ for (let j = 0; j < results.length; j++) {
92
+ const result = results[j];
93
+ if (result.embedding?.values) {
94
+ embeddings.push(result.embedding.values);
95
+ } else {
96
+ // Fallback: generate random embedding
97
+ logger.warn(`[GoogleEmbeddings] Empty embedding for batch ${Math.floor(i / batchSize)}, index ${j}`);
98
+ embeddings.push(new Array(768).fill(0));
99
+ }
100
+ }
101
+ } catch (error: any) {
102
+ logger.error(`[GoogleEmbeddings] Error embedding batch: ${error.message}`);
103
+ // Return zero embeddings on error
104
+ for (let j = 0; j < batch.length; j++) {
105
+ embeddings.push(new Array(768).fill(0));
106
+ }
107
+ }
108
+ }
109
+
110
+ return embeddings;
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Factory function
116
+ */
117
+ export function createGoogleEmbeddings(options?: GoogleEmbeddingsOptions): GoogleEmbeddings {
118
+ return new GoogleEmbeddings(options);
119
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Local Embeddings
3
+ *
4
+ * Zero-cost, completely offline embedding generation
5
+ * Uses a simple hash-based approach for demonstration
6
+ * For production, use transformers.js or ONNX runtime
7
+ */
8
+
9
+ import { logger } from '../utils/logger.js';
10
+
11
+ /**
12
+ * Local Embeddings
13
+ *
14
+ * Generates embeddings locally without API calls.
15
+ * Uses a deterministic hash-based approach for consistent results.
16
+ * For production use, integrate with transformers.js or ONNX runtime.
17
+ */
18
+ export class LocalEmbeddings {
19
+ readonly dimensions: number;
20
+ private modelName: string;
21
+
22
+ constructor(options: { dimensions?: number; modelName?: string } = {}) {
23
+ this.dimensions = options.dimensions || 384;
24
+ this.modelName = options.modelName || 'local-hash';
25
+ logger.info(`[LocalEmbeddings] Initialized with ${this.dimensions} dimensions`);
26
+ }
27
+
28
+ /**
29
+ * Generate embedding using a simple hash-based approach
30
+ * This is NOT suitable for production semantic search
31
+ * but provides consistent results for testing
32
+ */
33
+ private generateHashEmbedding(text: string): number[] {
34
+ const embedding = new Array(this.dimensions).fill(0);
35
+
36
+ // Simple hash to generate consistent embedding
37
+ for (let i = 0; i < text.length; i++) {
38
+ const char = text.charCodeAt(i);
39
+ const idx1 = i % this.dimensions;
40
+ const idx2 = (i * 31 + char) % this.dimensions;
41
+
42
+ embedding[idx1] += char / text.length;
43
+ embedding[idx2] += char / text.length;
44
+ }
45
+
46
+ // Normalize
47
+ const magnitude = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
48
+ if (magnitude > 0) {
49
+ for (let i = 0; i < embedding.length; i++) {
50
+ embedding[i] /= magnitude;
51
+ }
52
+ }
53
+
54
+ return embedding;
55
+ }
56
+
57
+ /**
58
+ * Embed a single text
59
+ */
60
+ async embedQuery(text: string): Promise<number[]> {
61
+ return this.generateHashEmbedding(text);
62
+ }
63
+
64
+ /**
65
+ * Embed multiple texts
66
+ */
67
+ async embedDocuments(texts: string[]): Promise<number[][]> {
68
+ return texts.map(text => this.generateHashEmbedding(text));
69
+ }
70
+
71
+ /**
72
+ * Batch embed
73
+ */
74
+ async embed(texts: string[]): Promise<number[][]> {
75
+ return this.embedDocuments(texts);
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Factory function
81
+ */
82
+ export function createLocalEmbeddings(options?: {
83
+ dimensions?: number;
84
+ modelName?: string;
85
+ }): LocalEmbeddings {
86
+ return new LocalEmbeddings(options);
87
+ }
88
+
89
+ /**
90
+ * Mock HuggingFace Embeddings (for compatibility)
91
+ * In production, use @xenova/transformers
92
+ */
93
+ export class HuggingFaceEmbeddings {
94
+ readonly model: string;
95
+ readonly device: string;
96
+ readonly normalize: boolean;
97
+
98
+ constructor(options: {
99
+ model?: string;
100
+ device?: string;
101
+ normalize?: boolean;
102
+ } = {}) {
103
+ this.model = options.model || 'sentence-transformers/all-MiniLM-L6-v2';
104
+ this.device = options.device || 'cpu';
105
+ this.normalize = options.normalize !== false;
106
+
107
+ logger.info(`[HuggingFaceEmbeddings] Initialized (mock). For real embeddings, install @xenova/transformers`);
108
+ }
109
+
110
+ async embedQuery(text: string): Promise<number[]> {
111
+ // Mock implementation
112
+ return new LocalEmbeddings().embedQuery(text);
113
+ }
114
+
115
+ async embedDocuments(texts: string[]): Promise<number[][]> {
116
+ return new LocalEmbeddings().embedDocuments(texts);
117
+ }
118
+ }
@@ -0,0 +1,99 @@
1
+ /**
2
+ * LLMJudge - Evaluate LLM responses
3
+ */
4
+
5
+ import { BaseChatModel, Message } from '../core/types.js';
6
+ import { logger } from '../utils/logger.js';
7
+
8
+ // ============================================================================
9
+ // Evaluation Criteria
10
+ // ============================================================================
11
+
12
+ export enum EvalCriteria {
13
+ FAITHFULNESS = 'faithfulness',
14
+ RELEVANCE = 'relevance',
15
+ TOXICITY = 'toxicity',
16
+ COHERENCE = 'coherence',
17
+ ACCURACY = 'accuracy',
18
+ }
19
+
20
+ export interface EvalResult {
21
+ score: number;
22
+ explanation: string;
23
+ passed: boolean;
24
+ }
25
+
26
+ // ============================================================================
27
+ // LLM Judge
28
+ // ============================================================================
29
+
30
+ const EVAL_PROMPT = `You are an impartial, strict evaluator. Your job is to grade the Assistant's response
31
+ based on the following criteria: {criteria}.
32
+
33
+ Question asked by User:
34
+ "{question}"
35
+
36
+ Context provided to Assistant (if any):
37
+ "{context}"
38
+
39
+ Assistant's Response:
40
+ "{response}"
41
+
42
+ Evaluate the response. Output strictly in the following JSON schema:
43
+ {{
44
+ "score": <int from 1 to 10>,
45
+ "explanation": "<brief reason for the score>",
46
+ "passed": <boolean true if score >= 7 else false>
47
+ }}
48
+ `;
49
+
50
+ export class LLMJudge {
51
+ private judgeLLM: BaseChatModel;
52
+
53
+ constructor(judgeLLM: BaseChatModel) {
54
+ this.judgeLLM = judgeLLM;
55
+ logger.info('LLMJudge ready. Ready to evaluate responses.');
56
+ }
57
+
58
+ async evaluate(
59
+ question: string,
60
+ response: string,
61
+ criteria: EvalCriteria,
62
+ context: string = ''
63
+ ): Promise<EvalResult> {
64
+ const prompt = EVAL_PROMPT
65
+ .replace('{criteria}', criteria as string)
66
+ .replace('{question}', question)
67
+ .replace('{context}', context)
68
+ .replace('{response}', response);
69
+
70
+ const messages: Message[] = [
71
+ { role: 'system', content: 'You are a JSON grading API.' },
72
+ { role: 'user', content: prompt },
73
+ ];
74
+
75
+ try {
76
+ const result = await this.judgeLLM.invoke(messages, {
77
+ responseFormat: { type: 'json_object' }
78
+ });
79
+
80
+ const content = result.content.trim();
81
+ const parsed = JSON.parse(content);
82
+
83
+ logger.debug(`[Judge] Score: ${parsed.score}/10 - Passed: ${parsed.passed}`);
84
+
85
+ return {
86
+ score: parsed.score ?? 0,
87
+ explanation: parsed.explanation ?? '',
88
+ passed: parsed.passed ?? false,
89
+ };
90
+ } catch (error) {
91
+ logger.error(`Evaluation failed: ${error}`);
92
+ return {
93
+ score: 0,
94
+ explanation: String(error),
95
+ passed: false,
96
+ };
97
+ }
98
+ }
99
+ }
package/src/index.ts ADDED
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Lazlo - The Anti-Framework for JavaScript/TypeScript
3
+ *
4
+ * A production-grade AI framework that prioritizes performance, transparency, and simplicity.
5
+ */
6
+
7
+ // ============================================================================
8
+ // Core Types
9
+ // ============================================================================
10
+
11
+ export * from './core/types.js';
12
+
13
+ // ============================================================================
14
+ // Providers
15
+ // ============================================================================
16
+
17
+ export { OpenAI, createOpenAI } from './providers/openai.js';
18
+ export { Ollama, createOllama } from './providers/ollama.js';
19
+
20
+ // ============================================================================
21
+ // Chains
22
+ // ============================================================================
23
+
24
+ export { LLMChain, SequentialChain, PromptTemplate } from './chains/llmchain.js';
25
+ export { RetrievalQAChain, createRetrievalChain } from './chains/rag.js';
26
+
27
+ // ============================================================================
28
+ // Router
29
+ // ============================================================================
30
+
31
+ export { SmartRouter } from './router/smartrouter.js';
32
+
33
+ // ============================================================================
34
+ // Cache
35
+ // ============================================================================
36
+
37
+ export { SemanticCache } from './cache/semantic.js';
38
+
39
+ // ============================================================================
40
+ // Memory
41
+ // ============================================================================
42
+
43
+ export { BufferMemory, TokenBudgetMemory } from './memory/buffer.js';
44
+
45
+ // ============================================================================
46
+ // Tools
47
+ // ============================================================================
48
+
49
+ export { Tool, tool, createToolDecorator, defineTool, calculator, search, weather, KeiroSearch } from './tools/index.js';
50
+
51
+ // ============================================================================
52
+ // Tracing
53
+ // ============================================================================
54
+
55
+ export { tracer, Tracer } from './tracing/tracer.js';
56
+
57
+ // ============================================================================
58
+ // Evals
59
+ // ============================================================================
60
+
61
+ export { LLMJudge, EvalCriteria } from './evals/judge.js';
62
+
63
+ // ============================================================================
64
+ // Text Splitters
65
+ // ============================================================================
66
+
67
+ export { CharacterTextSplitter, RecursiveCharacterTextSplitter, createCharacterSplitter, createRecursiveSplitter } from './text_splitters/index.js';
68
+
69
+ // ============================================================================
70
+ // Vector Stores
71
+ // ============================================================================
72
+
73
+ export { InMemoryVectorStore, ChromaVectorStore, SQLiteVectorStore, createVectorStore, createChromaVectorStore, createSQLiteVectorStore } from './vectorstores/index.js';
74
+
75
+ // ============================================================================
76
+ // Document Loaders
77
+ // ============================================================================
78
+
79
+ export { TextLoader, CSVLoader, JSONLoader, loadDocument, loadDocuments } from './document_loaders/index.js';
80
+
81
+ // ============================================================================
82
+ // Embeddings
83
+ // ============================================================================
84
+
85
+ export { GoogleEmbeddings, createGoogleEmbeddings } from './embeddings/google.js';
86
+ export { LocalEmbeddings, HuggingFaceEmbeddings, createLocalEmbeddings } from './embeddings/local.js';
87
+
88
+ // ============================================================================
89
+ // Output Parsers
90
+ // ============================================================================
91
+
92
+ export { JSONOutputParser, XMLOutputParser, CommaSeparatedListParser, MarkdownCodeBlockParser, ToolCallParser, createJSONParser, createXMLParser, createListParser, createMarkdownParser } from './parsers/output.js';
93
+
94
+ // ============================================================================
95
+ // Prompt Registry
96
+ // ============================================================================
97
+
98
+ export { PromptRegistry, SimplePromptTemplate, createPromptRegistry } from './prompts/registry.js';
99
+
100
+ // ============================================================================
101
+ // Retrievers
102
+ // ============================================================================
103
+
104
+ export { ContextualCompressionRetriever, ParentDocumentRetriever, EnsembleRetriever, createVectorStoreRetriever } from './retrievers/index.js';
105
+ export type { BaseRetriever } from './retrievers/index.js';
106
+
107
+ // ============================================================================
108
+ // Utils
109
+ // ============================================================================
110
+
111
+ export { logger } from './utils/logger.js';
112
+ export { getPricing, setPricing, calculateCost, estimateCost, estimateTokens } from './utils/pricing.js';
113
+
114
+ // ============================================================================
115
+ // Initialize
116
+ // ============================================================================
117
+
118
+ import { loadEnvPricing } from './utils/pricing.js';
119
+ loadEnvPricing();
120
+
121
+ console.log('⚡ Lazlo JS loaded. The Anti-Framework.');