@yamo/memory-mesh 3.0.0 → 3.0.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.
Files changed (107) hide show
  1. package/README.md +8 -2
  2. package/lib/llm/client.d.ts +23 -48
  3. package/lib/llm/client.js +1 -0
  4. package/lib/llm/client.ts +298 -377
  5. package/lib/llm/index.js +1 -0
  6. package/lib/llm/index.ts +1 -2
  7. package/lib/memory/adapters/client.d.ts +22 -85
  8. package/lib/memory/adapters/client.js +1 -0
  9. package/lib/memory/adapters/client.ts +474 -633
  10. package/lib/memory/adapters/config.d.ts +82 -89
  11. package/lib/memory/adapters/config.js +1 -0
  12. package/lib/memory/adapters/config.ts +156 -225
  13. package/lib/memory/adapters/errors.d.ts +28 -20
  14. package/lib/memory/adapters/errors.js +1 -0
  15. package/lib/memory/adapters/errors.ts +83 -120
  16. package/lib/memory/context-manager.d.ts +15 -18
  17. package/lib/memory/context-manager.js +1 -0
  18. package/lib/memory/context-manager.ts +314 -401
  19. package/lib/memory/embeddings/factory.d.ts +18 -20
  20. package/lib/memory/embeddings/factory.js +1 -0
  21. package/lib/memory/embeddings/factory.ts +130 -173
  22. package/lib/memory/embeddings/index.js +1 -0
  23. package/lib/memory/embeddings/index.ts +1 -0
  24. package/lib/memory/embeddings/service.d.ts +36 -66
  25. package/lib/memory/embeddings/service.js +1 -0
  26. package/lib/memory/embeddings/service.ts +479 -616
  27. package/lib/memory/index.d.ts +2 -2
  28. package/lib/memory/index.js +1 -0
  29. package/lib/memory/index.ts +3 -13
  30. package/lib/memory/memory-mesh.d.ts +151 -93
  31. package/lib/memory/memory-mesh.js +1 -0
  32. package/lib/memory/memory-mesh.ts +1406 -1692
  33. package/lib/memory/memory-translator.d.ts +1 -6
  34. package/lib/memory/memory-translator.js +1 -0
  35. package/lib/memory/memory-translator.ts +96 -128
  36. package/lib/memory/schema.d.ts +29 -10
  37. package/lib/memory/schema.js +1 -0
  38. package/lib/memory/schema.ts +102 -185
  39. package/lib/memory/scorer.d.ts +3 -4
  40. package/lib/memory/scorer.js +1 -0
  41. package/lib/memory/scorer.ts +69 -86
  42. package/lib/memory/search/index.js +1 -0
  43. package/lib/memory/search/index.ts +1 -0
  44. package/lib/memory/search/keyword-search.d.ts +10 -26
  45. package/lib/memory/search/keyword-search.js +1 -0
  46. package/lib/memory/search/keyword-search.ts +123 -161
  47. package/lib/scrubber/config/defaults.d.ts +39 -46
  48. package/lib/scrubber/config/defaults.js +1 -0
  49. package/lib/scrubber/config/defaults.ts +50 -112
  50. package/lib/scrubber/errors/scrubber-error.d.ts +22 -0
  51. package/lib/scrubber/errors/scrubber-error.js +39 -0
  52. package/lib/scrubber/errors/scrubber-error.ts +44 -0
  53. package/lib/scrubber/index.d.ts +0 -1
  54. package/lib/scrubber/index.js +1 -0
  55. package/lib/scrubber/index.ts +1 -2
  56. package/lib/scrubber/scrubber.d.ts +14 -31
  57. package/lib/scrubber/scrubber.js +1 -0
  58. package/lib/scrubber/scrubber.ts +93 -152
  59. package/lib/scrubber/stages/chunker.d.ts +22 -10
  60. package/lib/scrubber/stages/chunker.js +86 -0
  61. package/lib/scrubber/stages/chunker.ts +104 -0
  62. package/lib/scrubber/stages/metadata-annotator.d.ts +14 -15
  63. package/lib/scrubber/stages/metadata-annotator.js +64 -0
  64. package/lib/scrubber/stages/metadata-annotator.ts +75 -0
  65. package/lib/scrubber/stages/normalizer.d.ts +13 -10
  66. package/lib/scrubber/stages/normalizer.js +51 -0
  67. package/lib/scrubber/stages/normalizer.ts +60 -0
  68. package/lib/scrubber/stages/semantic-filter.d.ts +13 -10
  69. package/lib/scrubber/stages/semantic-filter.js +51 -0
  70. package/lib/scrubber/stages/semantic-filter.ts +62 -0
  71. package/lib/scrubber/stages/structural-cleaner.d.ts +15 -10
  72. package/lib/scrubber/stages/structural-cleaner.js +73 -0
  73. package/lib/scrubber/stages/structural-cleaner.ts +83 -0
  74. package/lib/scrubber/stages/validator.d.ts +14 -15
  75. package/lib/scrubber/stages/validator.js +56 -0
  76. package/lib/scrubber/stages/validator.ts +67 -0
  77. package/lib/scrubber/telemetry.d.ts +20 -27
  78. package/lib/scrubber/telemetry.js +1 -0
  79. package/lib/scrubber/telemetry.ts +53 -90
  80. package/lib/scrubber/utils/hash.d.ts +14 -0
  81. package/lib/scrubber/utils/hash.js +37 -0
  82. package/lib/scrubber/utils/hash.ts +40 -0
  83. package/lib/scrubber/utils/html-parser.d.ts +14 -0
  84. package/lib/scrubber/utils/html-parser.js +38 -0
  85. package/lib/scrubber/utils/html-parser.ts +46 -0
  86. package/lib/scrubber/utils/pattern-matcher.d.ts +12 -0
  87. package/lib/scrubber/utils/pattern-matcher.js +54 -0
  88. package/lib/scrubber/utils/pattern-matcher.ts +64 -0
  89. package/lib/scrubber/utils/token-counter.d.ts +18 -0
  90. package/lib/scrubber/utils/token-counter.js +30 -0
  91. package/lib/scrubber/utils/token-counter.ts +32 -0
  92. package/lib/utils/logger.d.ts +1 -11
  93. package/lib/utils/logger.js +1 -0
  94. package/lib/utils/logger.ts +43 -63
  95. package/lib/utils/skill-metadata.d.ts +6 -14
  96. package/lib/utils/skill-metadata.js +1 -0
  97. package/lib/utils/skill-metadata.ts +89 -103
  98. package/lib/yamo/emitter.d.ts +8 -35
  99. package/lib/yamo/emitter.js +1 -0
  100. package/lib/yamo/emitter.ts +77 -155
  101. package/lib/yamo/index.d.ts +14 -0
  102. package/lib/yamo/index.js +14 -0
  103. package/lib/yamo/index.ts +16 -0
  104. package/lib/yamo/schema.d.ts +8 -10
  105. package/lib/yamo/schema.js +1 -0
  106. package/lib/yamo/schema.ts +82 -114
  107. package/package.json +4 -2
