@vectorize-io/hindsight-openclaw 0.4.14 → 0.4.15
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/dist/index.js +86 -60
- package/dist/types.d.ts +2 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,6 +2,12 @@ import { HindsightEmbedManager } from './embed-manager.js';
|
|
|
2
2
|
import { HindsightClient } from './client.js';
|
|
3
3
|
import { dirname } from 'path';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
|
+
// Debug logging: silent by default, enable with debug: true in plugin config
|
|
6
|
+
let debugEnabled = false;
|
|
7
|
+
const debug = (...args) => {
|
|
8
|
+
if (debugEnabled)
|
|
9
|
+
console.log(...args);
|
|
10
|
+
};
|
|
5
11
|
// Module-level state
|
|
6
12
|
let embedManager = null;
|
|
7
13
|
let client = null;
|
|
@@ -13,6 +19,7 @@ let currentPluginConfig = null;
|
|
|
13
19
|
// Track which banks have had their mission set (to avoid re-setting on every request)
|
|
14
20
|
const banksWithMissionSet = new Set();
|
|
15
21
|
const inflightRecalls = new Map();
|
|
22
|
+
const turnCountBySession = new Map();
|
|
16
23
|
const RECALL_TIMEOUT_MS = 10_000;
|
|
17
24
|
// Cooldown + guard to prevent concurrent reinit attempts
|
|
18
25
|
let lastReinitAttempt = 0;
|
|
@@ -40,7 +47,7 @@ async function lazyReinit() {
|
|
|
40
47
|
isReinitInProgress = false;
|
|
41
48
|
return; // Only external API mode supports lazy reinit
|
|
42
49
|
}
|
|
43
|
-
|
|
50
|
+
debug('[Hindsight] Attempting lazy re-initialization...');
|
|
44
51
|
try {
|
|
45
52
|
await checkExternalApiHealth(externalApi.apiUrl, externalApi.apiToken);
|
|
46
53
|
// Health check passed — set up env vars and create client
|
|
@@ -59,7 +66,7 @@ async function lazyReinit() {
|
|
|
59
66
|
isInitialized = true;
|
|
60
67
|
// Replace the rejected initPromise with a resolved one
|
|
61
68
|
initPromise = Promise.resolve();
|
|
62
|
-
|
|
69
|
+
debug('[Hindsight] ✓ Lazy re-initialization succeeded');
|
|
63
70
|
}
|
|
64
71
|
catch (error) {
|
|
65
72
|
console.warn(`[Hindsight] Lazy re-initialization failed (will retry in ${REINIT_COOLDOWN_MS / 1000}s):`, error instanceof Error ? error.message : error);
|
|
@@ -107,7 +114,7 @@ if (typeof global !== 'undefined') {
|
|
|
107
114
|
try {
|
|
108
115
|
await client.setBankMission(config.bankMission);
|
|
109
116
|
banksWithMissionSet.add(bankId);
|
|
110
|
-
|
|
117
|
+
debug(`[Hindsight] Set mission for new bank: ${bankId}`);
|
|
111
118
|
}
|
|
112
119
|
catch (error) {
|
|
113
120
|
// Log but don't fail - bank mission is not critical
|
|
@@ -319,7 +326,7 @@ async function checkExternalApiHealth(apiUrl, apiToken) {
|
|
|
319
326
|
const retryDelay = 2000;
|
|
320
327
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
321
328
|
try {
|
|
322
|
-
|
|
329
|
+
debug(`[Hindsight] Checking external API health at ${healthUrl}... (attempt ${attempt}/${maxRetries})`);
|
|
323
330
|
const headers = {};
|
|
324
331
|
if (apiToken) {
|
|
325
332
|
headers['Authorization'] = `Bearer ${apiToken}`;
|
|
@@ -329,12 +336,12 @@ async function checkExternalApiHealth(apiUrl, apiToken) {
|
|
|
329
336
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
330
337
|
}
|
|
331
338
|
const data = await response.json();
|
|
332
|
-
|
|
339
|
+
debug(`[Hindsight] External API health: ${JSON.stringify(data)}`);
|
|
333
340
|
return;
|
|
334
341
|
}
|
|
335
342
|
catch (error) {
|
|
336
343
|
if (attempt < maxRetries) {
|
|
337
|
-
|
|
344
|
+
debug(`[Hindsight] Health check attempt ${attempt} failed, retrying in ${retryDelay}ms...`);
|
|
338
345
|
await new Promise(resolve => setTimeout(resolve, retryDelay));
|
|
339
346
|
}
|
|
340
347
|
else {
|
|
@@ -363,37 +370,39 @@ function getPluginConfig(api) {
|
|
|
363
370
|
bankIdPrefix: config.bankIdPrefix,
|
|
364
371
|
excludeProviders: Array.isArray(config.excludeProviders) ? config.excludeProviders : [],
|
|
365
372
|
autoRecall: config.autoRecall !== false, // Default: true (on) — backward compatible
|
|
373
|
+
retainEveryNTurns: config.retainEveryNTurns,
|
|
374
|
+
debug: config.debug ?? false,
|
|
366
375
|
};
|
|
367
376
|
}
|
|
368
377
|
export default function (api) {
|
|
369
378
|
try {
|
|
370
|
-
|
|
371
|
-
// Get plugin config first (needed for LLM detection)
|
|
372
|
-
console.log('[Hindsight] Getting plugin config...');
|
|
379
|
+
debug('[Hindsight] Plugin loading...');
|
|
380
|
+
// Get plugin config first (needed for LLM detection and debug flag)
|
|
373
381
|
const pluginConfig = getPluginConfig(api);
|
|
382
|
+
debugEnabled = pluginConfig.debug ?? false;
|
|
374
383
|
// Store config globally for bank ID derivation in hooks
|
|
375
384
|
currentPluginConfig = pluginConfig;
|
|
376
385
|
// Detect LLM configuration (env vars > plugin config > auto-detect)
|
|
377
|
-
|
|
386
|
+
debug('[Hindsight] Detecting LLM config...');
|
|
378
387
|
const llmConfig = detectLLMConfig(pluginConfig);
|
|
379
388
|
const baseUrlInfo = llmConfig.baseUrl ? `, base URL: ${llmConfig.baseUrl}` : '';
|
|
380
389
|
const modelInfo = llmConfig.model || 'default';
|
|
381
390
|
if (llmConfig.provider === 'ollama') {
|
|
382
|
-
|
|
391
|
+
debug(`[Hindsight] ✓ Using provider: ${llmConfig.provider}, model: ${modelInfo} (${llmConfig.source})`);
|
|
383
392
|
}
|
|
384
393
|
else {
|
|
385
|
-
|
|
394
|
+
debug(`[Hindsight] ✓ Using provider: ${llmConfig.provider}, model: ${modelInfo} (${llmConfig.source}${baseUrlInfo})`);
|
|
386
395
|
}
|
|
387
396
|
if (pluginConfig.bankMission) {
|
|
388
|
-
|
|
397
|
+
debug(`[Hindsight] Custom bank mission configured: "${pluginConfig.bankMission.substring(0, 50)}..."`);
|
|
389
398
|
}
|
|
390
399
|
// Log dynamic bank ID mode
|
|
391
400
|
if (pluginConfig.dynamicBankId) {
|
|
392
401
|
const prefixInfo = pluginConfig.bankIdPrefix ? ` (prefix: ${pluginConfig.bankIdPrefix})` : '';
|
|
393
|
-
|
|
402
|
+
debug(`[Hindsight] ✓ Dynamic bank IDs enabled${prefixInfo} - each channel gets isolated memory`);
|
|
394
403
|
}
|
|
395
404
|
else {
|
|
396
|
-
|
|
405
|
+
debug(`[Hindsight] Dynamic bank IDs disabled - using static bank: ${DEFAULT_BANK_NAME}`);
|
|
397
406
|
}
|
|
398
407
|
// Detect external API mode
|
|
399
408
|
const externalApi = detectExternalApi(pluginConfig);
|
|
@@ -402,64 +411,64 @@ export default function (api) {
|
|
|
402
411
|
if (externalApi.apiUrl) {
|
|
403
412
|
// External API mode - skip local daemon
|
|
404
413
|
usingExternalApi = true;
|
|
405
|
-
|
|
414
|
+
debug(`[Hindsight] ✓ Using external API: ${externalApi.apiUrl}`);
|
|
406
415
|
// Set env vars so CLI commands (uvx hindsight-embed) use external API
|
|
407
416
|
process.env.HINDSIGHT_EMBED_API_URL = externalApi.apiUrl;
|
|
408
417
|
if (externalApi.apiToken) {
|
|
409
418
|
process.env.HINDSIGHT_EMBED_API_TOKEN = externalApi.apiToken;
|
|
410
|
-
|
|
419
|
+
debug('[Hindsight] API token configured');
|
|
411
420
|
}
|
|
412
421
|
}
|
|
413
422
|
else {
|
|
414
|
-
|
|
415
|
-
|
|
423
|
+
debug(`[Hindsight] Daemon idle timeout: ${pluginConfig.daemonIdleTimeout}s (0 = never timeout)`);
|
|
424
|
+
debug(`[Hindsight] API Port: ${apiPort}`);
|
|
416
425
|
}
|
|
417
426
|
// Initialize in background (non-blocking)
|
|
418
|
-
|
|
427
|
+
debug('[Hindsight] Starting initialization in background...');
|
|
419
428
|
initPromise = (async () => {
|
|
420
429
|
try {
|
|
421
430
|
if (usingExternalApi && externalApi.apiUrl) {
|
|
422
431
|
// External API mode - check health, skip daemon startup
|
|
423
|
-
|
|
432
|
+
debug('[Hindsight] External API mode - skipping local daemon...');
|
|
424
433
|
await checkExternalApiHealth(externalApi.apiUrl, externalApi.apiToken);
|
|
425
434
|
// Initialize client with direct HTTP mode
|
|
426
|
-
|
|
435
|
+
debug('[Hindsight] Creating HindsightClient (HTTP mode)...');
|
|
427
436
|
client = new HindsightClient(buildClientOptions(llmConfig, pluginConfig, externalApi));
|
|
428
437
|
// Set default bank (will be overridden per-request when dynamic bank IDs are enabled)
|
|
429
438
|
const defaultBankId = deriveBankId(undefined, pluginConfig);
|
|
430
|
-
|
|
439
|
+
debug(`[Hindsight] Default bank: ${defaultBankId}`);
|
|
431
440
|
client.setBankId(defaultBankId);
|
|
432
441
|
// Note: Bank mission will be set per-bank when dynamic bank IDs are enabled
|
|
433
442
|
// For now, set it on the default bank
|
|
434
443
|
if (pluginConfig.bankMission && !pluginConfig.dynamicBankId) {
|
|
435
|
-
|
|
444
|
+
debug(`[Hindsight] Setting bank mission...`);
|
|
436
445
|
await client.setBankMission(pluginConfig.bankMission);
|
|
437
446
|
}
|
|
438
447
|
isInitialized = true;
|
|
439
|
-
|
|
448
|
+
debug('[Hindsight] ✓ Ready (external API mode)');
|
|
440
449
|
}
|
|
441
450
|
else {
|
|
442
451
|
// Local daemon mode - start hindsight-embed daemon
|
|
443
|
-
|
|
452
|
+
debug('[Hindsight] Creating HindsightEmbedManager...');
|
|
444
453
|
embedManager = new HindsightEmbedManager(apiPort, llmConfig.provider, llmConfig.apiKey, llmConfig.model, llmConfig.baseUrl, pluginConfig.daemonIdleTimeout, pluginConfig.embedVersion, pluginConfig.embedPackagePath);
|
|
445
454
|
// Start the embedded server
|
|
446
|
-
|
|
455
|
+
debug('[Hindsight] Starting embedded server...');
|
|
447
456
|
await embedManager.start();
|
|
448
457
|
// Initialize client (local daemon mode — no apiUrl)
|
|
449
|
-
|
|
458
|
+
debug('[Hindsight] Creating HindsightClient (subprocess mode)...');
|
|
450
459
|
client = new HindsightClient(buildClientOptions(llmConfig, pluginConfig, { apiUrl: null, apiToken: null }));
|
|
451
460
|
// Set default bank (will be overridden per-request when dynamic bank IDs are enabled)
|
|
452
461
|
const defaultBankId = deriveBankId(undefined, pluginConfig);
|
|
453
|
-
|
|
462
|
+
debug(`[Hindsight] Default bank: ${defaultBankId}`);
|
|
454
463
|
client.setBankId(defaultBankId);
|
|
455
464
|
// Note: Bank mission will be set per-bank when dynamic bank IDs are enabled
|
|
456
465
|
// For now, set it on the default bank
|
|
457
466
|
if (pluginConfig.bankMission && !pluginConfig.dynamicBankId) {
|
|
458
|
-
|
|
467
|
+
debug(`[Hindsight] Setting bank mission...`);
|
|
459
468
|
await client.setBankMission(pluginConfig.bankMission);
|
|
460
469
|
}
|
|
461
470
|
isInitialized = true;
|
|
462
|
-
|
|
471
|
+
debug('[Hindsight] ✓ Ready');
|
|
463
472
|
}
|
|
464
473
|
}
|
|
465
474
|
catch (error) {
|
|
@@ -470,11 +479,11 @@ export default function (api) {
|
|
|
470
479
|
// Suppress unhandled rejection — service.start() will await and handle errors
|
|
471
480
|
initPromise.catch(() => { });
|
|
472
481
|
// Register background service for cleanup
|
|
473
|
-
|
|
482
|
+
debug('[Hindsight] Registering service...');
|
|
474
483
|
api.registerService({
|
|
475
484
|
id: 'hindsight-memory',
|
|
476
485
|
async start() {
|
|
477
|
-
|
|
486
|
+
debug('[Hindsight] Service start called...');
|
|
478
487
|
// Wait for background init if still pending
|
|
479
488
|
if (initPromise) {
|
|
480
489
|
try {
|
|
@@ -491,7 +500,7 @@ export default function (api) {
|
|
|
491
500
|
if (externalApi.apiUrl && isInitialized) {
|
|
492
501
|
try {
|
|
493
502
|
await checkExternalApiHealth(externalApi.apiUrl, externalApi.apiToken);
|
|
494
|
-
|
|
503
|
+
debug('[Hindsight] External API is healthy');
|
|
495
504
|
return;
|
|
496
505
|
}
|
|
497
506
|
catch (error) {
|
|
@@ -507,10 +516,10 @@ export default function (api) {
|
|
|
507
516
|
if (embedManager && isInitialized) {
|
|
508
517
|
const healthy = await embedManager.checkHealth();
|
|
509
518
|
if (healthy) {
|
|
510
|
-
|
|
519
|
+
debug('[Hindsight] Daemon is healthy');
|
|
511
520
|
return;
|
|
512
521
|
}
|
|
513
|
-
|
|
522
|
+
debug('[Hindsight] Daemon is not responding - reinitializing...');
|
|
514
523
|
// Reset state for reinitialization
|
|
515
524
|
embedManager = null;
|
|
516
525
|
client = null;
|
|
@@ -519,7 +528,7 @@ export default function (api) {
|
|
|
519
528
|
}
|
|
520
529
|
// Reinitialize if needed (fresh start or recovery)
|
|
521
530
|
if (!isInitialized) {
|
|
522
|
-
|
|
531
|
+
debug('[Hindsight] Reinitializing...');
|
|
523
532
|
const reinitPluginConfig = getPluginConfig(api);
|
|
524
533
|
currentPluginConfig = reinitPluginConfig;
|
|
525
534
|
const llmConfig = detectLLMConfig(reinitPluginConfig);
|
|
@@ -540,7 +549,7 @@ export default function (api) {
|
|
|
540
549
|
await client.setBankMission(reinitPluginConfig.bankMission);
|
|
541
550
|
}
|
|
542
551
|
isInitialized = true;
|
|
543
|
-
|
|
552
|
+
debug('[Hindsight] Reinitialization complete (external API mode)');
|
|
544
553
|
}
|
|
545
554
|
else {
|
|
546
555
|
// Local daemon mode
|
|
@@ -553,13 +562,13 @@ export default function (api) {
|
|
|
553
562
|
await client.setBankMission(reinitPluginConfig.bankMission);
|
|
554
563
|
}
|
|
555
564
|
isInitialized = true;
|
|
556
|
-
|
|
565
|
+
debug('[Hindsight] Reinitialization complete');
|
|
557
566
|
}
|
|
558
567
|
}
|
|
559
568
|
},
|
|
560
569
|
async stop() {
|
|
561
570
|
try {
|
|
562
|
-
|
|
571
|
+
debug('[Hindsight] Service stopping...');
|
|
563
572
|
// Only stop daemon if in local mode
|
|
564
573
|
if (!usingExternalApi && embedManager) {
|
|
565
574
|
await embedManager.stop();
|
|
@@ -567,7 +576,7 @@ export default function (api) {
|
|
|
567
576
|
}
|
|
568
577
|
client = null;
|
|
569
578
|
isInitialized = false;
|
|
570
|
-
|
|
579
|
+
debug('[Hindsight] Service stopped');
|
|
571
580
|
}
|
|
572
581
|
catch (error) {
|
|
573
582
|
console.error('[Hindsight] Service stop error:', error);
|
|
@@ -575,9 +584,9 @@ export default function (api) {
|
|
|
575
584
|
}
|
|
576
585
|
},
|
|
577
586
|
});
|
|
578
|
-
|
|
587
|
+
debug('[Hindsight] Plugin loaded successfully');
|
|
579
588
|
// Register agent hooks for auto-recall and auto-retention
|
|
580
|
-
|
|
589
|
+
debug('[Hindsight] Registering agent hooks...');
|
|
581
590
|
// Store session key and context for retention
|
|
582
591
|
let currentSessionKey;
|
|
583
592
|
let currentAgentContext;
|
|
@@ -592,17 +601,17 @@ export default function (api) {
|
|
|
592
601
|
currentAgentContext = ctx;
|
|
593
602
|
// Check if this provider is excluded
|
|
594
603
|
if (ctx?.messageProvider && pluginConfig.excludeProviders?.includes(ctx.messageProvider)) {
|
|
595
|
-
|
|
604
|
+
debug(`[Hindsight] Skipping recall for excluded provider: ${ctx.messageProvider}`);
|
|
596
605
|
return;
|
|
597
606
|
}
|
|
598
607
|
// Skip auto-recall when disabled (agent has its own recall tool)
|
|
599
608
|
if (!pluginConfig.autoRecall) {
|
|
600
|
-
|
|
609
|
+
debug('[Hindsight] Auto-recall disabled via config, skipping');
|
|
601
610
|
return;
|
|
602
611
|
}
|
|
603
612
|
// Derive bank ID from context
|
|
604
613
|
const bankId = deriveBankId(ctx, pluginConfig);
|
|
605
|
-
|
|
614
|
+
debug(`[Hindsight] before_agent_start - bank: ${bankId}, channel: ${ctx?.messageProvider}/${ctx?.channelId}`);
|
|
606
615
|
// Get the user's latest message for recall — only the raw user text, not the full prompt
|
|
607
616
|
// rawMessage is clean user text; prompt includes envelope, system events, media notes, etc.
|
|
608
617
|
const extracted = extractRecallQuery(event.rawMessage, event.prompt);
|
|
@@ -618,23 +627,23 @@ export default function (api) {
|
|
|
618
627
|
// Wait for client to be ready
|
|
619
628
|
const clientGlobal = global.__hindsightClient;
|
|
620
629
|
if (!clientGlobal) {
|
|
621
|
-
|
|
630
|
+
debug('[Hindsight] Client global not available, skipping auto-recall');
|
|
622
631
|
return;
|
|
623
632
|
}
|
|
624
633
|
await clientGlobal.waitForReady();
|
|
625
634
|
// Get client configured for this context's bank (async to handle mission setup)
|
|
626
635
|
const client = await clientGlobal.getClientForContext(ctx);
|
|
627
636
|
if (!client) {
|
|
628
|
-
|
|
637
|
+
debug('[Hindsight] Client not initialized, skipping auto-recall');
|
|
629
638
|
return;
|
|
630
639
|
}
|
|
631
|
-
|
|
640
|
+
debug(`[Hindsight] Auto-recall for bank ${bankId}, prompt: ${prompt.substring(0, 50)}`);
|
|
632
641
|
// Recall with deduplication: reuse in-flight request for same bank
|
|
633
642
|
const recallKey = bankId;
|
|
634
643
|
const existing = inflightRecalls.get(recallKey);
|
|
635
644
|
let recallPromise;
|
|
636
645
|
if (existing) {
|
|
637
|
-
|
|
646
|
+
debug(`[Hindsight] Reusing in-flight recall for bank ${bankId}`);
|
|
638
647
|
recallPromise = existing;
|
|
639
648
|
}
|
|
640
649
|
else {
|
|
@@ -644,7 +653,7 @@ export default function (api) {
|
|
|
644
653
|
}
|
|
645
654
|
const response = await recallPromise;
|
|
646
655
|
if (!response.results || response.results.length === 0) {
|
|
647
|
-
|
|
656
|
+
debug('[Hindsight] No memories found for auto-recall');
|
|
648
657
|
return;
|
|
649
658
|
}
|
|
650
659
|
// Format memories as JSON with all fields from recall
|
|
@@ -655,7 +664,7 @@ ${memoriesJson}
|
|
|
655
664
|
|
|
656
665
|
User message: ${prompt}
|
|
657
666
|
</hindsight_memories>`;
|
|
658
|
-
|
|
667
|
+
debug(`[Hindsight] Auto-recall: Injecting ${response.results.length} memories from bank ${bankId}`);
|
|
659
668
|
// Inject context before the user message
|
|
660
669
|
return { prependContext: contextMessage };
|
|
661
670
|
}
|
|
@@ -679,15 +688,15 @@ User message: ${prompt}
|
|
|
679
688
|
const effectiveCtx = ctx || currentAgentContext;
|
|
680
689
|
// Check if this provider is excluded
|
|
681
690
|
if (effectiveCtx?.messageProvider && pluginConfig.excludeProviders?.includes(effectiveCtx.messageProvider)) {
|
|
682
|
-
|
|
691
|
+
debug(`[Hindsight] Skipping retain for excluded provider: ${effectiveCtx.messageProvider}`);
|
|
683
692
|
return;
|
|
684
693
|
}
|
|
685
694
|
// Derive bank ID from context
|
|
686
695
|
const bankId = deriveBankId(effectiveCtx, pluginConfig);
|
|
687
|
-
|
|
696
|
+
debug(`[Hindsight Hook] agent_end triggered - bank: ${bankId}`);
|
|
688
697
|
// Check event success and messages
|
|
689
698
|
if (!event.success || !Array.isArray(event.messages) || event.messages.length === 0) {
|
|
690
|
-
|
|
699
|
+
debug('[Hindsight Hook] Skipping: success:', event.success, 'messages:', event.messages?.length);
|
|
691
700
|
return;
|
|
692
701
|
}
|
|
693
702
|
// Wait for client to be ready
|
|
@@ -703,8 +712,25 @@ User message: ${prompt}
|
|
|
703
712
|
console.warn('[Hindsight] Client not initialized, skipping retain');
|
|
704
713
|
return;
|
|
705
714
|
}
|
|
715
|
+
// --- Chunked retention: only retain every Nth turn ---
|
|
716
|
+
const retainEveryN = pluginConfig.retainEveryNTurns ?? 10;
|
|
717
|
+
let messagesToRetain = event.messages;
|
|
718
|
+
if (retainEveryN > 1) {
|
|
719
|
+
const sessionTrackingKey = `${bankId}:${effectiveCtx?.sessionKey || currentSessionKey || 'session'}`;
|
|
720
|
+
const turnCount = (turnCountBySession.get(sessionTrackingKey) || 0) + 1;
|
|
721
|
+
turnCountBySession.set(sessionTrackingKey, turnCount);
|
|
722
|
+
if (turnCount % retainEveryN !== 0) {
|
|
723
|
+
const nextRetain = Math.ceil(turnCount / retainEveryN) * retainEveryN;
|
|
724
|
+
debug(`[Hindsight Hook] Skipping retain (turn ${turnCount}, next at ${nextRetain})`);
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
// Sliding window: N turns of new content + 2-turn overlap for context continuity
|
|
728
|
+
const windowSize = retainEveryN * 2 + 4;
|
|
729
|
+
messagesToRetain = event.messages.slice(-windowSize);
|
|
730
|
+
debug(`[Hindsight Hook] Chunked retain at turn ${turnCount} \u2014 last ${messagesToRetain.length} msgs`);
|
|
731
|
+
}
|
|
706
732
|
// Format messages into a transcript
|
|
707
|
-
const transcript =
|
|
733
|
+
const transcript = messagesToRetain
|
|
708
734
|
.map((msg) => {
|
|
709
735
|
const role = msg.role || 'unknown';
|
|
710
736
|
let content = '';
|
|
@@ -724,7 +750,7 @@ User message: ${prompt}
|
|
|
724
750
|
})
|
|
725
751
|
.join('\n\n');
|
|
726
752
|
if (!transcript.trim() || transcript.length < 10) {
|
|
727
|
-
|
|
753
|
+
debug('[Hindsight Hook] Transcript too short, skipping');
|
|
728
754
|
return;
|
|
729
755
|
}
|
|
730
756
|
// Use unique document ID per conversation (sessionKey + timestamp)
|
|
@@ -736,19 +762,19 @@ User message: ${prompt}
|
|
|
736
762
|
document_id: documentId,
|
|
737
763
|
metadata: {
|
|
738
764
|
retained_at: new Date().toISOString(),
|
|
739
|
-
message_count: String(
|
|
765
|
+
message_count: String(messagesToRetain.length),
|
|
740
766
|
channel_type: effectiveCtx?.messageProvider,
|
|
741
767
|
channel_id: effectiveCtx?.channelId,
|
|
742
768
|
sender_id: effectiveCtx?.senderId,
|
|
743
769
|
},
|
|
744
770
|
});
|
|
745
|
-
|
|
771
|
+
debug(`[Hindsight] Retained ${messagesToRetain.length} messages to bank ${bankId} for session ${documentId}`);
|
|
746
772
|
}
|
|
747
773
|
catch (error) {
|
|
748
774
|
console.error('[Hindsight] Error retaining messages:', error);
|
|
749
775
|
}
|
|
750
776
|
});
|
|
751
|
-
|
|
777
|
+
debug('[Hindsight] Hooks registered');
|
|
752
778
|
}
|
|
753
779
|
catch (error) {
|
|
754
780
|
console.error('[Hindsight] Plugin loading error:', error);
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED