@riotprompt/riotprompt 0.0.9 → 0.0.10
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/BUG-ANALYSIS.md +523 -0
- package/CODE-REVIEW-SUMMARY.md +330 -0
- package/FIXES-APPLIED.md +437 -0
- package/dist/chat.d.ts +1 -1
- package/dist/chat.js +2 -5
- package/dist/chat.js.map +1 -1
- package/dist/constants.js +1 -2
- package/dist/constants.js.map +1 -1
- package/dist/context-manager.d.ts +3 -2
- package/dist/context-manager.js +29 -6
- package/dist/context-manager.js.map +1 -1
- package/dist/conversation-logger.d.ts +3 -1
- package/dist/conversation-logger.js +41 -4
- package/dist/conversation-logger.js.map +1 -1
- package/dist/conversation.d.ts +8 -2
- package/dist/conversation.js +36 -9
- package/dist/conversation.js.map +1 -1
- package/dist/items/section.js +3 -3
- package/dist/items/section.js.map +1 -1
- package/dist/iteration-strategy.d.ts +2 -0
- package/dist/iteration-strategy.js +40 -6
- package/dist/iteration-strategy.js.map +1 -1
- package/dist/loader.js +18 -3
- package/dist/loader.js.map +1 -1
- package/dist/message-builder.js +4 -2
- package/dist/message-builder.js.map +1 -1
- package/dist/model-config.d.ts +115 -0
- package/dist/model-config.js +205 -0
- package/dist/model-config.js.map +1 -0
- package/dist/override.js +5 -1
- package/dist/override.js.map +1 -1
- package/dist/parser.js +3 -3
- package/dist/parser.js.map +1 -1
- package/dist/recipes.d.ts +1 -1
- package/dist/recipes.js +4 -4
- package/dist/recipes.js.map +1 -1
- package/dist/reflection.js +5 -2
- package/dist/reflection.js.map +1 -1
- package/dist/riotprompt.cjs +439 -94
- package/dist/riotprompt.cjs.map +1 -1
- package/dist/riotprompt.d.ts +2 -0
- package/dist/riotprompt.js +1 -0
- package/dist/riotprompt.js.map +1 -1
- package/dist/token-budget.d.ts +2 -2
- package/dist/token-budget.js +23 -26
- package/dist/token-budget.js.map +1 -1
- package/dist/util/general.js +1 -1
- package/dist/util/general.js.map +1 -1
- package/package.json +1 -1
package/FIXES-APPLIED.md
ADDED
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
# Code Review Fixes Applied
|
|
2
|
+
|
|
3
|
+
All issues identified in the comprehensive code review have been fixed.
|
|
4
|
+
|
|
5
|
+
## Summary
|
|
6
|
+
|
|
7
|
+
- **Total Issues Fixed:** 19
|
|
8
|
+
- **Critical Issues:** 4
|
|
9
|
+
- **High Priority Issues:** 6
|
|
10
|
+
- **Medium Priority Issues:** 9
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 🔴 Critical Issues Fixed
|
|
15
|
+
|
|
16
|
+
### 1. **Memory Leak in TokenBudgetManager** ✅
|
|
17
|
+
**File:** `src/token-budget.ts`
|
|
18
|
+
|
|
19
|
+
**Problem:** Creating temporary `TokenBudgetManager` instances without disposing encoders.
|
|
20
|
+
|
|
21
|
+
**Fix:** Modified `compressAdaptive()` to temporarily modify config instead of creating new instance.
|
|
22
|
+
|
|
23
|
+
**Before:**
|
|
24
|
+
```typescript
|
|
25
|
+
const tempManager = new TokenBudgetManager(modifiedConfig, 'gpt-4o', this.logger);
|
|
26
|
+
return tempManager.compressFIFO(messages, targetTokens);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**After:**
|
|
30
|
+
```typescript
|
|
31
|
+
const originalPreserveRecent = this.config.preserveRecent;
|
|
32
|
+
this.config.preserveRecent = 5;
|
|
33
|
+
const result = this.compressFIFO(messages, targetTokens);
|
|
34
|
+
this.config.preserveRecent = originalPreserveRecent;
|
|
35
|
+
return result;
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
### 2. **Context Injection Position Tracking Bug** ✅
|
|
41
|
+
**File:** `src/conversation.ts`
|
|
42
|
+
|
|
43
|
+
**Problem:** Multiple items injected at same position had incorrect tracking.
|
|
44
|
+
|
|
45
|
+
**Fix:** Track each item at `position + index` to maintain correct positions.
|
|
46
|
+
|
|
47
|
+
**Before:**
|
|
48
|
+
```typescript
|
|
49
|
+
this.state.messages.splice(position, 0, contextMessage);
|
|
50
|
+
this.state.contextManager.track(item, position);
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**After:**
|
|
54
|
+
```typescript
|
|
55
|
+
const actualPosition = position + i;
|
|
56
|
+
this.state.messages.splice(actualPosition, 0, contextMessage);
|
|
57
|
+
this.state.contextManager.track(item, actualPosition);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
### 3. **Shallow Copy Causing Shared State** ✅
|
|
63
|
+
**File:** `src/conversation.ts`
|
|
64
|
+
|
|
65
|
+
**Problem:** Cloning conversations with shallow copy causes `tool_calls` arrays to be shared.
|
|
66
|
+
|
|
67
|
+
**Fix:** Deep copy messages including nested `tool_calls` arrays.
|
|
68
|
+
|
|
69
|
+
**Before:**
|
|
70
|
+
```typescript
|
|
71
|
+
cloned.state.messages = this.state.messages.map(msg => ({ ...msg }));
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**After:**
|
|
75
|
+
```typescript
|
|
76
|
+
cloned.state.messages = this.state.messages.map(msg => ({
|
|
77
|
+
...msg,
|
|
78
|
+
tool_calls: msg.tool_calls ? msg.tool_calls.map(tc => ({
|
|
79
|
+
...tc,
|
|
80
|
+
function: { ...tc.function }
|
|
81
|
+
})) : undefined
|
|
82
|
+
}));
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
### 4. **Uncaught JSON Parse Error** ✅
|
|
88
|
+
**File:** `src/iteration-strategy.ts`
|
|
89
|
+
|
|
90
|
+
**Problem:** No error handling for `JSON.parse()` on tool arguments.
|
|
91
|
+
|
|
92
|
+
**Fix:** Wrapped JSON.parse in try-catch with descriptive error message.
|
|
93
|
+
|
|
94
|
+
**After:**
|
|
95
|
+
```typescript
|
|
96
|
+
let toolArgs: any;
|
|
97
|
+
try {
|
|
98
|
+
toolArgs = JSON.parse(toolCall.function.arguments);
|
|
99
|
+
} catch (parseError) {
|
|
100
|
+
throw new Error(`Invalid JSON in tool arguments: ${parseError.message}`);
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 🟡 High Priority Issues Fixed
|
|
107
|
+
|
|
108
|
+
### 5. **Hardcoded Model in Recipe ExecuteWith** ✅
|
|
109
|
+
**File:** `src/recipes.ts`
|
|
110
|
+
|
|
111
|
+
**Problem:** `executeWith()` hardcoded `'gpt-4o'` model.
|
|
112
|
+
|
|
113
|
+
**Fix:** Added `model` parameter with default value.
|
|
114
|
+
|
|
115
|
+
**After:**
|
|
116
|
+
```typescript
|
|
117
|
+
executeWith: async (
|
|
118
|
+
llm: LLMClient,
|
|
119
|
+
strategy: IterationStrategy,
|
|
120
|
+
model: Model = 'gpt-4o',
|
|
121
|
+
tokenBudget?: TokenBudgetConfig
|
|
122
|
+
)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
### 6. **Section Array Append Missing Options** ✅
|
|
128
|
+
**File:** `src/items/section.ts`
|
|
129
|
+
|
|
130
|
+
**Problem:** Options not propagated when appending arrays.
|
|
131
|
+
|
|
132
|
+
**Fix:** Pass `options` parameter in recursive calls.
|
|
133
|
+
|
|
134
|
+
**After:**
|
|
135
|
+
```typescript
|
|
136
|
+
if (Array.isArray(item)) {
|
|
137
|
+
item.forEach((item) => {
|
|
138
|
+
append(item, options); // Now propagates options
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### 7. **JSONL File Race Condition** ✅
|
|
146
|
+
**File:** `src/conversation-logger.ts`
|
|
147
|
+
|
|
148
|
+
**Problem:** Fire-and-forget async writes could corrupt JSONL files.
|
|
149
|
+
|
|
150
|
+
**Fix:** Added write queue and cached output path.
|
|
151
|
+
|
|
152
|
+
**After:**
|
|
153
|
+
```typescript
|
|
154
|
+
private cachedOutputPath?: string;
|
|
155
|
+
private writeQueue: Promise<void> = Promise.resolve();
|
|
156
|
+
|
|
157
|
+
// Queue writes
|
|
158
|
+
this.writeQueue = this.writeQueue
|
|
159
|
+
.then(() => this.appendToJSONL(loggedMessage))
|
|
160
|
+
.catch(this.config.onError);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
### 8. **Hardcoded Model Detection System** ✅
|
|
166
|
+
**Files:** New `src/model-config.ts`, `src/chat.ts`, `src/message-builder.ts`, `src/token-budget.ts`
|
|
167
|
+
|
|
168
|
+
**Problem:** Model names hardcoded throughout codebase, inflexible for new models.
|
|
169
|
+
|
|
170
|
+
**Fix:** Created flexible `ModelRegistry` system with pattern-based configuration.
|
|
171
|
+
|
|
172
|
+
**Key Features:**
|
|
173
|
+
- Pattern-based model matching (regex)
|
|
174
|
+
- Configurable role mapping (system vs developer)
|
|
175
|
+
- Tokenizer encoding configuration
|
|
176
|
+
- User-extensible via `configureModel()`
|
|
177
|
+
|
|
178
|
+
**Example Usage:**
|
|
179
|
+
```typescript
|
|
180
|
+
import { configureModel } from 'riotprompt';
|
|
181
|
+
|
|
182
|
+
// Add support for new model family
|
|
183
|
+
configureModel({
|
|
184
|
+
pattern: /^gemini/i,
|
|
185
|
+
personaRole: 'system',
|
|
186
|
+
encoding: 'cl100k_base',
|
|
187
|
+
family: 'gemini'
|
|
188
|
+
});
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
### 9. **Conversation Replayer JSON Parse Error** ✅
|
|
194
|
+
**File:** `src/conversation-logger.ts`
|
|
195
|
+
|
|
196
|
+
**Problem:** No error handling when parsing tool call arguments from logs.
|
|
197
|
+
|
|
198
|
+
**Fix:** Added try-catch with fallback object containing raw arguments.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
### 10. **Iteration Counter Misplaced** ✅
|
|
203
|
+
**File:** `src/iteration-strategy.ts`
|
|
204
|
+
|
|
205
|
+
**Problem:** Counter incremented per phase instead of per iteration.
|
|
206
|
+
|
|
207
|
+
**Fix:** Moved `incrementIteration()` inside the iteration loop.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## 🟠 Medium Priority Issues Fixed
|
|
212
|
+
|
|
213
|
+
### 11. **FIFO Compression O(n*m) Complexity** ✅
|
|
214
|
+
**File:** `src/token-budget.ts`
|
|
215
|
+
|
|
216
|
+
**Problem:** Using `includes()` on array is O(n*m) for large conversations.
|
|
217
|
+
|
|
218
|
+
**Fix:** Use `Set` for O(1) lookups, reducing to O(n).
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
### 12. **Overly Aggressive Similar Content Detection** ✅
|
|
223
|
+
**File:** `src/context-manager.ts`
|
|
224
|
+
|
|
225
|
+
**Problem:** "Hello" and "Hello world" considered duplicates.
|
|
226
|
+
|
|
227
|
+
**Fix:** Added similarity threshold (default 90%) for substring matching.
|
|
228
|
+
|
|
229
|
+
**After:**
|
|
230
|
+
```typescript
|
|
231
|
+
hasSimilarContent(content: string, similarityThreshold: number = 0.9): boolean {
|
|
232
|
+
const lengthRatio = shorter.length / longer.length;
|
|
233
|
+
if (lengthRatio >= similarityThreshold) {
|
|
234
|
+
if (longer.includes(shorter)) {
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
### 13. **Duplicate Context Without IDs** ✅
|
|
244
|
+
**File:** `src/context-manager.ts`
|
|
245
|
+
|
|
246
|
+
**Problem:** Same content tracked multiple times if no ID provided.
|
|
247
|
+
|
|
248
|
+
**Fix:** Check content hash before tracking items without IDs.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
### 14. **Tool Category Filter Edge Case** ✅
|
|
253
|
+
**File:** `src/recipes.ts`
|
|
254
|
+
|
|
255
|
+
**Problem:** Tools without category could match empty string in filter array.
|
|
256
|
+
|
|
257
|
+
**Fix:** Added explicit check for truthy `tool.category`.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
### 15. **Circuit Breaker for Failing Tools** ✅
|
|
262
|
+
**File:** `src/iteration-strategy.ts`
|
|
263
|
+
|
|
264
|
+
**Problem:** No protection against repeatedly calling broken tools.
|
|
265
|
+
|
|
266
|
+
**Fix:** Added circuit breaker with configurable threshold (default: 3 consecutive failures).
|
|
267
|
+
|
|
268
|
+
**Features:**
|
|
269
|
+
- Tracks consecutive failures per tool
|
|
270
|
+
- Configurable via `maxConsecutiveToolFailures` in phase config
|
|
271
|
+
- Resets counter on successful execution
|
|
272
|
+
- Logs circuit breaker triggers
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
### 16. **Generic Parser Error Message** ✅
|
|
277
|
+
**File:** `src/parser.ts`
|
|
278
|
+
|
|
279
|
+
**Problem:** Error said "instructions" but parser is used for all content types.
|
|
280
|
+
|
|
281
|
+
**Fix:** Changed to generic "content" in error message.
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
### 17. **Override Array Mutation** ✅
|
|
286
|
+
**File:** `src/override.ts`
|
|
287
|
+
|
|
288
|
+
**Problem:** Mutating `appends` array with `.reverse()`.
|
|
289
|
+
|
|
290
|
+
**Fix:** Create copy before reversing: `[...appends].reverse()`.
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
### 18. **Type Assertion Hack in Loader** ✅
|
|
295
|
+
**File:** `src/loader.ts`
|
|
296
|
+
|
|
297
|
+
**Problem:** Double cast `as unknown as T` circumventing type system.
|
|
298
|
+
|
|
299
|
+
**Fix:** Removed unnecessary cast - `Section.add()` correctly accepts `Section<T>`.
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
### 19. **Ignore Pattern Only Tests Filename** ✅
|
|
304
|
+
**File:** `src/loader.ts`
|
|
305
|
+
|
|
306
|
+
**Problem:** Regex patterns only tested against filename, not full path.
|
|
307
|
+
|
|
308
|
+
**Fix:** Test against both filename and full path for flexibility.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## New Features Added
|
|
313
|
+
|
|
314
|
+
### Model Configuration System
|
|
315
|
+
|
|
316
|
+
Created a comprehensive, user-configurable model system:
|
|
317
|
+
|
|
318
|
+
**File:** `src/model-config.ts`
|
|
319
|
+
|
|
320
|
+
**Exports:**
|
|
321
|
+
- `ModelRegistry` - Main registry class
|
|
322
|
+
- `getModelRegistry()` - Get global instance
|
|
323
|
+
- `configureModel()` - Register custom models
|
|
324
|
+
- `getPersonaRole()` - Get role for model
|
|
325
|
+
- `getEncoding()` - Get tokenizer encoding
|
|
326
|
+
- `supportsToolCalls()` - Check tool support
|
|
327
|
+
- `getModelFamily()` - Get model family
|
|
328
|
+
|
|
329
|
+
**Default Configurations:**
|
|
330
|
+
- GPT-4 family (uses 'system' role)
|
|
331
|
+
- O-series models (uses 'developer' role)
|
|
332
|
+
- Claude family (uses 'system' role)
|
|
333
|
+
- Default fallback for unknown models
|
|
334
|
+
|
|
335
|
+
**Benefits:**
|
|
336
|
+
- No more hardcoded model names
|
|
337
|
+
- Easy to add new models without code changes
|
|
338
|
+
- Pattern-based matching (e.g., `/^o\d+/` matches o1, o2, o3, etc.)
|
|
339
|
+
- User-extensible at runtime
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## Testing Recommendations
|
|
344
|
+
|
|
345
|
+
1. **Memory Leak Test:** Run long conversation with many compressions, monitor memory
|
|
346
|
+
2. **Context Injection Test:** Inject multiple items, verify position tracking
|
|
347
|
+
3. **Clone Test:** Clone conversation, modify tool_calls, verify no cross-contamination
|
|
348
|
+
4. **Invalid JSON Test:** Send malformed tool arguments, verify graceful error handling
|
|
349
|
+
5. **Circuit Breaker Test:** Configure tool to fail repeatedly, verify circuit breaker triggers
|
|
350
|
+
6. **Model Registry Test:** Register custom model, verify correct role/encoding selection
|
|
351
|
+
7. **JSONL Race Test:** Add many messages rapidly, verify file integrity
|
|
352
|
+
8. **Performance Test:** Compress large conversations (1000+ messages), verify Set optimization
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## Breaking Changes
|
|
357
|
+
|
|
358
|
+
⚠️ **Minor Breaking Change in Recipe API:**
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
// OLD
|
|
362
|
+
builder.executeWith(llm, strategy, tokenBudget)
|
|
363
|
+
|
|
364
|
+
// NEW
|
|
365
|
+
builder.executeWith(llm, strategy, model, tokenBudget)
|
|
366
|
+
// OR use default
|
|
367
|
+
builder.executeWith(llm, strategy) // defaults to 'gpt-4o'
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Migration Guide
|
|
373
|
+
|
|
374
|
+
### For Custom Model Support
|
|
375
|
+
|
|
376
|
+
**Before:** Had to modify source code to add new models
|
|
377
|
+
|
|
378
|
+
**After:** Configure at runtime:
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
import { configureModel } from 'riotprompt';
|
|
382
|
+
|
|
383
|
+
// Add new model family
|
|
384
|
+
configureModel({
|
|
385
|
+
pattern: /^my-model/i,
|
|
386
|
+
personaRole: 'system',
|
|
387
|
+
encoding: 'gpt-4o',
|
|
388
|
+
supportsToolCalls: true,
|
|
389
|
+
family: 'my-family'
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
// Add specific override
|
|
393
|
+
configureModel({
|
|
394
|
+
exactMatch: 'my-model-v2-special',
|
|
395
|
+
personaRole: 'developer',
|
|
396
|
+
encoding: 'cl100k_base'
|
|
397
|
+
});
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
## Files Modified
|
|
403
|
+
|
|
404
|
+
1. `src/model-config.ts` (NEW)
|
|
405
|
+
2. `src/chat.ts`
|
|
406
|
+
3. `src/conversation.ts`
|
|
407
|
+
4. `src/token-budget.ts`
|
|
408
|
+
5. `src/iteration-strategy.ts`
|
|
409
|
+
6. `src/recipes.ts`
|
|
410
|
+
7. `src/conversation-logger.ts`
|
|
411
|
+
8. `src/context-manager.ts`
|
|
412
|
+
9. `src/items/section.ts`
|
|
413
|
+
10. `src/parser.ts`
|
|
414
|
+
11. `src/loader.ts`
|
|
415
|
+
12. `src/override.ts`
|
|
416
|
+
13. `src/message-builder.ts`
|
|
417
|
+
14. `src/riotprompt.ts`
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Next Steps
|
|
422
|
+
|
|
423
|
+
1. ✅ All critical issues fixed
|
|
424
|
+
2. ✅ All high priority issues fixed
|
|
425
|
+
3. ✅ All medium priority issues fixed
|
|
426
|
+
4. ✅ No linting errors
|
|
427
|
+
5. ⏭️ Run test suite to verify fixes
|
|
428
|
+
6. ⏭️ Update documentation for model configuration system
|
|
429
|
+
7. ⏭️ Consider adding unit tests for circuit breaker
|
|
430
|
+
8. ⏭️ Performance test compression optimization
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
**Review completed:** December 27, 2025
|
|
435
|
+
**Total fixes applied:** 19
|
|
436
|
+
**Status:** ✅ All issues resolved
|
|
437
|
+
|
package/dist/chat.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type Role = "user" | "assistant" | "system" | "developer";
|
|
2
|
-
export type Model =
|
|
2
|
+
export type Model = string;
|
|
3
3
|
export interface Message {
|
|
4
4
|
role: Role;
|
|
5
5
|
content: string | string[];
|
package/dist/chat.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getPersonaRole as getPersonaRole$1 } from './model-config.js';
|
|
2
2
|
|
|
3
3
|
const getPersonaRole = (model)=>{
|
|
4
|
-
|
|
5
|
-
return "system";
|
|
6
|
-
}
|
|
7
|
-
return DEFAULT_PERSONA_ROLE;
|
|
4
|
+
return getPersonaRole$1(model);
|
|
8
5
|
};
|
|
9
6
|
const createRequest = (model)=>{
|
|
10
7
|
const messages = [];
|
package/dist/chat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.js","sources":["../src/chat.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"chat.js","sources":["../src/chat.ts"],"sourcesContent":["import { getPersonaRole as getPersonaRoleFromRegistry } from \"./model-config\";\n\nexport type Role = \"user\" | \"assistant\" | \"system\" | \"developer\";\n\n// Model is now a flexible string type\nexport type Model = string;\n\nexport interface Message {\n role: Role;\n content: string | string[];\n name?: string;\n}\n\nexport interface Request {\n messages: Message[];\n model: Model;\n\n addMessage(message: Message): void;\n}\n\nexport const getPersonaRole = (model: Model): Role => {\n return getPersonaRoleFromRegistry(model);\n}\n\nexport const createRequest = (model: Model): Request => {\n const messages: Message[] = [];\n\n return {\n model,\n messages,\n addMessage: (message: Message) => {\n messages.push(message);\n }\n }\n}\n"],"names":["getPersonaRole","model","getPersonaRoleFromRegistry","createRequest","messages","addMessage","message","push"],"mappings":";;AAoBO,MAAMA,iBAAiB,CAACC,KAAAA,GAAAA;AAC3B,IAAA,OAAOC,gBAAAA,CAA2BD,KAAAA,CAAAA;AACtC;AAEO,MAAME,gBAAgB,CAACF,KAAAA,GAAAA;AAC1B,IAAA,MAAMG,WAAsB,EAAE;IAE9B,OAAO;AACHH,QAAAA,KAAAA;AACAG,QAAAA,QAAAA;AACAC,QAAAA,UAAAA,EAAY,CAACC,OAAAA,GAAAA;AACTF,YAAAA,QAAAA,CAASG,IAAI,CAACD,OAAAA,CAAAA;AAClB,QAAA;AACJ,KAAA;AACJ;;;;"}
|
package/dist/constants.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const DEFAULT_CHARACTER_ENCODING = "utf8";
|
|
2
2
|
const LIBRARY_NAME = "riotprompt";
|
|
3
|
-
const DEFAULT_PERSONA_ROLE = "developer";
|
|
4
3
|
const DEFAULT_IGNORE_PATTERNS = [
|
|
5
4
|
"^\\..*",
|
|
6
5
|
"\\.(jpg|jpeg|png|gif|bmp|svg|webp|ico)$",
|
|
@@ -19,5 +18,5 @@ const DEFAULT_FORMAT_OPTIONS = {
|
|
|
19
18
|
sectionDepth: 0
|
|
20
19
|
};
|
|
21
20
|
|
|
22
|
-
export { DEFAULT_CHARACTER_ENCODING, DEFAULT_FORMAT_OPTIONS, DEFAULT_IGNORE_PATTERNS,
|
|
21
|
+
export { DEFAULT_CHARACTER_ENCODING, DEFAULT_FORMAT_OPTIONS, DEFAULT_IGNORE_PATTERNS, DEFAULT_SECTION_INDENTATION, DEFAULT_SECTION_SEPARATOR, DEFAULT_SECTION_TITLE_PROPERTY, LIBRARY_NAME };
|
|
23
22
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sources":["../src/constants.ts"],"sourcesContent":["import { SectionSeparator } from \"formatter\";\n\nimport { FormatOptions } from \"formatter\";\n\nexport const DEFAULT_CHARACTER_ENCODING = \"utf8\";\nexport const LIBRARY_NAME = \"riotprompt\";\n\nexport const DEFAULT_PERSONA_ROLE = \"developer\";\n\nexport const DEFAULT_INSTRUCTIONS_AREA_TITLE = \"Instructions\";\nexport const DEFAULT_CONTENTS_AREA_TITLE = \"Contents\";\nexport const DEFAULT_CONTEXT_AREA_TITLE = \"Context\";\n\nexport const DEFAULT_IGNORE_PATTERNS: string[] = [\n \"^\\\\..*\", // Hidden files (e.g., .git, .DS_Store)\n \"\\\\.(jpg|jpeg|png|gif|bmp|svg|webp|ico)$\", // Image files\n \"\\\\.(mp3|wav|ogg|aac|flac)$\", // Audio files\n \"\\\\.(mp4|mov|avi|mkv|webm)$\", // Video files\n \"\\\\.(pdf|doc|docx|xls|xlsx|ppt|pptx)$\", // Document files\n \"\\\\.(zip|tar|gz|rar|7z)$\" // Compressed files\n];\n\nexport const DEFAULT_SECTION_SEPARATOR: SectionSeparator = \"tag\";\nexport const DEFAULT_SECTION_INDENTATION = true;\nexport const DEFAULT_SECTION_TAG = \"section\";\nexport const DEFAULT_SECTION_TITLE_PROPERTY = \"title\";\n\nexport const DEFAULT_FORMAT_OPTIONS: FormatOptions = {\n sectionSeparator: DEFAULT_SECTION_SEPARATOR,\n sectionIndentation: DEFAULT_SECTION_INDENTATION,\n sectionTitleProperty: DEFAULT_SECTION_TITLE_PROPERTY,\n sectionDepth: 0,\n}\n"],"names":["DEFAULT_CHARACTER_ENCODING","LIBRARY_NAME","
|
|
1
|
+
{"version":3,"file":"constants.js","sources":["../src/constants.ts"],"sourcesContent":["import { SectionSeparator } from \"formatter\";\n\nimport { FormatOptions } from \"formatter\";\n\nexport const DEFAULT_CHARACTER_ENCODING = \"utf8\";\nexport const LIBRARY_NAME = \"riotprompt\";\n\nexport const DEFAULT_PERSONA_ROLE = \"developer\";\n\nexport const DEFAULT_INSTRUCTIONS_AREA_TITLE = \"Instructions\";\nexport const DEFAULT_CONTENTS_AREA_TITLE = \"Contents\";\nexport const DEFAULT_CONTEXT_AREA_TITLE = \"Context\";\n\nexport const DEFAULT_IGNORE_PATTERNS: string[] = [\n \"^\\\\..*\", // Hidden files (e.g., .git, .DS_Store)\n \"\\\\.(jpg|jpeg|png|gif|bmp|svg|webp|ico)$\", // Image files\n \"\\\\.(mp3|wav|ogg|aac|flac)$\", // Audio files\n \"\\\\.(mp4|mov|avi|mkv|webm)$\", // Video files\n \"\\\\.(pdf|doc|docx|xls|xlsx|ppt|pptx)$\", // Document files\n \"\\\\.(zip|tar|gz|rar|7z)$\" // Compressed files\n];\n\nexport const DEFAULT_SECTION_SEPARATOR: SectionSeparator = \"tag\";\nexport const DEFAULT_SECTION_INDENTATION = true;\nexport const DEFAULT_SECTION_TAG = \"section\";\nexport const DEFAULT_SECTION_TITLE_PROPERTY = \"title\";\n\nexport const DEFAULT_FORMAT_OPTIONS: FormatOptions = {\n sectionSeparator: DEFAULT_SECTION_SEPARATOR,\n sectionIndentation: DEFAULT_SECTION_INDENTATION,\n sectionTitleProperty: DEFAULT_SECTION_TITLE_PROPERTY,\n sectionDepth: 0,\n}\n"],"names":["DEFAULT_CHARACTER_ENCODING","LIBRARY_NAME","DEFAULT_IGNORE_PATTERNS","DEFAULT_SECTION_SEPARATOR","DEFAULT_SECTION_INDENTATION","DEFAULT_SECTION_TITLE_PROPERTY","DEFAULT_FORMAT_OPTIONS","sectionSeparator","sectionIndentation","sectionTitleProperty","sectionDepth"],"mappings":"AAIO,MAAMA,6BAA6B;AACnC,MAAMC,eAAe;MAQfC,uBAAAA,GAAoC;AAC7C,IAAA,QAAA;AACA,IAAA,yCAAA;AACA,IAAA,4BAAA;AACA,IAAA,4BAAA;AACA,IAAA,sCAAA;AACA,IAAA,yBAAA;;AAGG,MAAMC,4BAA8C;AACpD,MAAMC,8BAA8B;AAEpC,MAAMC,iCAAiC;MAEjCC,sBAAAA,GAAwC;IACjDC,gBAAAA,EAAkBJ,yBAAAA;IAClBK,kBAAAA,EAAoBJ,2BAAAA;IACpBK,oBAAAA,EAAsBJ,8BAAAA;IACtBK,YAAAA,EAAc;AAClB;;;;"}
|
|
@@ -68,7 +68,7 @@ export declare class ContextManager {
|
|
|
68
68
|
private logger;
|
|
69
69
|
constructor(logger?: any);
|
|
70
70
|
/**
|
|
71
|
-
* Track a context item
|
|
71
|
+
* Track a context item (with deduplication by content hash for items without ID)
|
|
72
72
|
*/
|
|
73
73
|
track(item: DynamicContentItem, position: number): void;
|
|
74
74
|
/**
|
|
@@ -81,8 +81,9 @@ export declare class ContextManager {
|
|
|
81
81
|
hasContentHash(content: string): boolean;
|
|
82
82
|
/**
|
|
83
83
|
* Check if similar content exists (fuzzy match)
|
|
84
|
+
* Uses similarity threshold to avoid overly aggressive deduplication
|
|
84
85
|
*/
|
|
85
|
-
hasSimilarContent(content: string): boolean;
|
|
86
|
+
hasSimilarContent(content: string, similarityThreshold?: number): boolean;
|
|
86
87
|
/**
|
|
87
88
|
* Get context item by ID
|
|
88
89
|
*/
|
package/dist/context-manager.js
CHANGED
|
@@ -46,10 +46,17 @@ function _define_property(obj, key, value) {
|
|
|
46
46
|
* ```
|
|
47
47
|
*/ class ContextManager {
|
|
48
48
|
/**
|
|
49
|
-
* Track a context item
|
|
49
|
+
* Track a context item (with deduplication by content hash for items without ID)
|
|
50
50
|
*/ track(item, position) {
|
|
51
|
-
const id = item.id || this.generateId();
|
|
52
51
|
const hash = this.hashContent(item.content);
|
|
52
|
+
// If item has no ID and we already have this content hash, skip tracking
|
|
53
|
+
if (!item.id && this.hashes.has(hash)) {
|
|
54
|
+
this.logger.debug('Skipping duplicate context item by hash', {
|
|
55
|
+
hash
|
|
56
|
+
});
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const id = item.id || this.generateId();
|
|
53
60
|
const trackedItem = {
|
|
54
61
|
...item,
|
|
55
62
|
id,
|
|
@@ -80,7 +87,16 @@ function _define_property(obj, key, value) {
|
|
|
80
87
|
}
|
|
81
88
|
/**
|
|
82
89
|
* Check if similar content exists (fuzzy match)
|
|
83
|
-
|
|
90
|
+
* Uses similarity threshold to avoid overly aggressive deduplication
|
|
91
|
+
*/ hasSimilarContent(content, similarityThreshold = 0.9) {
|
|
92
|
+
// Warn if checking against a large number of items (performance consideration)
|
|
93
|
+
const MAX_ITEMS_WARNING = 1000;
|
|
94
|
+
if (this.items.size > MAX_ITEMS_WARNING) {
|
|
95
|
+
this.logger.warn('Large number of context items, similarity check may be slow', {
|
|
96
|
+
count: this.items.size,
|
|
97
|
+
threshold: MAX_ITEMS_WARNING
|
|
98
|
+
});
|
|
99
|
+
}
|
|
84
100
|
const normalized = this.normalizeContent(content);
|
|
85
101
|
for (const item of this.items.values()){
|
|
86
102
|
const itemNormalized = this.normalizeContent(item.content || '');
|
|
@@ -88,9 +104,16 @@ function _define_property(obj, key, value) {
|
|
|
88
104
|
if (normalized === itemNormalized) {
|
|
89
105
|
return true;
|
|
90
106
|
}
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
|
|
107
|
+
// Calculate similarity ratio (Jaccard-like)
|
|
108
|
+
const longer = normalized.length > itemNormalized.length ? normalized : itemNormalized;
|
|
109
|
+
const shorter = normalized.length <= itemNormalized.length ? normalized : itemNormalized;
|
|
110
|
+
// Only consider substring match if the shorter is at least 90% of longer
|
|
111
|
+
const lengthRatio = shorter.length / longer.length;
|
|
112
|
+
if (lengthRatio >= similarityThreshold) {
|
|
113
|
+
// Check if one is contained in the other
|
|
114
|
+
if (longer.includes(shorter)) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
94
117
|
}
|
|
95
118
|
}
|
|
96
119
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-manager.js","sources":["../src/context-manager.ts"],"sourcesContent":["import crypto from 'crypto';\nimport { DEFAULT_LOGGER, wrapLogger } from \"./logger\";\n\n// ===== TYPE DEFINITIONS =====\n\n/**\n * Dynamic content item with enhanced tracking and lifecycle\n */\nexport interface DynamicContentItem {\n content: string;\n title?: string;\n weight?: number;\n\n // Unique identifier for deduplication\n id?: string;\n\n // Category for grouping\n category?: string;\n\n // Source of context\n source?: string;\n\n // Priority level\n priority?: 'high' | 'medium' | 'low';\n\n // Timestamp\n timestamp?: Date;\n}\n\n/**\n * Tracked context item with metadata\n */\nexport interface TrackedContextItem extends DynamicContentItem {\n id: string;\n hash: string;\n position: number;\n injectedAt: Date;\n}\n\n/**\n * Context statistics\n */\nexport interface ContextStats {\n totalItems: number;\n byCategory: Map<string, number>;\n byPriority: Map<string, number>;\n bySource: Map<string, number>;\n oldestTimestamp?: Date;\n newestTimestamp?: Date;\n}\n\n/**\n * ContextManager tracks and manages dynamically injected context.\n *\n * Features:\n * - Track all injected context with metadata\n * - Deduplication by ID, hash, or content\n * - Category-based organization\n * - Query context state\n * - Context statistics\n *\n * @example\n * ```typescript\n * const manager = new ContextManager();\n *\n * // Track injected context\n * manager.track({\n * id: 'file:main.ts',\n * content: fileContent,\n * title: 'Main File',\n * category: 'source-code'\n * }, 5);\n *\n * // Check for duplicates\n * if (manager.hasContext('file:main.ts')) {\n * console.log('Already provided');\n * }\n *\n * // Query by category\n * const sourceFiles = manager.getByCategory('source-code');\n * ```\n */\nexport class ContextManager {\n private items: Map<string, TrackedContextItem>;\n private hashes: Set<string>;\n private logger: any;\n\n constructor(logger?: any) {\n this.items = new Map();\n this.hashes = new Set();\n this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'ContextManager');\n }\n\n /**\n * Track a context item\n */\n track(item: DynamicContentItem, position: number): void {\n const id = item.id || this.generateId();\n const hash = this.hashContent(item.content);\n\n const trackedItem: TrackedContextItem = {\n ...item,\n id,\n hash,\n position,\n injectedAt: new Date(),\n timestamp: item.timestamp || new Date(),\n priority: item.priority || 'medium',\n };\n\n this.items.set(id, trackedItem);\n this.hashes.add(hash);\n\n this.logger.debug('Tracked context item', { id, category: item.category, position });\n }\n\n /**\n * Check if context with given ID exists\n */\n hasContext(id: string): boolean {\n return this.items.has(id);\n }\n\n /**\n * Check if content with given hash exists\n */\n hasContentHash(content: string): boolean {\n const hash = this.hashContent(content);\n return this.hashes.has(hash);\n }\n\n /**\n * Check if similar content exists (fuzzy match)\n */\n hasSimilarContent(content: string): boolean {\n const normalized = this.normalizeContent(content);\n\n for (const item of this.items.values()) {\n const itemNormalized = this.normalizeContent(item.content || '');\n\n // Exact match\n if (normalized === itemNormalized) {\n return true;\n }\n\n // Substring match (one contains the other)\n if (normalized.includes(itemNormalized) || itemNormalized.includes(normalized)) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Get context item by ID\n */\n get(id: string): TrackedContextItem | undefined {\n return this.items.get(id);\n }\n\n /**\n * Get all tracked context items\n */\n getAll(): TrackedContextItem[] {\n return Array.from(this.items.values());\n }\n\n /**\n * Get context items by category\n */\n getByCategory(category: string): TrackedContextItem[] {\n return this.getAll().filter(item => item.category === category);\n }\n\n /**\n * Get context items by priority\n */\n getByPriority(priority: 'high' | 'medium' | 'low'): TrackedContextItem[] {\n return this.getAll().filter(item => item.priority === priority);\n }\n\n /**\n * Get context items by source\n */\n getBySource(source: string): TrackedContextItem[] {\n return this.getAll().filter(item => item.source === source);\n }\n\n /**\n * Get all categories\n */\n getCategories(): string[] {\n const categories = new Set<string>();\n this.items.forEach(item => {\n if (item.category) {\n categories.add(item.category);\n }\n });\n return Array.from(categories).sort();\n }\n\n /**\n * Get context statistics\n */\n getStats(): ContextStats {\n const byCategory = new Map<string, number>();\n const byPriority = new Map<string, number>();\n const bySource = new Map<string, number>();\n let oldestTimestamp: Date | undefined;\n let newestTimestamp: Date | undefined;\n\n this.items.forEach(item => {\n // Category stats\n if (item.category) {\n byCategory.set(item.category, (byCategory.get(item.category) || 0) + 1);\n }\n\n // Priority stats\n const priority = item.priority || 'medium';\n byPriority.set(priority, (byPriority.get(priority) || 0) + 1);\n\n // Source stats\n if (item.source) {\n bySource.set(item.source, (bySource.get(item.source) || 0) + 1);\n }\n\n // Timestamp stats\n if (item.timestamp) {\n if (!oldestTimestamp || item.timestamp < oldestTimestamp) {\n oldestTimestamp = item.timestamp;\n }\n if (!newestTimestamp || item.timestamp > newestTimestamp) {\n newestTimestamp = item.timestamp;\n }\n }\n });\n\n return {\n totalItems: this.items.size,\n byCategory,\n byPriority,\n bySource,\n oldestTimestamp,\n newestTimestamp,\n };\n }\n\n /**\n * Remove context item by ID\n */\n remove(id: string): boolean {\n const item = this.items.get(id);\n if (item) {\n this.items.delete(id);\n this.hashes.delete(item.hash);\n this.logger.debug('Removed context item', { id });\n return true;\n }\n return false;\n }\n\n /**\n * Clear all tracked context\n */\n clear(): void {\n this.items.clear();\n this.hashes.clear();\n this.logger.debug('Cleared all context');\n }\n\n /**\n * Generate unique ID for context item\n */\n private generateId(): string {\n return `ctx-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n }\n\n /**\n * Hash content for deduplication\n */\n private hashContent(content: string): string {\n return crypto\n .createHash('sha256')\n .update(content)\n .digest('hex')\n .substring(0, 16);\n }\n\n /**\n * Normalize content for comparison\n */\n private normalizeContent(content: string): string {\n return content.replace(/\\s+/g, ' ').trim().toLowerCase();\n }\n}\n\nexport default ContextManager;\n\n"],"names":["ContextManager","track","item","position","id","generateId","hash","hashContent","content","trackedItem","injectedAt","Date","timestamp","priority","items","set","hashes","add","logger","debug","category","hasContext","has","hasContentHash","hasSimilarContent","normalized","normalizeContent","values","itemNormalized","includes","get","getAll","Array","from","getByCategory","filter","getByPriority","getBySource","source","getCategories","categories","Set","forEach","sort","getStats","byCategory","Map","byPriority","bySource","oldestTimestamp","newestTimestamp","totalItems","size","remove","delete","clear","now","Math","random","toString","substring","crypto","createHash","update","digest","replace","trim","toLowerCase","wrapLogger","DEFAULT_LOGGER"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"context-manager.js","sources":["../src/context-manager.ts"],"sourcesContent":["import crypto from 'crypto';\nimport { DEFAULT_LOGGER, wrapLogger } from \"./logger\";\n\n// ===== TYPE DEFINITIONS =====\n\n/**\n * Dynamic content item with enhanced tracking and lifecycle\n */\nexport interface DynamicContentItem {\n content: string;\n title?: string;\n weight?: number;\n\n // Unique identifier for deduplication\n id?: string;\n\n // Category for grouping\n category?: string;\n\n // Source of context\n source?: string;\n\n // Priority level\n priority?: 'high' | 'medium' | 'low';\n\n // Timestamp\n timestamp?: Date;\n}\n\n/**\n * Tracked context item with metadata\n */\nexport interface TrackedContextItem extends DynamicContentItem {\n id: string;\n hash: string;\n position: number;\n injectedAt: Date;\n}\n\n/**\n * Context statistics\n */\nexport interface ContextStats {\n totalItems: number;\n byCategory: Map<string, number>;\n byPriority: Map<string, number>;\n bySource: Map<string, number>;\n oldestTimestamp?: Date;\n newestTimestamp?: Date;\n}\n\n/**\n * ContextManager tracks and manages dynamically injected context.\n *\n * Features:\n * - Track all injected context with metadata\n * - Deduplication by ID, hash, or content\n * - Category-based organization\n * - Query context state\n * - Context statistics\n *\n * @example\n * ```typescript\n * const manager = new ContextManager();\n *\n * // Track injected context\n * manager.track({\n * id: 'file:main.ts',\n * content: fileContent,\n * title: 'Main File',\n * category: 'source-code'\n * }, 5);\n *\n * // Check for duplicates\n * if (manager.hasContext('file:main.ts')) {\n * console.log('Already provided');\n * }\n *\n * // Query by category\n * const sourceFiles = manager.getByCategory('source-code');\n * ```\n */\nexport class ContextManager {\n private items: Map<string, TrackedContextItem>;\n private hashes: Set<string>;\n private logger: any;\n\n constructor(logger?: any) {\n this.items = new Map();\n this.hashes = new Set();\n this.logger = wrapLogger(logger || DEFAULT_LOGGER, 'ContextManager');\n }\n\n /**\n * Track a context item (with deduplication by content hash for items without ID)\n */\n track(item: DynamicContentItem, position: number): void {\n const hash = this.hashContent(item.content);\n\n // If item has no ID and we already have this content hash, skip tracking\n if (!item.id && this.hashes.has(hash)) {\n this.logger.debug('Skipping duplicate context item by hash', { hash });\n return;\n }\n\n const id = item.id || this.generateId();\n\n const trackedItem: TrackedContextItem = {\n ...item,\n id,\n hash,\n position,\n injectedAt: new Date(),\n timestamp: item.timestamp || new Date(),\n priority: item.priority || 'medium',\n };\n\n this.items.set(id, trackedItem);\n this.hashes.add(hash);\n\n this.logger.debug('Tracked context item', { id, category: item.category, position });\n }\n\n /**\n * Check if context with given ID exists\n */\n hasContext(id: string): boolean {\n return this.items.has(id);\n }\n\n /**\n * Check if content with given hash exists\n */\n hasContentHash(content: string): boolean {\n const hash = this.hashContent(content);\n return this.hashes.has(hash);\n }\n\n /**\n * Check if similar content exists (fuzzy match)\n * Uses similarity threshold to avoid overly aggressive deduplication\n */\n hasSimilarContent(content: string, similarityThreshold: number = 0.9): boolean {\n // Warn if checking against a large number of items (performance consideration)\n const MAX_ITEMS_WARNING = 1000;\n if (this.items.size > MAX_ITEMS_WARNING) {\n this.logger.warn('Large number of context items, similarity check may be slow', {\n count: this.items.size,\n threshold: MAX_ITEMS_WARNING\n });\n }\n\n const normalized = this.normalizeContent(content);\n\n for (const item of this.items.values()) {\n const itemNormalized = this.normalizeContent(item.content || '');\n\n // Exact match\n if (normalized === itemNormalized) {\n return true;\n }\n\n // Calculate similarity ratio (Jaccard-like)\n const longer = normalized.length > itemNormalized.length ? normalized : itemNormalized;\n const shorter = normalized.length <= itemNormalized.length ? normalized : itemNormalized;\n\n // Only consider substring match if the shorter is at least 90% of longer\n const lengthRatio = shorter.length / longer.length;\n\n if (lengthRatio >= similarityThreshold) {\n // Check if one is contained in the other\n if (longer.includes(shorter)) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * Get context item by ID\n */\n get(id: string): TrackedContextItem | undefined {\n return this.items.get(id);\n }\n\n /**\n * Get all tracked context items\n */\n getAll(): TrackedContextItem[] {\n return Array.from(this.items.values());\n }\n\n /**\n * Get context items by category\n */\n getByCategory(category: string): TrackedContextItem[] {\n return this.getAll().filter(item => item.category === category);\n }\n\n /**\n * Get context items by priority\n */\n getByPriority(priority: 'high' | 'medium' | 'low'): TrackedContextItem[] {\n return this.getAll().filter(item => item.priority === priority);\n }\n\n /**\n * Get context items by source\n */\n getBySource(source: string): TrackedContextItem[] {\n return this.getAll().filter(item => item.source === source);\n }\n\n /**\n * Get all categories\n */\n getCategories(): string[] {\n const categories = new Set<string>();\n this.items.forEach(item => {\n if (item.category) {\n categories.add(item.category);\n }\n });\n return Array.from(categories).sort();\n }\n\n /**\n * Get context statistics\n */\n getStats(): ContextStats {\n const byCategory = new Map<string, number>();\n const byPriority = new Map<string, number>();\n const bySource = new Map<string, number>();\n let oldestTimestamp: Date | undefined;\n let newestTimestamp: Date | undefined;\n\n this.items.forEach(item => {\n // Category stats\n if (item.category) {\n byCategory.set(item.category, (byCategory.get(item.category) || 0) + 1);\n }\n\n // Priority stats\n const priority = item.priority || 'medium';\n byPriority.set(priority, (byPriority.get(priority) || 0) + 1);\n\n // Source stats\n if (item.source) {\n bySource.set(item.source, (bySource.get(item.source) || 0) + 1);\n }\n\n // Timestamp stats\n if (item.timestamp) {\n if (!oldestTimestamp || item.timestamp < oldestTimestamp) {\n oldestTimestamp = item.timestamp;\n }\n if (!newestTimestamp || item.timestamp > newestTimestamp) {\n newestTimestamp = item.timestamp;\n }\n }\n });\n\n return {\n totalItems: this.items.size,\n byCategory,\n byPriority,\n bySource,\n oldestTimestamp,\n newestTimestamp,\n };\n }\n\n /**\n * Remove context item by ID\n */\n remove(id: string): boolean {\n const item = this.items.get(id);\n if (item) {\n this.items.delete(id);\n this.hashes.delete(item.hash);\n this.logger.debug('Removed context item', { id });\n return true;\n }\n return false;\n }\n\n /**\n * Clear all tracked context\n */\n clear(): void {\n this.items.clear();\n this.hashes.clear();\n this.logger.debug('Cleared all context');\n }\n\n /**\n * Generate unique ID for context item\n */\n private generateId(): string {\n return `ctx-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n }\n\n /**\n * Hash content for deduplication\n */\n private hashContent(content: string): string {\n return crypto\n .createHash('sha256')\n .update(content)\n .digest('hex')\n .substring(0, 16);\n }\n\n /**\n * Normalize content for comparison\n */\n private normalizeContent(content: string): string {\n return content.replace(/\\s+/g, ' ').trim().toLowerCase();\n }\n}\n\nexport default ContextManager;\n\n"],"names":["ContextManager","track","item","position","hash","hashContent","content","id","hashes","has","logger","debug","generateId","trackedItem","injectedAt","Date","timestamp","priority","items","set","add","category","hasContext","hasContentHash","hasSimilarContent","similarityThreshold","MAX_ITEMS_WARNING","size","warn","count","threshold","normalized","normalizeContent","values","itemNormalized","longer","length","shorter","lengthRatio","includes","get","getAll","Array","from","getByCategory","filter","getByPriority","getBySource","source","getCategories","categories","Set","forEach","sort","getStats","byCategory","Map","byPriority","bySource","oldestTimestamp","newestTimestamp","totalItems","remove","delete","clear","now","Math","random","toString","substring","crypto","createHash","update","digest","replace","trim","toLowerCase","wrapLogger","DEFAULT_LOGGER"],"mappings":"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"}
|
|
@@ -130,6 +130,8 @@ export declare class ConversationLogger {
|
|
|
130
130
|
private startTime;
|
|
131
131
|
private logger;
|
|
132
132
|
private messageIndex;
|
|
133
|
+
private cachedOutputPath?;
|
|
134
|
+
private writeQueue;
|
|
133
135
|
constructor(config: LogConfig, logger?: any);
|
|
134
136
|
/**
|
|
135
137
|
* Start conversation logging
|
|
@@ -160,7 +162,7 @@ export declare class ConversationLogger {
|
|
|
160
162
|
*/
|
|
161
163
|
private generateId;
|
|
162
164
|
/**
|
|
163
|
-
* Get output file path
|
|
165
|
+
* Get output file path (cached for JSONL to avoid recalculation)
|
|
164
166
|
*/
|
|
165
167
|
private getOutputPath;
|
|
166
168
|
/**
|