package/lib/llm/client.ts CHANGED
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck
1
2
  /**
2
3
  * LLM Client - Multi-provider LLM API client for reflection generation
3
4
  *
@@ -7,108 +8,76 @@
7
8
  * - Ollama (local models)
8
9
  * - Graceful fallback when LLM unavailable
9
10
  */
10
-
11
11
  import { createLogger } from "../utils/logger.js";
12
-
13
12
  const logger = createLogger("llm-client");
14
-
15
- export interface LLMConfig {
16
- provider?: string;
17
- apiKey?: string;
18
- model?: string;
19
- baseUrl?: string;
20
- timeout?: number;
21
- maxRetries?: number;
22
- maxTokens?: number;
23
- }
24
-
25
- export interface ReflectionResult {
26
- reflection: string;
27
- confidence: number;
28
- }
29
-
30
- export interface LLMStats {
31
- totalRequests: number;
32
- successfulRequests: number;
33
- failedRequests: number;
34
- fallbackCount: number;
35
- }
36
-
37
13
  /**
38
14
  * LLMClient provides unified interface for calling various LLM providers
39
15
  * to generate reflections from memory contexts.
40
16
  */
41
17
  export class LLMClient {
42
- provider: string;
43
- apiKey: string;
44
- model: string;
45
- baseUrl: string;
46
- timeout: number;
47
- maxRetries: number;
48
- maxTokens: number;
49
- stats: LLMStats;
50
-
51
- /**
52
- * Create a new LLMClient instance
53
- */
54
- constructor(config: LLMConfig = {}) {
55
- this.provider = config.provider || process.env.LLM_PROVIDER || "openai";
56
- this.apiKey = config.apiKey || process.env.LLM_API_KEY || "";
57
- this.model =
58
- config.model || process.env.LLM_MODEL || this._getDefaultModel();
59
- this.baseUrl =
60
- config.baseUrl || process.env.LLM_BASE_URL || this._getDefaultBaseUrl();
61
- this.maxTokens = config.maxTokens || 2000;
62
- this.timeout = config.timeout || (this.maxTokens >= 4000 ? 300000 : 60000);
63
- this.maxRetries = config.maxRetries || 2;
64
-
65
- // Statistics
66
- this.stats = {
67
- totalRequests: 0,
68
- successfulRequests: 0,
69
- failedRequests: 0,
70
- fallbackCount: 0,
71
- };
72
- }
73
-
74
- /**
75
- * Get default model for provider
76
- * @private
77
- */
78
- _getDefaultModel(): string {
79
- const defaults: Record<string, string> = {
80
- openai: "gpt-4o-mini",
81
- anthropic: "claude-3-5-haiku-20241022",
82
- ollama: "llama3.2",
83
- };
84
- return defaults[this.provider] || "gpt-4o-mini";
85
- }
86
-
87
- /**
88
- * Get default base URL for provider
89
- * @private
90
- */
91
- _getDefaultBaseUrl(): string {
92
- const defaults: Record<string, string> = {
93
- openai: "https://api.openai.com/v1",
94
- anthropic: "https://api.anthropic.com/v1",
95
- ollama: "http://localhost:11434",
96
- };
97
- return defaults[this.provider] || "https://api.openai.com/v1";
98
- }
99
-
100
- /**
101
- * Generate reflection from memories
102
- * Main entry point for reflection generation
103
- */
104
- async reflect(prompt: string, memories: any[]): Promise<ReflectionResult> {
105
- this.stats.totalRequests++;
106
-
107
- if (!memories || memories.length === 0) {
108
- return this._fallback("No memories provided");
18
+ provider;
19
+ apiKey;
20
+ model;
21
+ baseUrl;
22
+ timeout;
23
+ maxRetries;
24
+ maxTokens;
25
+ stats;
26
+ /**
27
+ * Create a new LLMClient instance
28
+ */
29
+ constructor(config = {}) {
30
+ this.provider = config.provider || process.env.LLM_PROVIDER || "openai";
31
+ this.apiKey = config.apiKey || process.env.LLM_API_KEY || "";
32
+ this.model =
33
+ config.model || process.env.LLM_MODEL || this._getDefaultModel();
34
+ this.baseUrl =
35
+ config.baseUrl || process.env.LLM_BASE_URL || this._getDefaultBaseUrl();
36
+ this.maxTokens = config.maxTokens || 2000;
37
+ this.timeout = config.timeout || (this.maxTokens >= 4000 ? 300000 : 60000);
38
+ this.maxRetries = config.maxRetries || 2;
39
+ // Statistics
40
+ this.stats = {
41
+ totalRequests: 0,
42
+ successfulRequests: 0,
43
+ failedRequests: 0,
44
+ fallbackCount: 0,
45
+ };
109
46
  }
110
-
111
- const systemPrompt = `You are a reflective AI agent. Review the provided memories and synthesize a high-level insight, belief, or observation.
47
+ /**
48
+ * Get default model for provider
49
+ * @private
50
+ */
51
+ _getDefaultModel() {
52
+ const defaults = {
53
+ openai: "gpt-4o-mini",
54
+ anthropic: "claude-3-5-haiku-20241022",
55
+ ollama: "llama3.2",
56
+ };
57
+ return defaults[this.provider] || "gpt-4o-mini";
58
+ }
59
+ /**
60
+ * Get default base URL for provider
61
+ * @private
62
+ */
63
+ _getDefaultBaseUrl() {
64
+ const defaults = {
65
+ openai: "https://api.openai.com/v1",
66
+ anthropic: "https://api.anthropic.com/v1",
67
+ ollama: "http://localhost:11434",
68
+ };
69
+ return defaults[this.provider] || "https://api.openai.com/v1";
70
+ }
71
+ /**
72
+ * Generate reflection from memories
73
+ * Main entry point for reflection generation
74
+ */
75
+ async reflect(prompt, memories) {
76
+ this.stats.totalRequests++;
77
+ if (!memories || memories.length === 0) {
78
+ return this._fallback("No memories provided");
79
+ }
80
+ const systemPrompt = `You are a reflective AI agent. Review the provided memories and synthesize a high-level insight, belief, or observation.
112
81
  Respond ONLY in JSON format with exactly these keys:
113
82
  {
114
83
  "reflection": "a concise insight or observation derived from the memories",
@@ -116,298 +85,250 @@ Respond ONLY in JSON format with exactly these keys:
116
85
  }
117
86
 
118
87
  Keep the reflection brief (1-2 sentences) and actionable.`;
119
-
120
- const userContent = this._formatMemoriesForLLM(prompt, memories);
121
-
122
- try {
123
- const response = await this._callWithRetry(systemPrompt, userContent);
124
- const parsed = JSON.parse(response);
125
-
126
- // Validate response structure
127
- if (!parsed.reflection || typeof parsed.confidence !== "number") {
128
- throw new Error("Invalid LLM response format");
129
- }
130
-
131
- // Clamp confidence to valid range
132
- parsed.confidence = Math.max(0, Math.min(1, parsed.confidence));
133
-
134
- this.stats.successfulRequests++;
135
- return parsed as ReflectionResult;
136
- } catch (error) {
137
- this.stats.failedRequests++;
138
- const errorMessage =
139
- error instanceof Error ? error.message : String(error);
140
- logger.debug({ err: error, errorMessage }, "LLM call failed");
141
- return this._fallback("LLM error", memories);
88
+ const userContent = this._formatMemoriesForLLM(prompt, memories);
89
+ try {
90
+ const response = await this._callWithRetry(systemPrompt, userContent);
91
+ const parsed = JSON.parse(response);
92
+ // Validate response structure
93
+ if (!parsed.reflection || typeof parsed.confidence !== "number") {
94
+ throw new Error("Invalid LLM response format");
95
+ }
96
+ // Clamp confidence to valid range
97
+ parsed.confidence = Math.max(0, Math.min(1, parsed.confidence));
98
+ this.stats.successfulRequests++;
99
+ return parsed;
100
+ }
101
+ catch (error) {
102
+ this.stats.failedRequests++;
103
+ const errorMessage = error instanceof Error ? error.message : String(error);
104
+ logger.debug({ err: error, errorMessage }, "LLM call failed");
105
+ return this._fallback("LLM error", memories);
106
+ }
142
107
  }
143
- }
144
-
145
- /**
146
- * Format memories for LLM consumption
147
- * @private
148
- */
149
- _formatMemoriesForLLM(prompt: string, memories: any[]): string {
150
- const memoryList = memories
151
- .map((m, i) => `${i + 1}. ${m.content}`)
152
- .join("\n");
153
-
154
- return `Prompt: ${prompt}\n\nMemories:\n${memoryList}\n\nBased on these memories, provide a brief reflective insight.`;
155
- }
156
-
157
- /**
158
- * Call LLM with retry logic
159
- * @private
160
- */
161
- async _callWithRetry(
162
- systemPrompt: string,
163
- userContent: string,
164
- ): Promise<string> {
165
- let lastError: any = null;
166
-
167
- for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
168
- try {
169
- return await this._callLLM(systemPrompt, userContent);
170
- } catch (error) {
171
- lastError = error;
172
- if (attempt < this.maxRetries) {
173
- const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
174
- await this._sleep(delay);
108
+ /**
109
+ * Format memories for LLM consumption
110
+ * @private
111
+ */
112
+ _formatMemoriesForLLM(prompt, memories) {
113
+ const memoryList = memories
114
+ .map((m, i) => `${i + 1}. ${m.content}`)
115
+ .join("\n");
116
+ return `Prompt: ${prompt}\n\nMemories:\n${memoryList}\n\nBased on these memories, provide a brief reflective insight.`;
117
+ }
118
+ /**
119
+ * Call LLM with retry logic
120
+ * @private
121
+ */
122
+ async _callWithRetry(systemPrompt, userContent) {
123
+ let lastError = null;
124
+ for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
125
+ try {
126
+ return await this._callLLM(systemPrompt, userContent);
127
+ }
128
+ catch (error) {
129
+ lastError = error;
130
+ if (attempt < this.maxRetries) {
131
+ const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
132
+ await this._sleep(delay);
133
+ }
134
+ }
175
135
  }
176
- }
136
+ throw lastError;
177
137
  }
178
-
179
- throw lastError;
180
- }
181
-
182
- /**
183
- * Call LLM based on provider
184
- * @private
185
- */
186
- async _callLLM(systemPrompt: string, userContent: string): Promise<string> {
187
- switch (this.provider) {
188
- case "openai":
189
- return this._callOpenAI(systemPrompt, userContent);
190
- case "anthropic":
191
- return this._callAnthropic(systemPrompt, userContent);
192
- case "ollama":
193
- return this._callOllama(systemPrompt, userContent);
194
- default:
195
- throw new Error(`Unsupported provider: ${this.provider}`);
138
+ /**
139
+ * Call LLM based on provider
140
+ * @private
141
+ */
142
+ async _callLLM(systemPrompt, userContent) {
143
+ switch (this.provider) {
144
+ case "openai":
145
+ return this._callOpenAI(systemPrompt, userContent);
146
+ case "anthropic":
147
+ return this._callAnthropic(systemPrompt, userContent);
148
+ case "ollama":
149
+ return this._callOllama(systemPrompt, userContent);
150
+ default:
151
+ throw new Error(`Unsupported provider: ${this.provider}`);
152
+ }
196
153
  }
197
- }
198
-
199
- /**
200
- * Call OpenAI API
201
- * @private
202
- */
203
- async _callOpenAI(
204
- systemPrompt: string,
205
- userContent: string,
206
- ): Promise<string> {
207
- if (!this.apiKey) {
208
- throw new Error("OpenAI API key not configured");
154
+ /**
155
+ * Call OpenAI API
156
+ * @private
157
+ */
158
+ async _callOpenAI(systemPrompt, userContent) {
159
+ if (!this.apiKey) {
160
+ throw new Error("OpenAI API key not configured");
161
+ }
162
+ const controller = new AbortController();
163
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
164
+ try {
165
+ const response = await fetch(`${this.baseUrl}/chat/completions`, {
166
+ method: "POST",
167
+ headers: {
168
+ "Content-Type": "application/json",
169
+ Authorization: `Bearer ${this.apiKey}`,
170
+ },
171
+ body: JSON.stringify({
172
+ model: this.model,
173
+ messages: [
174
+ { role: "system", content: systemPrompt },
175
+ { role: "user", content: userContent },
176
+ ],
177
+ temperature: 0.7,
178
+ max_tokens: this.maxTokens,
179
+ }),
180
+ signal: controller.signal,
181
+ });
182
+ clearTimeout(timeoutId);
183
+ if (!response.ok) {
184
+ const error = await response.text();
185
+ throw new Error(`OpenAI API error: ${response.status} - ${error}`);
186
+ }
187
+ const data = await response.json();
188
+ return data.choices[0].message.content;
189
+ }
190
+ catch (error) {
191
+ clearTimeout(timeoutId);
192
+ if (error instanceof Error && error.name === "AbortError") {
193
+ throw new Error("Request timeout");
194
+ }
195
+ throw error;
196
+ }
209
197
  }
210
-
211
- const controller = new AbortController();
212
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
213
-
214
- try {
215
- const response = await fetch(`${this.baseUrl}/chat/completions`, {
216
- method: "POST",
217
- headers: {
218
- "Content-Type": "application/json",
219
- Authorization: `Bearer ${this.apiKey}`,
220
- },
221
- body: JSON.stringify({
222
- model: this.model,
223
- messages: [
224
- { role: "system", content: systemPrompt },
225
- { role: "user", content: userContent },
226
- ],
227
- temperature: 0.7,
228
- max_tokens: this.maxTokens,
229
- }),
230
- signal: controller.signal,
231
- });
232
-
233
- clearTimeout(timeoutId);
234
-
235
- if (!response.ok) {
236
- const error = await response.text();
237
- throw new Error(`OpenAI API error: ${response.status} - ${error}`);
238
- }
239
-
240
- const data = await response.json();
241
- return data.choices[0].message.content;
242
- } catch (error) {
243
- clearTimeout(timeoutId);
244
- if (error instanceof Error && error.name === "AbortError") {
245
- throw new Error("Request timeout");
246
- }
247
- throw error;
198
+ /**
199
+ * Call Anthropic (Claude) API
200
+ * @private
201
+ */
202
+ async _callAnthropic(systemPrompt, userContent) {
203
+ if (!this.apiKey) {
204
+ throw new Error("Anthropic API key not configured");
205
+ }
206
+ const controller = new AbortController();
207
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
208
+ try {
209
+ const response = await fetch(`${this.baseUrl}/messages`, {
210
+ method: "POST",
211
+ headers: {
212
+ "Content-Type": "application/json",
213
+ "x-api-key": this.apiKey,
214
+ "anthropic-version": "2023-06-01",
215
+ },
216
+ body: JSON.stringify({
217
+ model: this.model,
218
+ max_tokens: this.maxTokens,
219
+ system: systemPrompt,
220
+ messages: [{ role: "user", content: userContent }],
221
+ }),
222
+ signal: controller.signal,
223
+ });
224
+ clearTimeout(timeoutId);
225
+ if (!response.ok) {
226
+ const error = await response.text();
227
+ throw new Error(`Anthropic API error: ${response.status} - ${error}`);
228
+ }
229
+ const data = await response.json();
230
+ return data.content[0].text;
231
+ }
232
+ catch (error) {
233
+ clearTimeout(timeoutId);
234
+ if (error instanceof Error && error.name === "AbortError") {
235
+ throw new Error("Request timeout");
236
+ }
237
+ throw error;
238
+ }
248
239
  }
249
- }
250
-
251
- /**
252
- * Call Anthropic (Claude) API
253
- * @private
254
- */
255
- async _callAnthropic(
256
- systemPrompt: string,
257
- userContent: string,
258
- ): Promise<string> {
259
- if (!this.apiKey) {
260
- throw new Error("Anthropic API key not configured");
240
+ /**
241
+ * Call Ollama (local) API
242
+ * @private
243
+ */
244
+ async _callOllama(systemPrompt, userContent) {
245
+ const controller = new AbortController();
246
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
247
+ try {
248
+ const response = await fetch(`${this.baseUrl}/api/chat`, {
249
+ method: "POST",
250
+ headers: {
251
+ "Content-Type": "application/json",
252
+ },
253
+ body: JSON.stringify({
254
+ model: this.model,
255
+ messages: [
256
+ { role: "system", content: systemPrompt },
257
+ { role: "user", content: userContent },
258
+ ],
259
+ stream: false,
260
+ options: {
261
+ num_predict: this.maxTokens,
262
+ },
263
+ }),
264
+ signal: controller.signal,
265
+ });
266
+ clearTimeout(timeoutId);
267
+ if (!response.ok) {
268
+ const error = await response.text();
269
+ throw new Error(`Ollama API error: ${response.status} - ${error}`);
270
+ }
271
+ const data = await response.json();
272
+ return data.message.content;
273
+ }
274
+ catch (error) {
275
+ clearTimeout(timeoutId);
276
+ if (error instanceof Error && error.name === "AbortError") {
277
+ throw new Error("Request timeout");
278
+ }
279
+ throw error;
280
+ }
261
281
  }
262
-
263
- const controller = new AbortController();
264
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
265
-
266
- try {
267
- const response = await fetch(`${this.baseUrl}/messages`, {
268
- method: "POST",
269
- headers: {
270
- "Content-Type": "application/json",
271
- "x-api-key": this.apiKey,
272
- "anthropic-version": "2023-06-01",
273
- },
274
- body: JSON.stringify({
275
- model: this.model,
276
- max_tokens: this.maxTokens,
277
- system: systemPrompt,
278
- messages: [{ role: "user", content: userContent }],
279
- }),
280
- signal: controller.signal,
281
- });
282
-
283
- clearTimeout(timeoutId);
284
-
285
- if (!response.ok) {
286
- const error = await response.text();
287
- throw new Error(`Anthropic API error: ${response.status} - ${error}`);
288
- }
289
-
290
- const data = await response.json();
291
- return data.content[0].text;
292
- } catch (error) {
293
- clearTimeout(timeoutId);
294
- if (error instanceof Error && error.name === "AbortError") {
295
- throw new Error("Request timeout");
296
- }
297
- throw error;
282
+ /**
283
+ * Fallback when LLM fails
284
+ * @private
285
+ */
286
+ _fallback(reason, memories = []) {
287
+ this.stats.fallbackCount++;
288
+ if (memories && memories.length > 0) {
289
+ // Simple aggregation fallback
290
+ const contents = memories.map((m) => m.content);
291
+ const combined = contents.join("; ");
292
+ const preview = combined.length > 200 ? `${combined.substring(0, 200)}...` : combined;
293
+ return {
294
+ reflection: `Aggregated from ${memories.length} memories: ${preview}`,
295
+ confidence: 0.5,
296
+ };
297
+ }
298
+ return {
299
+ reflection: `Reflection generation unavailable: ${reason}`,
300
+ confidence: 0.3,
301
+ };
298
302
  }
299
- }
300
-
301
- /**
302
- * Call Ollama (local) API
303
- * @private
304
- */
305
- async _callOllama(
306
- systemPrompt: string,
307
- userContent: string,
308
- ): Promise<string> {
309
- const controller = new AbortController();
310
- const timeoutId = setTimeout(() => controller.abort(), this.timeout);
311
-
312
- try {
313
- const response = await fetch(`${this.baseUrl}/api/chat`, {
314
- method: "POST",
315
- headers: {
316
- "Content-Type": "application/json",
317
- },
318
- body: JSON.stringify({
319
- model: this.model,
320
- messages: [
321
- { role: "system", content: systemPrompt },
322
- { role: "user", content: userContent },
323
- ],
324
- stream: false,
325
- options: {
326
- num_predict: this.maxTokens,
327
- },
328
- }),
329
- signal: controller.signal,
330
- });
331
-
332
- clearTimeout(timeoutId);
333
-
334
- if (!response.ok) {
335
- const error = await response.text();
336
- throw new Error(`Ollama API error: ${response.status} - ${error}`);
337
- }
338
-
339
- const data = await response.json();
340
- return data.message.content;
341
- } catch (error) {
342
- clearTimeout(timeoutId);
343
- if (error instanceof Error && error.name === "AbortError") {
344
- throw new Error("Request timeout");
345
- }
346
- throw error;
303
+ /**
304
+ * Sleep utility
305
+ * @private
306
+ */
307
+ _sleep(ms) {
308
+ return new Promise((resolve) => setTimeout(resolve, ms));
347
309
  }
348
- }
349
-
350
- /**
351
- * Fallback when LLM fails
352
- * @private
353
- */
354
- _fallback(reason: string, memories: any[] = []): ReflectionResult {
355
- this.stats.fallbackCount++;
356
-
357
- if (memories && memories.length > 0) {
358
- // Simple aggregation fallback
359
- const contents = memories.map((m) => m.content);
360
- const combined = contents.join("; ");
361
- const preview =
362
- combined.length > 200 ? `${combined.substring(0, 200)}...` : combined;
363
-
364
- return {
365
- reflection: `Aggregated from ${memories.length} memories: ${preview}`,
366
- confidence: 0.5,
367
- };
310
+ /**
311
+ * Get client statistics
312
+ * @returns {Object} Statistics
313
+ */
314
+ getStats() {
315
+ return {
316
+ ...this.stats,
317
+ successRate: this.stats.totalRequests > 0
318
+ ? (this.stats.successfulRequests / this.stats.totalRequests).toFixed(2)
319
+ : "0.00",
320
+ };
321
+ }
322
+ /**
323
+ * Reset statistics
324
+ */
325
+ resetStats() {
326
+ this.stats = {
327
+ totalRequests: 0,
328
+ successfulRequests: 0,
329
+ failedRequests: 0,
330
+ fallbackCount: 0,
331
+ };
368
332
  }
369
-
370
- return {
371
- reflection: `Reflection generation unavailable: ${reason}`,
372
- confidence: 0.3,
373
- };
374
- }
375
-
376
- /**
377
- * Sleep utility
378
- * @private
379
- */
380
- _sleep(ms: number): Promise<void> {
381
- return new Promise((resolve) => setTimeout(resolve, ms));
382
- }
383
-
384
- /**
385
- * Get client statistics
386
- * @returns {Object} Statistics
387
- */
388
- getStats(): any {
389
- return {
390
- ...this.stats,
391
- successRate:
392
- this.stats.totalRequests > 0
393
- ? (this.stats.successfulRequests / this.stats.totalRequests).toFixed(
394
- 2,
395
- )
396
- : "0.00",
397
- };
398
- }
399
-
400
- /**
401
- * Reset statistics
402
- */
403
- resetStats(): void {
404
- this.stats = {
405
- totalRequests: 0,
406
- successfulRequests: 0,
407
- failedRequests: 0,
408
- fallbackCount: 0,
409
- };
410
- }
411
333
  }
412
-
413
334
  export default LLMClient;