@martian-engineering/lossless-claw 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -78,6 +78,35 @@ function ensureSummaryModelColumn(db: DatabaseSync): void {
78
78
  }
79
79
  }
80
80
 
81
+ function ensureCompactionTelemetryColumns(db: DatabaseSync): void {
82
+ const telemetryColumns = db.prepare(`PRAGMA table_info(conversation_compaction_telemetry)`).all() as SummaryColumnInfo[];
83
+ const hasLastLeafCompactionAt = telemetryColumns.some((col) => col.name === "last_leaf_compaction_at");
84
+ const hasTurnsSinceLeafCompaction = telemetryColumns.some((col) => col.name === "turns_since_leaf_compaction");
85
+ const hasTokensAccumulatedSinceLeafCompaction = telemetryColumns.some(
86
+ (col) => col.name === "tokens_accumulated_since_leaf_compaction",
87
+ );
88
+ const hasLastActivityBand = telemetryColumns.some((col) => col.name === "last_activity_band");
89
+
90
+ if (!hasLastLeafCompactionAt) {
91
+ db.exec(`ALTER TABLE conversation_compaction_telemetry ADD COLUMN last_leaf_compaction_at TEXT`);
92
+ }
93
+ if (!hasTurnsSinceLeafCompaction) {
94
+ db.exec(
95
+ `ALTER TABLE conversation_compaction_telemetry ADD COLUMN turns_since_leaf_compaction INTEGER NOT NULL DEFAULT 0`,
96
+ );
97
+ }
98
+ if (!hasTokensAccumulatedSinceLeafCompaction) {
99
+ db.exec(
100
+ `ALTER TABLE conversation_compaction_telemetry ADD COLUMN tokens_accumulated_since_leaf_compaction INTEGER NOT NULL DEFAULT 0`,
101
+ );
102
+ }
103
+ if (!hasLastActivityBand) {
104
+ db.exec(
105
+ `ALTER TABLE conversation_compaction_telemetry ADD COLUMN last_activity_band TEXT NOT NULL DEFAULT 'low' CHECK (last_activity_band IN ('low', 'medium', 'high'))`,
106
+ );
107
+ }
108
+ }
109
+
81
110
  function backfillSummaryDepths(db: DatabaseSync): void {
82
111
  // Leaves are always depth 0, even if legacy rows had malformed values.
83
112
  db.exec(`UPDATE summaries SET depth = 0 WHERE kind = 'leaf'`);
@@ -546,15 +575,39 @@ export function runLcmMigrations(
546
575
  updated_at TEXT NOT NULL DEFAULT (datetime('now'))
547
576
  );
548
577
 
578
+ CREATE TABLE IF NOT EXISTS conversation_compaction_telemetry (
579
+ conversation_id INTEGER PRIMARY KEY REFERENCES conversations(conversation_id) ON DELETE CASCADE,
580
+ last_observed_cache_read INTEGER,
581
+ last_observed_cache_write INTEGER,
582
+ last_observed_cache_hit_at TEXT,
583
+ last_observed_cache_break_at TEXT,
584
+ cache_state TEXT NOT NULL DEFAULT 'unknown'
585
+ CHECK (cache_state IN ('hot', 'cold', 'unknown')),
586
+ retention TEXT,
587
+ last_leaf_compaction_at TEXT,
588
+ turns_since_leaf_compaction INTEGER NOT NULL DEFAULT 0,
589
+ tokens_accumulated_since_leaf_compaction INTEGER NOT NULL DEFAULT 0,
590
+ last_activity_band TEXT NOT NULL DEFAULT 'low'
591
+ CHECK (last_activity_band IN ('low', 'medium', 'high')),
592
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
593
+ );
594
+
549
595
  -- Indexes
550
596
  CREATE INDEX IF NOT EXISTS messages_conv_seq_idx ON messages (conversation_id, seq);
551
597
  CREATE INDEX IF NOT EXISTS summaries_conv_created_idx ON summaries (conversation_id, created_at);
598
+ CREATE INDEX IF NOT EXISTS summary_messages_message_idx ON summary_messages (message_id);
599
+ CREATE INDEX IF NOT EXISTS summary_parents_parent_summary_idx ON summary_parents (parent_summary_id);
552
600
  CREATE INDEX IF NOT EXISTS message_parts_message_idx ON message_parts (message_id);
553
601
  CREATE INDEX IF NOT EXISTS message_parts_type_idx ON message_parts (part_type);
554
602
  CREATE INDEX IF NOT EXISTS context_items_conv_idx ON context_items (conversation_id, ordinal);
555
603
  CREATE INDEX IF NOT EXISTS large_files_conv_idx ON large_files (conversation_id, created_at);
556
604
  CREATE INDEX IF NOT EXISTS bootstrap_state_path_idx
557
605
  ON conversation_bootstrap_state (session_file_path, updated_at);
606
+ CREATE INDEX IF NOT EXISTS compaction_telemetry_state_idx
607
+ ON conversation_compaction_telemetry (cache_state, updated_at);
608
+
609
+ -- Speed up summary_messages lookups by message_id (PK is summary_id,message_id)
610
+ CREATE INDEX IF NOT EXISTS summary_messages_message_idx ON summary_messages (message_id);
558
611
  `);
559
612
 
560
613
  // Forward-compatible conversations migration for existing DBs.
@@ -595,7 +648,11 @@ export function runLcmMigrations(
595
648
  ensureSummaryDepthColumn(db);
596
649
  ensureSummaryMetadataColumns(db);
597
650
  ensureSummaryModelColumn(db);
651
+ ensureCompactionTelemetryColumns(db);
598
652
  backfillSummaryDepths(db);
653
+ // Index on depth — created AFTER backfillSummaryDepths to avoid index
654
+ // maintenance overhead during bulk depth updates on large existing DBs.
655
+ db.exec(`CREATE INDEX IF NOT EXISTS summaries_conv_depth_kind_idx ON summaries (conversation_id, depth, kind)`);
599
656
  backfillSummaryMetadata(db);
600
657
  backfillToolCallColumns(db);
601
658