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
package/.env.example ADDED
@@ -0,0 +1,9 @@
1
+ # OpenAI API Key (required for OpenAI provider)
2
+ OPENAI_API_KEY=sk-your-openai-key-here
3
+
4
+ # Keiro Search API (optional - for web search tool)
5
+ KEIRO_API_KEY=your-keiro-key
6
+
7
+ # Custom model pricing (optional)
8
+ # Format: LAZLO_PRICING_model_name=input_cost,output_cost
9
+ # LAZLO_PRICING_gpt4=2.5,10
package/README.md ADDED
@@ -0,0 +1,278 @@
1
+ # Lazlo JS
2
+
3
+ The Anti-Framework for JavaScript/TypeScript - A production-grade AI framework that prioritizes performance, transparency, and simplicity.
4
+
5
+ ## Why Lazlo?
6
+
7
+ - **No Black Magic**: When you use a tool, you see the JSON being parsed. Debugging is straightforward JavaScript.
8
+ - **Zero Bloat**: Core Lazlo uses just `axios` and `zod`. Everything else is optional.
9
+ - **Production Built-In**: Caching, routing, and tracing are built directly into Lazlo, locally and securely.
10
+ - **Protocols over Inheritance**: Duck typing works out of the box. If your class implements `invoke()`, it's an LLM.
11
+ - **Full RAG Pipeline**: Document loaders, embeddings, vector stores, and retrievers built-in.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install lazlo
17
+ ```
18
+
19
+ ## Environment Setup
20
+
21
+ Create a `.env` file in your project root:
22
+
23
+ ```bash
24
+ # Required for OpenAI provider
25
+ OPENAI_API_KEY=sk-your-openai-key-here
26
+
27
+ # Required for Google embeddings/Gemini
28
+ GEMINI_API_KEY=your-gemini-key
29
+
30
+ # Required for Ollama (local models)
31
+ # No API key needed - runs locally
32
+
33
+ # Optional: Keiro Search API
34
+ KEIRO_API_KEY=your-keiro-key
35
+ ```
36
+
37
+ ## Quick Start
38
+
39
+ ```typescript
40
+ import { OpenAI, LLMChain, PromptTemplate } from 'lazlo';
41
+
42
+ // Create an LLM - key from OPENAI_API_KEY env var
43
+ const llm = new OpenAI();
44
+
45
+ // Create a chain
46
+ const chain = new LLMChain({
47
+ llm,
48
+ prompt: new PromptTemplate('What is {topic}?'),
49
+ });
50
+
51
+ // Run it
52
+ const result = await chain.invoke({ topic: 'quantum computing' });
53
+ console.log(result.text);
54
+ ```
55
+
56
+ ## Full Feature List
57
+
58
+ ### Providers
59
+ - **OpenAI** - GPT-4, GPT-4o, GPT-4o-mini, etc.
60
+ - **Ollama** - Local LLMs (Llama3.2, Mistral, etc.)
61
+
62
+ ### Embeddings
63
+ - **OpenAIEmbeddings** - OpenAI text embeddings
64
+ - **GoogleEmbeddings** - Google Gemini embeddings
65
+ - **LocalEmbeddings** - Zero-cost offline embeddings
66
+
67
+ ### Vector Stores
68
+ - **InMemoryVectorStore** - Fast prototyping
69
+ - **ChromaVectorStore** - Production disk persistence
70
+ - **SQLiteVectorStore** - Zero-infrastructure, single file
71
+
72
+ ### Document Loaders
73
+ - **TextLoader** - .txt, .md files
74
+ - **CSVLoader** - CSV with custom delimiters
75
+ - **JSONLoader** - JSON with key extraction
76
+ - Auto-detection of file types
77
+
78
+ ### Chains
79
+ - **LLMChain** - Basic prompt → LLM → output
80
+ - **SequentialChain** - Multi-step pipelines
81
+ - **RetrievalQAChain** - RAG with context
82
+
83
+ ### Smart Routing
84
+ - Auto-route simple queries to cheap models
85
+ - Complex queries to smart models
86
+
87
+ ### Caching
88
+ - **SemanticCache** - Cosine similarity cache hits
89
+
90
+ ### Memory
91
+ - **BufferMemory** - Conversation history
92
+ - **TokenBudgetMemory** - Auto-summarization at limit
93
+
94
+ ### Tools
95
+ - **@tool decorator** - Custom function tools
96
+ - **calculator** - Math expression evaluator
97
+ - **search** - Web search (via Keiro)
98
+ - **weather** - Weather data
99
+
100
+ ### Tracing
101
+ - Built-in observability, no SaaS needed
102
+
103
+ ### Evals
104
+ - **LLMJudge** - Automated response evaluation
105
+
106
+ ### Output Parsers
107
+ - **JSONOutputParser** - Parse JSON from text
108
+ - **XMLOutputParser** - Extract XML tags
109
+ - **CommaSeparatedListParser** - Split lists
110
+ - **MarkdownCodeBlockParser** - Extract code blocks
111
+
112
+ ### Prompt Registry
113
+ - Load prompts from YAML files
114
+ - Version support (@v1, @v2)
115
+
116
+ ### Retrievers
117
+ - **ContextualCompressionRetriever** - Compress docs by context
118
+ - **ParentDocumentRetriever** - Get full docs from chunks
119
+ - **EnsembleRetriever** - Combine multiple retrievers
120
+ - **createVectorStoreRetriever** - Easy vector RAG
121
+
122
+ ## Example: Full RAG Pipeline
123
+
124
+ ```typescript
125
+ import {
126
+ OpenAI,
127
+ InMemoryVectorStore,
128
+ TextLoader,
129
+ CharacterTextSplitter,
130
+ LLMChain,
131
+ PromptTemplate,
132
+ createVectorStoreRetriever
133
+ } from 'lazlo';
134
+
135
+ // 1. Load documents
136
+ const loader = new TextLoader('./docs.txt');
137
+ const docs = await loader.load();
138
+
139
+ // 2. Split into chunks
140
+ const splitter = new CharacterTextSplitter({ chunkSize: 1000 });
141
+ const chunks = await splitter.splitDocuments(docs);
142
+
143
+ // 3. Create vector store
144
+ const embeddings = new OpenAI(); // Uses OpenAI embeddings
145
+ const vectorStore = new InMemoryVectorStore(embeddings);
146
+ await vectorStore.addDocuments(chunks);
147
+
148
+ // 4. Create retriever
149
+ const retriever = createVectorStoreRetriever(vectorStore);
150
+
151
+ // 5. Create RAG chain
152
+ const ragChain = new LLMChain({
153
+ llm: new OpenAI(),
154
+ prompt: new PromptTemplate('Context: {context}\nQuestion: {question}\nAnswer:'),
155
+ });
156
+
157
+ // 6. Run with retrieval
158
+ const retrievedDocs = await retriever.getRelevantDocuments('What is Lazlo?');
159
+ const context = retrievedDocs.map(d => d.pageContent).join('\n');
160
+ const result = await ragChain.invoke({ question: 'What is Lazlo?', context });
161
+ ```
162
+
163
+ ## Example: Prompt Registry
164
+
165
+ ```typescript
166
+ import { PromptRegistry } from 'lazlo';
167
+
168
+ const registry = new PromptRegistry('./prompts');
169
+
170
+ // Register a prompt
171
+ registry.register('rag_qa', {
172
+ template: 'Context: {context}\nQuestion: {question}',
173
+ description: 'RAG QA prompt',
174
+ version: '1.0.0',
175
+ variables: ['context', 'question'],
176
+ });
177
+
178
+ // Load with version
179
+ const template = registry.load('rag_qa@v1');
180
+ const formatted = registry.format(template, { context: '...', question: '...' });
181
+ ```
182
+
183
+ ## Example: Output Parsing
184
+
185
+ ```typescript
186
+ import { JSONOutputParser } from 'lazlo';
187
+
188
+ const parser = new JSONOutputParser();
189
+ const result = await parser.parse('{"name": "John", "age": 30}');
190
+ // Returns: { name: "John", age: 30 }
191
+ ```
192
+
193
+ ## Example: Ensemble Retrieval
194
+
195
+ ```typescript
196
+ import {
197
+ EnsembleRetriever,
198
+ createVectorStoreRetriever,
199
+ InMemoryVectorStore
200
+ } from 'lazlo';
201
+
202
+ const embeddings = new OpenAI();
203
+ const store1 = new InMemoryVectorStore(embeddings);
204
+ const store2 = new InMemoryVectorStore(embeddings);
205
+
206
+ // ... add different docs to each store ...
207
+
208
+ const retriever = new EnsembleRetriever([
209
+ { retriever: createVectorStoreRetriever(store1), weight: 0.7 },
210
+ { retriever: createVectorStoreRetriever(store2), weight: 0.3 },
211
+ ]);
212
+ ```
213
+
214
+ ## Cost Estimation
215
+
216
+ ```typescript
217
+ import { LLMChain, PromptTemplate, OpenAI } from 'lazlo';
218
+
219
+ const chain = new LLMChain({
220
+ llm: new OpenAI('gpt-4o'),
221
+ prompt: new PromptTemplate('Write about {topic}'),
222
+ });
223
+
224
+ const estimate = chain.estimateCost({ topic: 'AI' });
225
+ console.log(`Estimated cost: $${estimate.estimatedCostUsd}`);
226
+ ```
227
+
228
+ ## API Reference
229
+
230
+ ### OpenAI
231
+
232
+ ```typescript
233
+ new OpenAI(apiKey?: string, defaultModel?: string, options?: {
234
+ temperature?: number,
235
+ maxTokens?: number,
236
+ topP?: number,
237
+ })
238
+ ```
239
+
240
+ ### Ollama
241
+
242
+ ```typescript
243
+ new Ollama(options?: {
244
+ model?: string,
245
+ baseUrl?: string,
246
+ temperature?: number,
247
+ numCtx?: number,
248
+ })
249
+ ```
250
+
251
+ ### Vector Stores
252
+
253
+ ```typescript
254
+ new InMemoryVectorStore(embeddings)
255
+ new ChromaVectorStore({ embeddings, collectionName?: string })
256
+ new SQLiteVectorStore({ embeddings, dbPath?: string })
257
+ ```
258
+
259
+ ### Document Loaders
260
+
261
+ ```typescript
262
+ new TextLoader(filePath: string)
263
+ new CSVLoader(filePath: string, options?: { delimiter?: string })
264
+ new JSONLoader(filePath: string, options?: { key?: string })
265
+ loadDocument(filePath: string): Promise<Document[]>
266
+ ```
267
+
268
+ ### Embeddings
269
+
270
+ ```typescript
271
+ new OpenAIEmbeddings(options?: { apiKey?: string, model?: string })
272
+ new GoogleEmbeddings(options?: { apiKey?: string, model?: string })
273
+ new LocalEmbeddings(options?: { dimensions?: number })
274
+ ```
275
+
276
+ ## License
277
+
278
+ MIT
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Semantic Cache - Cache LLM responses with semantic similarity
3
+ */
4
+ export interface SemanticCacheOptions {
5
+ threshold?: number;
6
+ }
7
+ export declare class SemanticCache {
8
+ private store;
9
+ private threshold;
10
+ private hits;
11
+ private misses;
12
+ private tokensSaved;
13
+ constructor(options?: SemanticCacheOptions);
14
+ /**
15
+ * Look up a cached response
16
+ */
17
+ lookup(prompt: string): string | null;
18
+ /**
19
+ * Store a response in the cache
20
+ */
21
+ put(prompt: string, response: string): void;
22
+ /**
23
+ * Wrap an LLM to use caching
24
+ */
25
+ wrap<T extends {
26
+ invoke(prompt: string): Promise<any>;
27
+ }>(llm: T): T & {
28
+ invoke(prompt: string): Promise<any>;
29
+ };
30
+ /**
31
+ * Print cache statistics
32
+ */
33
+ printStats(): void;
34
+ /**
35
+ * Clear the cache
36
+ */
37
+ clear(): void;
38
+ }
39
+ //# sourceMappingURL=semantic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../src/cache/semantic.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6DH,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,WAAW,CAAK;gBAEZ,OAAO,GAAE,oBAAyB;IAK9C;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA2BrC;;OAEG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAM3C;;OAEG;IACH,IAAI,CAAC,CAAC,SAAS;QAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;KAAE,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG;QAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;KAAE;IAsB9G;;OAEG;IACH,UAAU,IAAI,IAAI;IAkBlB;;OAEG;IACH,KAAK,IAAI,IAAI;CAOd"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Semantic Cache - Cache LLM responses with semantic similarity
3
+ */
4
+ import { logger } from '../utils/logger.js';
5
+ // ============================================================================
6
+ // Cosine Similarity
7
+ // ============================================================================
8
+ function cosineSimilarity(v1, v2) {
9
+ const dot = v1.reduce((sum, a, i) => sum + a * v2[i], 0);
10
+ const norm1 = Math.sqrt(v1.reduce((sum, a) => sum + a * a, 0));
11
+ const norm2 = Math.sqrt(v2.reduce((sum, b) => sum + b * b, 0));
12
+ if (norm1 === 0 || norm2 === 0)
13
+ return 0;
14
+ return dot / (norm1 * norm2);
15
+ }
16
+ // Simple hash-based embedding (for demo - in production use real embeddings)
17
+ // This creates a deterministic "embedding" from the text
18
+ function simpleEmbedding(text) {
19
+ const hash = new Map();
20
+ const words = text.toLowerCase().split(/\s+/);
21
+ // Create a simple bag-of-words embedding
22
+ for (let i = 0; i < 384; i++) {
23
+ hash.set(String(i), 0);
24
+ }
25
+ words.forEach((word, idx) => {
26
+ const hash1 = (word.charCodeAt(0) * 31 + idx) % 384;
27
+ const hash2 = (word.length * 17 + idx) % 384;
28
+ hash.set(String(hash1), (hash.get(String(hash1)) ?? 0) + 1);
29
+ hash.set(String(hash2), (hash.get(String(hash2)) ?? 0) + 0.5);
30
+ });
31
+ // Normalize
32
+ const embedding = [];
33
+ let norm = 0;
34
+ for (let i = 0; i < 384; i++) {
35
+ const val = hash.get(String(i)) ?? 0;
36
+ embedding.push(val);
37
+ norm += val * val;
38
+ }
39
+ norm = Math.sqrt(norm);
40
+ return embedding.map(v => v / (norm || 1));
41
+ }
42
+ export class SemanticCache {
43
+ store = [];
44
+ threshold;
45
+ hits = 0;
46
+ misses = 0;
47
+ tokensSaved = 0;
48
+ constructor(options = {}) {
49
+ this.threshold = options.threshold ?? 0.92;
50
+ logger.info(`SemanticCache ready. Threshold: ${this.threshold}`);
51
+ }
52
+ /**
53
+ * Look up a cached response
54
+ */
55
+ lookup(prompt) {
56
+ if (this.store.length === 0) {
57
+ return null;
58
+ }
59
+ const queryEmbedding = simpleEmbedding(prompt);
60
+ let bestScore = 0;
61
+ let bestResponse = null;
62
+ for (const entry of this.store) {
63
+ const score = cosineSimilarity(queryEmbedding, entry.embedding);
64
+ if (score > bestScore) {
65
+ bestScore = score;
66
+ bestResponse = entry.response;
67
+ }
68
+ }
69
+ if (bestScore >= this.threshold) {
70
+ logger.info(`[SemanticCache] CACHE HIT (similarity=${bestScore.toFixed(3)}). Skipping LLM call.`);
71
+ this.hits++;
72
+ this.tokensSaved += bestResponse.length / 4;
73
+ return bestResponse;
74
+ }
75
+ return null;
76
+ }
77
+ /**
78
+ * Store a response in the cache
79
+ */
80
+ put(prompt, response) {
81
+ const embedding = simpleEmbedding(prompt);
82
+ this.store.push({ prompt, response, embedding });
83
+ logger.debug(`[SemanticCache] Stored response for: ${prompt.slice(0, 50)}...`);
84
+ }
85
+ /**
86
+ * Wrap an LLM to use caching
87
+ */
88
+ wrap(llm) {
89
+ const cache = this;
90
+ const cachedInvoke = async function (prompt) {
91
+ const cached = cache.lookup(prompt);
92
+ if (cached !== null) {
93
+ return cached;
94
+ }
95
+ cache.misses++;
96
+ logger.debug('[SemanticCache] CACHE MISS. Calling LLM.');
97
+ const response = await llm.invoke(prompt);
98
+ const responseStr = typeof response === 'string' ? response : response.content ?? '';
99
+ cache.put(prompt, responseStr);
100
+ return response;
101
+ };
102
+ return Object.assign(cachedInvoke, llm);
103
+ }
104
+ /**
105
+ * Print cache statistics
106
+ */
107
+ printStats() {
108
+ const total = this.hits + this.misses;
109
+ const hitRate = total > 0 ? (this.hits / total * 100).toFixed(1) : '0.0';
110
+ const costSaved = (this.tokensSaved / 1000 * 0.002).toFixed(4);
111
+ console.log(`
112
+ ${'='.repeat(50)}
113
+ Lazlo SemanticCache Stats
114
+ ${'='.repeat(50)}
115
+ Total calls : ${total}
116
+ Cache hits : ${this.hits} (${hitRate}%)
117
+ Cache misses: ${this.misses}
118
+ Est. tokens saved : ~${this.tokensSaved.toLocaleString()}
119
+ Est. cost avoided : ~$${costSaved}
120
+ ${'='.repeat(50)}
121
+ `);
122
+ }
123
+ /**
124
+ * Clear the cache
125
+ */
126
+ clear() {
127
+ this.store = [];
128
+ this.hits = 0;
129
+ this.misses = 0;
130
+ this.tokensSaved = 0;
131
+ logger.info('SemanticCache cleared.');
132
+ }
133
+ }
134
+ //# sourceMappingURL=semantic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic.js","sourceRoot":"","sources":["../../src/cache/semantic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * LLMChain - Simple prompt chaining
3
+ */
4
+ import { BaseChatModel, ChainInputs, ChainOutputs } from '../core/types.js';
5
+ export declare class PromptTemplate {
6
+ private template;
7
+ private inputVariables;
8
+ constructor(template: string);
9
+ format(values: Record<string, unknown>): string;
10
+ get inputVars(): string[];
11
+ }
12
+ export interface LLMChainOptions {
13
+ llm: BaseChatModel;
14
+ prompt: PromptTemplate;
15
+ outputKey?: string;
16
+ }
17
+ export interface CostEstimate {
18
+ estimatedTokensIn: number;
19
+ estimatedTokensOut: number;
20
+ estimatedCostUsd: number;
21
+ estimatedLatencyMs: number;
22
+ model: string;
23
+ pricing: {
24
+ input: number;
25
+ output: number;
26
+ };
27
+ }
28
+ export declare class LLMChain {
29
+ private llm;
30
+ private prompt;
31
+ private outputKey;
32
+ constructor(options: LLMChainOptions);
33
+ /**
34
+ * Estimate cost before running
35
+ */
36
+ estimateCost(inputs: ChainInputs, model?: string): CostEstimate;
37
+ /**
38
+ * Invoke the chain synchronously
39
+ */
40
+ invoke(inputs: ChainInputs): Promise<ChainOutputs>;
41
+ /**
42
+ * Stream the response
43
+ */
44
+ stream(inputs: ChainInputs): AsyncGenerator<string>;
45
+ /**
46
+ * Async invoke
47
+ */
48
+ ainvoke(inputs: ChainInputs): Promise<ChainOutputs>;
49
+ /**
50
+ * Async stream
51
+ */
52
+ astream(inputs: ChainInputs): AsyncGenerator<string>;
53
+ }
54
+ export declare class SequentialChain {
55
+ private chains;
56
+ private inputVariables;
57
+ private outputVariables;
58
+ constructor(options: {
59
+ chains: LLMChain[];
60
+ inputVariables: string[];
61
+ outputVariables: string[];
62
+ });
63
+ invoke(inputs: ChainInputs): Promise<ChainOutputs>;
64
+ }
65
+ //# sourceMappingURL=llmchain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llmchain.d.ts","sourceRoot":"","sources":["../../src/chains/llmchain.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAW,WAAW,EAAE,YAAY,EAAkB,MAAM,kBAAkB,CAAC;AAQrG,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,cAAc,CAAW;gBAErB,QAAQ,EAAE,MAAM;IAQ5B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM;IAc/C,IAAI,SAAS,IAAI,MAAM,EAAE,CAExB;CACF;AAMD,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,aAAa,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5C;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,GAAG,CAAgB;IAC3B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,EAAE,eAAe;IAMpC;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,YAAY;IAwB/D;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAwBxD;;OAEG;IACI,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC;IAW1D;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAIzD;;OAEG;IACI,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC;CAG5D;AAMD,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,cAAc,CAAW;IACjC,OAAO,CAAC,eAAe,CAAW;gBAEtB,OAAO,EAAE;QACnB,MAAM,EAAE,QAAQ,EAAE,CAAC;QACnB,cAAc,EAAE,MAAM,EAAE,CAAC;QACzB,eAAe,EAAE,MAAM,EAAE,CAAC;KAC3B;IAMK,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;CAkBzD"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * LLMChain - Simple prompt chaining
3
+ */
4
+ import { logger } from '../utils/logger.js';
5
+ import { getPricing, estimateTokens, calculateCost } from '../utils/pricing.js';
6
+ // ============================================================================
7
+ // Prompt Template
8
+ // ============================================================================
9
+ export class PromptTemplate {
10
+ template;
11
+ inputVariables;
12
+ constructor(template) {
13
+ this.template = template;
14
+ // Extract variables from {variable} patterns
15
+ const regex = /\{([^}]+)\}/g;
16
+ const matches = template.match(regex);
17
+ this.inputVariables = matches ? matches.map(m => m.slice(1, -1)) : [];
18
+ }
19
+ format(values) {
20
+ // Check for missing variables
21
+ const missing = this.inputVariables.filter(v => !(v in values));
22
+ if (missing.length > 0) {
23
+ throw new Error(`Missing required variables: ${missing.join(', ')}`);
24
+ }
25
+ let result = this.template;
26
+ for (const [key, value] of Object.entries(values)) {
27
+ result = result.replace(new RegExp(`\\{${key}\\}`, 'g'), String(value));
28
+ }
29
+ return result;
30
+ }
31
+ get inputVars() {
32
+ return this.inputVariables;
33
+ }
34
+ }
35
+ export class LLMChain {
36
+ llm;
37
+ prompt;
38
+ outputKey;
39
+ constructor(options) {
40
+ this.llm = options.llm;
41
+ this.prompt = options.prompt;
42
+ this.outputKey = options.outputKey ?? 'text';
43
+ }
44
+ /**
45
+ * Estimate cost before running
46
+ */
47
+ estimateCost(inputs, model) {
48
+ const modelName = model ?? this.llm.defaultModel ?? 'default';
49
+ const formattedPrompt = this.prompt.format(inputs);
50
+ const estimatedTokensIn = estimateTokens(formattedPrompt);
51
+ const estimatedTokensOut = Math.max(1, Math.floor(estimatedTokensIn / 4));
52
+ const pricing = getPricing(modelName);
53
+ const estimatedCost = (estimatedTokensIn / 1_000_000 * pricing.input) +
54
+ (estimatedTokensOut / 1_000_000 * pricing.output);
55
+ // Rough latency: 100ms per 1K input + 50ms per 1K output
56
+ const estimatedLatency = Math.floor(estimatedTokensIn * 0.1 + estimatedTokensOut * 0.05);
57
+ return {
58
+ estimatedTokensIn,
59
+ estimatedTokensOut,
60
+ estimatedCostUsd: Math.round(estimatedCost * 1_000_000) / 1_000_000,
61
+ estimatedLatencyMs: estimatedLatency,
62
+ model: modelName,
63
+ pricing,
64
+ };
65
+ }
66
+ /**
67
+ * Invoke the chain synchronously
68
+ */
69
+ async invoke(inputs) {
70
+ const formattedPrompt = this.prompt.format(inputs);
71
+ logger.debug(`[Chain] Prompt: ${formattedPrompt.slice(0, 100)}...`);
72
+ const messages = [{ role: 'user', content: formattedPrompt }];
73
+ const response = await this.llm.invoke(messages);
74
+ const outputs = {
75
+ [this.outputKey]: response.content,
76
+ };
77
+ // Include usage info if available
78
+ if (response.usage) {
79
+ outputs.usage = response.usage;
80
+ outputs.cost = calculateCost(response.model ?? 'default', response.usage.prompt_tokens, response.usage.completion_tokens);
81
+ }
82
+ return outputs;
83
+ }
84
+ /**
85
+ * Stream the response
86
+ */
87
+ async *stream(inputs) {
88
+ const formattedPrompt = this.prompt.format(inputs);
89
+ logger.debug(`[Chain Stream] Prompt: ${formattedPrompt.slice(0, 100)}...`);
90
+ const messages = [{ role: 'user', content: formattedPrompt }];
91
+ for await (const chunk of this.llm.stream?.(messages) ?? []) {
92
+ yield chunk.delta;
93
+ }
94
+ }
95
+ /**
96
+ * Async invoke
97
+ */
98
+ async ainvoke(inputs) {
99
+ return this.invoke(inputs);
100
+ }
101
+ /**
102
+ * Async stream
103
+ */
104
+ async *astream(inputs) {
105
+ yield* this.stream(inputs);
106
+ }
107
+ }
108
+ // ============================================================================
109
+ // Sequential Chain
110
+ // ============================================================================
111
+ export class SequentialChain {
112
+ chains;
113
+ inputVariables;
114
+ outputVariables;
115
+ constructor(options) {
116
+ this.chains = options.chains;
117
+ this.inputVariables = options.inputVariables;
118
+ this.outputVariables = options.outputVariables;
119
+ }
120
+ async invoke(inputs) {
121
+ let currentState = { ...inputs };
122
+ for (let i = 0; i < this.chains.length; i++) {
123
+ logger.debug(`[SequentialChain] Executing Chain ${i + 1}/${this.chains.length}`);
124
+ const chainOutput = await this.chains[i].invoke(currentState);
125
+ currentState = { ...currentState, ...chainOutput };
126
+ }
127
+ // Return only the requested output variables
128
+ const result = {};
129
+ for (const key of this.outputVariables) {
130
+ if (key in currentState) {
131
+ result[key] = currentState[key];
132
+ }
133
+ }
134
+ return result;
135
+ }
136
+ }
137
+ //# sourceMappingURL=llmchain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llmchain.js","sourceRoot":"","sources":["../../src/chains/llmchain.ts"],"names":[],"mappings":"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"}