@cortexkit/opencode-magic-context 0.14.1 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/cli/diagnostics.d.ts +38 -5
  2. package/dist/cli/diagnostics.d.ts.map +1 -1
  3. package/dist/cli/logs.d.ts.map +1 -1
  4. package/dist/cli.js +158 -7
  5. package/dist/config/schema/magic-context.d.ts +26 -0
  6. package/dist/config/schema/magic-context.d.ts.map +1 -1
  7. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  8. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  9. package/dist/features/magic-context/storage-tags.d.ts +8 -0
  10. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  11. package/dist/features/magic-context/storage.d.ts +1 -1
  12. package/dist/features/magic-context/storage.d.ts.map +1 -1
  13. package/dist/features/magic-context/types.d.ts +8 -0
  14. package/dist/features/magic-context/types.d.ts.map +1 -1
  15. package/dist/hooks/magic-context/caveman-cleanup.d.ts +86 -0
  16. package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -0
  17. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  18. package/dist/hooks/magic-context/heuristic-cleanup.d.ts +8 -0
  19. package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
  20. package/dist/hooks/magic-context/hook.d.ts +4 -0
  21. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  22. package/dist/hooks/magic-context/nudger.d.ts +1 -1
  23. package/dist/hooks/magic-context/nudger.d.ts.map +1 -1
  24. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  25. package/dist/hooks/magic-context/tag-messages.d.ts +13 -1
  26. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  27. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +9 -0
  28. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  29. package/dist/hooks/magic-context/transform.d.ts +19 -0
  30. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  31. package/dist/index.js +381 -132
  32. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  33. package/dist/shared/error-message.d.ts +30 -0
  34. package/dist/shared/error-message.d.ts.map +1 -1
  35. package/package.json +1 -1
  36. package/src/shared/error-message.test.ts +94 -0
  37. package/src/shared/error-message.ts +112 -0
package/dist/index.js CHANGED
@@ -14215,11 +14215,16 @@ var init_magic_context = __esm(() => {
14215
14215
  enabled: exports_external.boolean().default(false),
14216
14216
  score_threshold: exports_external.number().min(0.3).max(0.95).default(0.55),
14217
14217
  min_prompt_chars: exports_external.number().min(5).max(500).default(20)
14218
- }).default({ enabled: false, score_threshold: 0.55, min_prompt_chars: 20 })
14218
+ }).default({ enabled: false, score_threshold: 0.55, min_prompt_chars: 20 }),
14219
+ caveman_text_compression: exports_external.object({
14220
+ enabled: exports_external.boolean().default(false),
14221
+ min_chars: exports_external.number().min(100).max(1e4).default(500)
14222
+ }).default({ enabled: false, min_chars: 500 })
14219
14223
  }).default({
14220
14224
  temporal_awareness: false,
14221
14225
  git_commit_indexing: { enabled: false, since_days: 365, max_commits: 2000 },
14222
- auto_search: { enabled: false, score_threshold: 0.55, min_prompt_chars: 20 }
14226
+ auto_search: { enabled: false, score_threshold: 0.55, min_prompt_chars: 20 },
14227
+ caveman_text_compression: { enabled: false, min_chars: 500 }
14223
14228
  }),
14224
14229
  memory: exports_external.object({
14225
14230
  enabled: exports_external.boolean().default(true),
@@ -15615,6 +15620,77 @@ var init_data_path = () => {};
15615
15620
  function getErrorMessage(error48) {
15616
15621
  return error48 instanceof Error ? error48.message : String(error48);
15617
15622
  }
15623
+ function readString(value) {
15624
+ if (typeof value === "string" && value.length > 0)
15625
+ return value;
15626
+ if (typeof value === "number")
15627
+ return String(value);
15628
+ return;
15629
+ }
15630
+ function clip(value, max) {
15631
+ if (value.length <= max)
15632
+ return value;
15633
+ return `${value.slice(0, max)}\u2026`;
15634
+ }
15635
+ function describeError(error48) {
15636
+ const stringForm = clip(safeString(error48), 400);
15637
+ if (!(error48 instanceof Error) && !(error48 && typeof error48 === "object")) {
15638
+ return {
15639
+ name: typeof error48,
15640
+ message: "",
15641
+ stringForm,
15642
+ brief: stringForm || "<empty>"
15643
+ };
15644
+ }
15645
+ const obj = error48;
15646
+ const nameFromField = readString(obj.name);
15647
+ const nameFromCtor = error48?.constructor?.name;
15648
+ const name = nameFromField ?? nameFromCtor ?? "Error";
15649
+ const message = readString(obj.message) ?? "";
15650
+ const status = readString(obj.status) ?? readString(obj.statusCode);
15651
+ const code = readString(obj.code);
15652
+ let causeName;
15653
+ const cause = obj.cause;
15654
+ if (cause && typeof cause === "object") {
15655
+ const causeRecord = cause;
15656
+ causeName = readString(causeRecord.name) ?? cause.constructor?.name;
15657
+ }
15658
+ const stack = readString(obj.stack);
15659
+ const stackHead = stack ? stack.split(`
15660
+ `).slice(0, 4).map((l) => l.trim()).filter((l) => l.length > 0).join(" | ") : undefined;
15661
+ const briefParts = [];
15662
+ if (name)
15663
+ briefParts.push(name);
15664
+ if (message)
15665
+ briefParts.push(`message="${clip(message, 200)}"`);
15666
+ if (status)
15667
+ briefParts.push(`status=${status}`);
15668
+ if (code)
15669
+ briefParts.push(`code=${code}`);
15670
+ if (causeName)
15671
+ briefParts.push(`cause=${causeName}`);
15672
+ if (!message && stringForm && stringForm !== name) {
15673
+ briefParts.push(`str="${clip(stringForm, 200)}"`);
15674
+ }
15675
+ const brief = briefParts.join(" ") || stringForm || name;
15676
+ return {
15677
+ name,
15678
+ message,
15679
+ ...status ? { status } : {},
15680
+ ...code ? { code } : {},
15681
+ ...causeName ? { causeName } : {},
15682
+ ...stackHead ? { stackHead } : {},
15683
+ stringForm,
15684
+ brief
15685
+ };
15686
+ }
15687
+ function safeString(value) {
15688
+ try {
15689
+ return String(value);
15690
+ } catch {
15691
+ return "<unstringifiable>";
15692
+ }
15693
+ }
15618
15694
 
15619
15695
  // src/features/magic-context/memory/storage-memory-embeddings.ts
15620
15696
  function isEmbeddingBlob(value) {
@@ -150778,6 +150854,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
150778
150854
  ensureColumn(db, "tags", "drop_mode", "TEXT DEFAULT 'full'");
150779
150855
  ensureColumn(db, "tags", "tool_name", "TEXT");
150780
150856
  ensureColumn(db, "tags", "input_byte_size", "INTEGER DEFAULT 0");
150857
+ ensureColumn(db, "tags", "caveman_depth", "INTEGER DEFAULT 0");
150781
150858
  ensureColumn(db, "session_meta", "system_prompt_tokens", "INTEGER DEFAULT 0");
150782
150859
  ensureColumn(db, "session_meta", "compaction_marker_state", "TEXT DEFAULT ''");
150783
150860
  ensureColumn(db, "session_meta", "key_files", "TEXT DEFAULT ''");
@@ -151183,7 +151260,10 @@ function incrementHistorianFailure(db, sessionId, error48) {
151183
151260
  db.transaction(() => {
151184
151261
  ensureSessionMetaRow(db, sessionId);
151185
151262
  const current = getHistorianFailureState(db, sessionId);
151186
- db.prepare("UPDATE session_meta SET historian_failure_count = ?, historian_last_error = ?, historian_last_failure_at = ? WHERE session_id = ?").run(current.failureCount + 1, error48, Date.now(), sessionId);
151263
+ const nextCount = current.failureCount + 1;
151264
+ db.prepare("UPDATE session_meta SET historian_failure_count = ?, historian_last_error = ?, historian_last_failure_at = ? WHERE session_id = ?").run(nextCount, error48, Date.now(), sessionId);
151265
+ const reason = error48.replace(/\s+/g, " ").trim().slice(0, 300);
151266
+ sessionLog(sessionId, `historian failure recorded: count=${nextCount} reason="${reason}"`);
151187
151267
  })();
151188
151268
  }
151189
151269
  function clearHistorianFailureState(db, sessionId) {
@@ -151267,6 +151347,7 @@ function removeStrippedPlaceholderId(db, sessionId, messageId) {
151267
151347
  return true;
151268
151348
  }
151269
151349
  var init_storage_meta_persisted = __esm(() => {
151350
+ init_logger();
151270
151351
  init_storage_meta_shared();
151271
151352
  });
151272
151353
 
@@ -151502,7 +151583,8 @@ function toTagEntry(row) {
151502
151583
  inputByteSize: row.input_byte_size ?? 0,
151503
151584
  byteSize: row.byte_size,
151504
151585
  reasoningByteSize: row.reasoning_byte_size ?? 0,
151505
- sessionId: row.session_id
151586
+ sessionId: row.session_id,
151587
+ cavemanDepth: typeof row.caveman_depth === "number" && Number.isFinite(row.caveman_depth) ? row.caveman_depth : 0
151506
151588
  };
151507
151589
  }
151508
151590
  function isTagNumberRow(row) {
@@ -151530,6 +151612,9 @@ function updateTagStatus(db, sessionId, tagId, status) {
151530
151612
  function updateTagDropMode(db, sessionId, tagNumber, dropMode) {
151531
151613
  getUpdateTagDropModeStatement(db).run(dropMode, sessionId, tagNumber);
151532
151614
  }
151615
+ function updateCavemanDepth(db, sessionId, tagNumber, depth) {
151616
+ db.prepare("UPDATE tags SET caveman_depth = ? WHERE session_id = ? AND tag_number = ?").run(depth, sessionId, tagNumber);
151617
+ }
151533
151618
  function updateTagMessageId(db, sessionId, tagId, messageId) {
151534
151619
  getUpdateTagMessageIdStatement(db).run(messageId, sessionId, tagId);
151535
151620
  }
@@ -151549,14 +151634,14 @@ function getMaxTagNumberBySession(db, sessionId) {
151549
151634
  return isMaxTagNumberRow(row) ? row.max_tag_number : 0;
151550
151635
  }
151551
151636
  function getTagsBySession(db, sessionId) {
151552
- const rows = db.prepare("SELECT id, message_id, type, status, drop_mode, tool_name, input_byte_size, byte_size, reasoning_byte_size, session_id, tag_number FROM tags WHERE session_id = ? ORDER BY tag_number ASC, id ASC").all(sessionId).filter(isTagRow);
151637
+ const rows = db.prepare("SELECT id, message_id, type, status, drop_mode, tool_name, input_byte_size, byte_size, reasoning_byte_size, session_id, tag_number, caveman_depth FROM tags WHERE session_id = ? ORDER BY tag_number ASC, id ASC").all(sessionId).filter(isTagRow);
151553
151638
  return rows.map(toTagEntry);
151554
151639
  }
151555
151640
  function getTopNBySize(db, sessionId, n) {
151556
151641
  if (n <= 0) {
151557
151642
  return [];
151558
151643
  }
151559
- const rows = db.prepare("SELECT id, message_id, type, status, drop_mode, tool_name, input_byte_size, byte_size, reasoning_byte_size, session_id, tag_number FROM tags WHERE session_id = ? AND status = 'active' ORDER BY byte_size DESC, tag_number ASC LIMIT ?").all(sessionId, n).filter(isTagRow);
151644
+ const rows = db.prepare("SELECT id, message_id, type, status, drop_mode, tool_name, input_byte_size, byte_size, reasoning_byte_size, session_id, tag_number, caveman_depth FROM tags WHERE session_id = ? AND status = 'active' ORDER BY byte_size DESC, tag_number ASC LIMIT ?").all(sessionId, n).filter(isTagRow);
151560
151645
  return rows.map(toTagEntry);
151561
151646
  }
151562
151647
  var insertTagStatements, updateTagStatusStatements, updateTagDropModeStatements, updateTagMessageIdStatements, getTagNumbersByMessageIdStatements, deleteTagsByMessageIdStatements, getMaxTagNumberBySessionStatements;
@@ -152157,14 +152242,12 @@ async function runHistorianPrompt(args) {
152157
152242
  const dumpPath = dumpHistorianResponse(parentSessionId, dumpLabel ?? "historian-response", result);
152158
152243
  return { ok: true, result, dumpPath };
152159
152244
  } catch (modelError) {
152160
- const modelMsg = getErrorMessage(modelError);
152161
- const modelStack = modelError instanceof Error ? modelError.stack : undefined;
152162
- sessionLog(parentSessionId, "compartment agent: historian attempt failed", {
152163
- error: modelMsg,
152164
- promptLength: prompt.length,
152165
- stack: modelStack
152166
- });
152167
- return { ok: false, error: `Historian failed while processing this session: ${modelMsg}` };
152245
+ const desc = describeError(modelError);
152246
+ sessionLog(parentSessionId, `historian prompt failed: ${desc.brief} promptLength=${prompt.length}${desc.stackHead ? ` stackHead="${desc.stackHead}"` : ""}`);
152247
+ return {
152248
+ ok: false,
152249
+ error: `Historian failed while processing this session: ${desc.brief}`
152250
+ };
152168
152251
  } finally {
152169
152252
  if (agentSessionId) {
152170
152253
  await client.session.delete({ path: { id: agentSessionId }, query: { directory: sessionDirectory } }).catch((e) => {
@@ -153529,108 +153612,6 @@ var init_note_nudger = __esm(() => {
153529
153612
  lastDeliveredAt = new Map;
153530
153613
  });
153531
153614
 
153532
- // src/features/magic-context/memory/embedding-backfill.ts
153533
- async function ensureMemoryEmbeddings(args) {
153534
- if (!isEmbeddingEnabled()) {
153535
- return args.existingEmbeddings;
153536
- }
153537
- const missingMemories = args.memories.filter((memory) => !args.existingEmbeddings.has(memory.id));
153538
- if (missingMemories.length === 0) {
153539
- return args.existingEmbeddings;
153540
- }
153541
- try {
153542
- const embeddings = await embedBatch(missingMemories.map((memory) => memory.content));
153543
- const modelId = getEmbeddingModelId();
153544
- const staged = new Map;
153545
- args.db.transaction(() => {
153546
- for (const [index, memory] of missingMemories.entries()) {
153547
- const embedding = embeddings[index];
153548
- if (!embedding) {
153549
- continue;
153550
- }
153551
- saveEmbedding(args.db, memory.id, embedding, modelId);
153552
- staged.set(memory.id, embedding);
153553
- }
153554
- })();
153555
- for (const [id, embedding] of staged) {
153556
- args.existingEmbeddings.set(id, embedding);
153557
- }
153558
- } catch (error48) {
153559
- log("[magic-context] failed to backfill memory embeddings:", error48);
153560
- }
153561
- return args.existingEmbeddings;
153562
- }
153563
- var init_embedding_backfill = __esm(() => {
153564
- init_logger();
153565
- init_embedding();
153566
- init_storage_memory_embeddings();
153567
- });
153568
-
153569
- // src/features/magic-context/memory/promotion.ts
153570
- function isPromotableCategory(category) {
153571
- return PROMOTABLE_CATEGORIES.some((promotableCategory) => promotableCategory === category);
153572
- }
153573
- function resolveExpiresAt(category) {
153574
- const ttl = CATEGORY_DEFAULT_TTL[category];
153575
- return ttl === undefined ? null : Date.now() + ttl;
153576
- }
153577
- function promoteSessionFactsToMemory(db, sessionId, projectPath, facts) {
153578
- for (const fact of facts) {
153579
- if (!isPromotableCategory(fact.category)) {
153580
- continue;
153581
- }
153582
- try {
153583
- const normalizedHash = computeNormalizedHash(fact.content);
153584
- const existingMemory = getMemoryByHash(db, projectPath, fact.category, normalizedHash);
153585
- if (existingMemory) {
153586
- updateMemorySeenCount(db, existingMemory.id);
153587
- continue;
153588
- }
153589
- const memoryInput = {
153590
- projectPath,
153591
- category: fact.category,
153592
- content: fact.content,
153593
- sourceSessionId: sessionId,
153594
- sourceType: "historian",
153595
- expiresAt: resolveExpiresAt(fact.category)
153596
- };
153597
- const memory = insertMemory(db, memoryInput);
153598
- embedAndStoreMemory(db, sessionId, memory.id, memory.content);
153599
- } catch (error48) {
153600
- sessionLog(sessionId, `memory promotion failed for fact "${fact.content.slice(0, 60)}":`, error48);
153601
- }
153602
- }
153603
- }
153604
- async function embedAndStoreMemory(db, sessionId, memoryId, content) {
153605
- try {
153606
- const embedding = await embedText(content);
153607
- if (embedding) {
153608
- saveEmbedding(db, memoryId, embedding, getEmbeddingModelId());
153609
- }
153610
- } catch (error48) {
153611
- sessionLog(sessionId, `memory embedding failed for memory ${memoryId}:`, error48);
153612
- }
153613
- }
153614
- var init_promotion = __esm(() => {
153615
- init_logger();
153616
- init_constants();
153617
- init_embedding();
153618
- init_storage_memory();
153619
- init_storage_memory_embeddings();
153620
- });
153621
- // src/features/magic-context/memory/index.ts
153622
- var init_memory = __esm(() => {
153623
- init_project_identity();
153624
- init_promotion();
153625
- init_constants();
153626
- init_embedding();
153627
- init_embedding_backfill();
153628
- init_embedding_cache();
153629
- init_storage_memory();
153630
- init_storage_memory_embeddings();
153631
- init_storage_memory_fts();
153632
- });
153633
-
153634
153615
  // src/hooks/magic-context/caveman.ts
153635
153616
  function protectRegions(text) {
153636
153617
  const preserved = [];
@@ -153863,6 +153844,108 @@ var init_caveman = __esm(() => {
153863
153844
  };
153864
153845
  });
153865
153846
 
153847
+ // src/features/magic-context/memory/embedding-backfill.ts
153848
+ async function ensureMemoryEmbeddings(args) {
153849
+ if (!isEmbeddingEnabled()) {
153850
+ return args.existingEmbeddings;
153851
+ }
153852
+ const missingMemories = args.memories.filter((memory) => !args.existingEmbeddings.has(memory.id));
153853
+ if (missingMemories.length === 0) {
153854
+ return args.existingEmbeddings;
153855
+ }
153856
+ try {
153857
+ const embeddings = await embedBatch(missingMemories.map((memory) => memory.content));
153858
+ const modelId = getEmbeddingModelId();
153859
+ const staged = new Map;
153860
+ args.db.transaction(() => {
153861
+ for (const [index, memory] of missingMemories.entries()) {
153862
+ const embedding = embeddings[index];
153863
+ if (!embedding) {
153864
+ continue;
153865
+ }
153866
+ saveEmbedding(args.db, memory.id, embedding, modelId);
153867
+ staged.set(memory.id, embedding);
153868
+ }
153869
+ })();
153870
+ for (const [id, embedding] of staged) {
153871
+ args.existingEmbeddings.set(id, embedding);
153872
+ }
153873
+ } catch (error48) {
153874
+ log("[magic-context] failed to backfill memory embeddings:", error48);
153875
+ }
153876
+ return args.existingEmbeddings;
153877
+ }
153878
+ var init_embedding_backfill = __esm(() => {
153879
+ init_logger();
153880
+ init_embedding();
153881
+ init_storage_memory_embeddings();
153882
+ });
153883
+
153884
+ // src/features/magic-context/memory/promotion.ts
153885
+ function isPromotableCategory(category) {
153886
+ return PROMOTABLE_CATEGORIES.some((promotableCategory) => promotableCategory === category);
153887
+ }
153888
+ function resolveExpiresAt(category) {
153889
+ const ttl = CATEGORY_DEFAULT_TTL[category];
153890
+ return ttl === undefined ? null : Date.now() + ttl;
153891
+ }
153892
+ function promoteSessionFactsToMemory(db, sessionId, projectPath, facts) {
153893
+ for (const fact of facts) {
153894
+ if (!isPromotableCategory(fact.category)) {
153895
+ continue;
153896
+ }
153897
+ try {
153898
+ const normalizedHash = computeNormalizedHash(fact.content);
153899
+ const existingMemory = getMemoryByHash(db, projectPath, fact.category, normalizedHash);
153900
+ if (existingMemory) {
153901
+ updateMemorySeenCount(db, existingMemory.id);
153902
+ continue;
153903
+ }
153904
+ const memoryInput = {
153905
+ projectPath,
153906
+ category: fact.category,
153907
+ content: fact.content,
153908
+ sourceSessionId: sessionId,
153909
+ sourceType: "historian",
153910
+ expiresAt: resolveExpiresAt(fact.category)
153911
+ };
153912
+ const memory = insertMemory(db, memoryInput);
153913
+ embedAndStoreMemory(db, sessionId, memory.id, memory.content);
153914
+ } catch (error48) {
153915
+ sessionLog(sessionId, `memory promotion failed for fact "${fact.content.slice(0, 60)}":`, error48);
153916
+ }
153917
+ }
153918
+ }
153919
+ async function embedAndStoreMemory(db, sessionId, memoryId, content) {
153920
+ try {
153921
+ const embedding = await embedText(content);
153922
+ if (embedding) {
153923
+ saveEmbedding(db, memoryId, embedding, getEmbeddingModelId());
153924
+ }
153925
+ } catch (error48) {
153926
+ sessionLog(sessionId, `memory embedding failed for memory ${memoryId}:`, error48);
153927
+ }
153928
+ }
153929
+ var init_promotion = __esm(() => {
153930
+ init_logger();
153931
+ init_constants();
153932
+ init_embedding();
153933
+ init_storage_memory();
153934
+ init_storage_memory_embeddings();
153935
+ });
153936
+ // src/features/magic-context/memory/index.ts
153937
+ var init_memory = __esm(() => {
153938
+ init_project_identity();
153939
+ init_promotion();
153940
+ init_constants();
153941
+ init_embedding();
153942
+ init_embedding_backfill();
153943
+ init_embedding_cache();
153944
+ init_storage_memory();
153945
+ init_storage_memory_embeddings();
153946
+ init_storage_memory_fts();
153947
+ });
153948
+
153866
153949
  // src/hooks/magic-context/compartment-runner-compressor.ts
153867
153950
  function cavemanLevelForDepth(outputDepth) {
153868
153951
  if (outputDepth <= 1)
@@ -154317,6 +154400,7 @@ async function runCompartmentAgent(deps) {
154317
154400
  const priorFacts = existingFacts;
154318
154401
  const existingValidationError = validateStoredCompartments(priorCompartments);
154319
154402
  if (existingValidationError) {
154403
+ sessionLog(sessionId, `historian failure: source=existing-validation reason="${existingValidationError}"`);
154320
154404
  await notifyHistorianIssue(`## Historian alert
154321
154405
 
154322
154406
  Historian skipped this session because existing stored compartments are invalid: ${existingValidationError}
@@ -154335,6 +154419,7 @@ No new compartments or facts were written. Rebuild or clear the broken compartme
154335
154419
  }
154336
154420
  const chunkCoverageError = validateChunkCoverage(chunk);
154337
154421
  if (chunkCoverageError) {
154422
+ sessionLog(sessionId, `historian failure: source=chunk-coverage reason="${chunkCoverageError}" chunkRange=${chunk.startIndex}-${chunk.endIndex}`);
154338
154423
  await notifyHistorianIssue(`## Historian alert
154339
154424
 
154340
154425
  Historian skipped this session because the raw chunk could not be represented safely: ${chunkCoverageError}
@@ -154370,6 +154455,7 @@ ${chunk.text}`);
154370
154455
  twoPass: deps.historianTwoPass
154371
154456
  });
154372
154457
  if (!validatedPass.ok) {
154458
+ sessionLog(sessionId, `historian failure: source=validation reason="${validatedPass.error}" chunkRange=${chunk.startIndex}-${chunk.endIndex} fallbackModel=${deps.fallbackModelId ?? "<none>"} twoPass=${deps.historianTwoPass ? "true" : "false"}`);
154373
154459
  incrementHistorianFailure(db, sessionId, validatedPass.error);
154374
154460
  await notifyHistorianIssue(`## Historian alert
154375
154461
 
@@ -154381,6 +154467,8 @@ No new compartments or facts were written. Check the historian model/output and
154381
154467
  const newCompartments = validatedPass.compartments;
154382
154468
  const lastNewEnd = newCompartments[newCompartments.length - 1]?.endMessage ?? 0;
154383
154469
  if (lastNewEnd + 1 <= offset) {
154470
+ sessionLog(sessionId, `historian failure: source=no-progress reason="historian returned compartments that did not advance past raw message ${offset - 1}" newCompartmentCount=${newCompartments.length} lastNewEnd=${lastNewEnd} priorEnd=${offset - 1}`);
154471
+ incrementHistorianFailure(db, sessionId, `no forward progress beyond raw message ${offset - 1}`);
154384
154472
  await notifyHistorianIssue(`## Historian alert
154385
154473
 
154386
154474
  Historian returned compartments that made no forward progress beyond raw message ${offset - 1}.
@@ -154434,11 +154522,13 @@ No new compartments or facts were written. Check the historian model/output and
154434
154522
  }
154435
154523
  }
154436
154524
  } catch (error48) {
154437
- const msg = getErrorMessage(error48);
154525
+ const desc = describeError(error48);
154526
+ sessionLog(sessionId, `historian failure: source=exception ${desc.brief}${desc.stackHead ? ` stackHead="${desc.stackHead}"` : ""}`);
154438
154527
  if (!issueNotified) {
154528
+ incrementHistorianFailure(db, sessionId, desc.brief);
154439
154529
  await notifyHistorianIssue(`## Historian alert
154440
154530
 
154441
- Historian failed unexpectedly: ${msg}
154531
+ Historian failed unexpectedly: ${desc.brief}
154442
154532
 
154443
154533
  No new compartments or facts were written. Check the historian model/output and try again.`);
154444
154534
  }
@@ -166438,6 +166528,120 @@ init_compartment_storage();
166438
166528
  init_project_identity();
166439
166529
  init_storage();
166440
166530
  init_logger();
166531
+
166532
+ // src/hooks/magic-context/caveman-cleanup.ts
166533
+ init_storage();
166534
+ init_shared();
166535
+ init_caveman();
166536
+ var DEPTH_UNTOUCHED = 0;
166537
+ var DEPTH_LITE = 1;
166538
+ var DEPTH_FULL = 2;
166539
+ var DEPTH_ULTRA = 3;
166540
+ var DEPTH_TO_LEVEL = {
166541
+ [DEPTH_LITE]: "lite",
166542
+ [DEPTH_FULL]: "full",
166543
+ [DEPTH_ULTRA]: "ultra"
166544
+ };
166545
+ function computeTargetDepth(positionIndex, totalEligible) {
166546
+ if (totalEligible <= 0)
166547
+ return DEPTH_UNTOUCHED;
166548
+ const fraction = positionIndex / totalEligible;
166549
+ if (fraction < 0.2)
166550
+ return DEPTH_ULTRA;
166551
+ if (fraction < 0.4)
166552
+ return DEPTH_FULL;
166553
+ if (fraction < 0.6)
166554
+ return DEPTH_LITE;
166555
+ return DEPTH_UNTOUCHED;
166556
+ }
166557
+ function applyCavemanCleanup(sessionId, db, targets, tags, config2) {
166558
+ const result = {
166559
+ compressedToLite: 0,
166560
+ compressedToFull: 0,
166561
+ compressedToUltra: 0
166562
+ };
166563
+ if (!config2.enabled)
166564
+ return result;
166565
+ const maxTag = tags.reduce((max, t) => Math.max(max, t.tagNumber), 0);
166566
+ const protectedCutoff = maxTag - config2.protectedTags;
166567
+ const eligible = tags.filter((tag) => tag.type === "message" && tag.status === "active" && tag.tagNumber <= protectedCutoff && tag.byteSize >= config2.minChars).sort((a, b) => a.tagNumber - b.tagNumber);
166568
+ if (eligible.length === 0)
166569
+ return result;
166570
+ const tagsNeedingCompression = eligible.filter((tag, index) => {
166571
+ const target = targets.get(tag.tagNumber);
166572
+ if (!target || !target.getContent || !target.setContent)
166573
+ return false;
166574
+ const targetDepth = computeTargetDepth(index, eligible.length);
166575
+ return targetDepth > tag.cavemanDepth;
166576
+ });
166577
+ if (tagsNeedingCompression.length === 0)
166578
+ return result;
166579
+ const originalByTag = getSourceContents(db, sessionId, tagsNeedingCompression.map((t) => t.tagNumber));
166580
+ const positionByTag = new Map;
166581
+ for (let i = 0;i < eligible.length; i += 1) {
166582
+ positionByTag.set(eligible[i].tagNumber, i);
166583
+ }
166584
+ db.transaction(() => {
166585
+ for (const tag of tagsNeedingCompression) {
166586
+ const originalText = originalByTag.get(tag.tagNumber);
166587
+ if (typeof originalText !== "string" || originalText.length === 0)
166588
+ continue;
166589
+ const positionIndex = positionByTag.get(tag.tagNumber) ?? 0;
166590
+ const targetDepth = computeTargetDepth(positionIndex, eligible.length);
166591
+ if (targetDepth <= tag.cavemanDepth)
166592
+ continue;
166593
+ const level = DEPTH_TO_LEVEL[targetDepth];
166594
+ if (!level)
166595
+ continue;
166596
+ const compressed = cavemanCompress(originalText, level);
166597
+ if (compressed.length === 0)
166598
+ continue;
166599
+ const target = targets.get(tag.tagNumber);
166600
+ if (!target)
166601
+ continue;
166602
+ target.setContent(compressed);
166603
+ updateCavemanDepth(db, sessionId, tag.tagNumber, targetDepth);
166604
+ if (targetDepth === DEPTH_LITE)
166605
+ result.compressedToLite += 1;
166606
+ else if (targetDepth === DEPTH_FULL)
166607
+ result.compressedToFull += 1;
166608
+ else if (targetDepth === DEPTH_ULTRA)
166609
+ result.compressedToUltra += 1;
166610
+ }
166611
+ })();
166612
+ const total = result.compressedToLite + result.compressedToFull + result.compressedToUltra;
166613
+ if (total > 0) {
166614
+ sessionLog(sessionId, `caveman cleanup: compressed ${total} text tags (lite=${result.compressedToLite}, full=${result.compressedToFull}, ultra=${result.compressedToUltra})`);
166615
+ }
166616
+ return result;
166617
+ }
166618
+ function replayCavemanCompression(sessionId, db, targets, tags) {
166619
+ const compressedTags = tags.filter((tag) => tag.type === "message" && tag.status === "active" && tag.cavemanDepth > 0 && targets.has(tag.tagNumber));
166620
+ if (compressedTags.length === 0)
166621
+ return 0;
166622
+ const originalByTag = getSourceContents(db, sessionId, compressedTags.map((t) => t.tagNumber));
166623
+ let replayed = 0;
166624
+ for (const tag of compressedTags) {
166625
+ const originalText = originalByTag.get(tag.tagNumber);
166626
+ if (typeof originalText !== "string" || originalText.length === 0)
166627
+ continue;
166628
+ const level = DEPTH_TO_LEVEL[tag.cavemanDepth];
166629
+ if (!level)
166630
+ continue;
166631
+ const compressed = cavemanCompress(originalText, level);
166632
+ if (compressed.length === 0)
166633
+ continue;
166634
+ const target = targets.get(tag.tagNumber);
166635
+ if (!target)
166636
+ continue;
166637
+ if (target.setContent(compressed)) {
166638
+ replayed += 1;
166639
+ }
166640
+ }
166641
+ return replayed;
166642
+ }
166643
+
166644
+ // src/hooks/magic-context/transform.ts
166441
166645
  init_compartment_runner();
166442
166646
 
166443
166647
  // src/hooks/magic-context/image-token-estimate.ts
@@ -167795,7 +167999,8 @@ function extractToolTagMetadata(part) {
167795
167999
  inputByteSize: estimateInputByteSize(input)
167796
168000
  };
167797
168001
  }
167798
- function tagMessages(sessionId, messages, tagger, db) {
168002
+ function tagMessages(sessionId, messages, tagger, db, options = {}) {
168003
+ const skipPrefixInjection = options.skipPrefixInjection === true;
167799
168004
  const targets = new Map;
167800
168005
  const reasoningByMessage = new Map;
167801
168006
  const messageTagNumbers = new Map;
@@ -167869,7 +168074,9 @@ function tagMessages(sessionId, messages, tagger, db) {
167869
168074
  }
167870
168075
  }
167871
168076
  messageTagNumbers.set(message, Math.max(messageTagNumbers.get(message) ?? 0, tagId));
167872
- textPart.text = prependTag(tagId, textPart.text);
168077
+ if (!skipPrefixInjection) {
168078
+ textPart.text = prependTag(tagId, textPart.text);
168079
+ }
167873
168080
  targets.set(tagId, {
167874
168081
  message,
167875
168082
  setContent: (content) => {
@@ -167896,7 +168103,9 @@ function tagMessages(sessionId, messages, tagger, db) {
167896
168103
  const { toolName, inputByteSize } = extractToolTagMetadata(toolPart);
167897
168104
  const tagId = tagger.assignTag(sessionId, toolPart.callID, "tool", byteSize(toolPart.state.output), db, reasoningBytes, toolName, inputByteSize);
167898
168105
  messageTagNumbers.set(message, Math.max(messageTagNumbers.get(message) ?? 0, tagId));
167899
- toolPart.state.output = prependTag(tagId, toolPart.state.output);
168106
+ if (!skipPrefixInjection) {
168107
+ toolPart.state.output = prependTag(tagId, toolPart.state.output);
168108
+ }
167900
168109
  toolTagByCallId.set(toolPart.callID, tagId);
167901
168110
  if (thinkingParts.length > 0 && !toolThinkingByCallId.has(toolPart.callID)) {
167902
168111
  toolThinkingByCallId.set(toolPart.callID, thinkingParts);
@@ -168842,7 +169051,16 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
168842
169051
  if (droppedTools > 0 || deduplicatedTools > 0 || droppedInjections > 0) {
168843
169052
  sessionLog(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
168844
169053
  }
168845
- return { droppedTools, deduplicatedTools, droppedInjections };
169054
+ let compressedTextTags = 0;
169055
+ if (config2.caveman?.enabled) {
169056
+ const cavemanResult = applyCavemanCleanup(sessionId, db, targets, tags, {
169057
+ enabled: true,
169058
+ minChars: config2.caveman.minChars,
169059
+ protectedTags: config2.protectedTags
169060
+ });
169061
+ compressedTextTags = cavemanResult.compressedToLite + cavemanResult.compressedToFull + cavemanResult.compressedToUltra;
169062
+ }
169063
+ return { droppedTools, deduplicatedTools, droppedInjections, compressedTextTags };
168846
169064
  }
168847
169065
  function extractToolInfo(part) {
168848
169066
  if (part.type === "tool" && typeof part.tool === "string" && DEDUP_SAFE_TOOLS.has(part.tool)) {
@@ -168914,7 +169132,7 @@ async function runPostTransformPhase(args) {
168914
169132
  const hasPendingUserOps = pendingOps.length > 0;
168915
169133
  const shouldApplyPendingOps = (args.schedulerDecision === "execute" || isExplicitFlush || forceMaterialization) && (!compartmentRunning || emergencyBypassCompartmentGate);
168916
169134
  const isCacheBustingPass = isExplicitFlush || shouldApplyPendingOps;
168917
- const shouldRunHeuristics = args.fullFeatureMode && (!compartmentRunning || emergencyBypassCompartmentGate) && (isExplicitFlush || forceMaterialization || args.schedulerDecision === "execute" && !alreadyRanThisTurn);
169135
+ const shouldRunHeuristics = (!compartmentRunning || emergencyBypassCompartmentGate) && (isExplicitFlush || forceMaterialization || args.schedulerDecision === "execute" && !alreadyRanThisTurn);
168918
169136
  if (shouldRunHeuristics) {
168919
169137
  const reason = isExplicitFlush ? "explicit_flush" : forceMaterialization ? `force_materialization (${args.contextUsage.percentage.toFixed(1)}% >= ${args.forceMaterializationPercentage}%)` : `scheduler_execute (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})`;
168920
169138
  sessionLog(args.sessionId, `heuristics WILL RUN \u2014 reason=${reason}, context=${args.contextUsage.percentage.toFixed(1)}%, turn=${args.currentTurnId}`);
@@ -168944,16 +169162,21 @@ async function runPostTransformPhase(args) {
168944
169162
  }
168945
169163
  if (shouldRunHeuristics) {
168946
169164
  const t5 = performance.now();
169165
+ const cavemanConfig = args.cavemanTextCompression?.enabled ? {
169166
+ enabled: true,
169167
+ minChars: args.cavemanTextCompression.minChars
169168
+ } : undefined;
168947
169169
  const cleanup = applyHeuristicCleanup(args.sessionId, args.db, args.targets, args.messageTagNumbers, {
168948
169170
  autoDropToolAge: args.autoDropToolAge,
168949
169171
  dropToolStructure: args.dropToolStructure,
168950
169172
  protectedTags: args.protectedTags,
168951
- dropAllTools: forceMaterialization
169173
+ dropAllTools: forceMaterialization,
169174
+ caveman: cavemanConfig
168952
169175
  }, args.tags);
168953
- if (cleanup.droppedTools > 0 || cleanup.deduplicatedTools > 0 || cleanup.droppedInjections > 0) {
169176
+ if (cleanup.droppedTools > 0 || cleanup.deduplicatedTools > 0 || cleanup.droppedInjections > 0 || cleanup.compressedTextTags > 0) {
168954
169177
  didMutateFromPendingOperations = true;
168955
169178
  }
168956
- logTransformTiming(args.sessionId, "applyHeuristicCleanup", t5, `droppedTools=${cleanup.droppedTools} deduplicatedTools=${cleanup.deduplicatedTools} droppedInjections=${cleanup.droppedInjections}`);
169179
+ logTransformTiming(args.sessionId, "applyHeuristicCleanup", t5, `droppedTools=${cleanup.droppedTools} deduplicatedTools=${cleanup.deduplicatedTools} droppedInjections=${cleanup.droppedInjections} compressedTextTags=${cleanup.compressedTextTags}`);
168957
169180
  if (args.watermark > 0) {
168958
169181
  const t6 = performance.now();
168959
169182
  truncateErroredTools(args.messages, args.watermark, args.messageTagNumbers);
@@ -169099,7 +169322,7 @@ async function runPostTransformPhase(args) {
169099
169322
  } else {
169100
169323
  args.nudgePlacements.clear(args.sessionId);
169101
169324
  }
169102
- const stickyNoteNudge = getStickyNoteNudge(args.db, args.sessionId);
169325
+ const stickyNoteNudge = args.fullFeatureMode ? getStickyNoteNudge(args.db, args.sessionId) : null;
169103
169326
  if (stickyNoteNudge) {
169104
169327
  const reinjected = appendReminderToUserMessageById(args.messages, stickyNoteNudge.messageId, stickyNoteNudge.text);
169105
169328
  if (!reinjected) {
@@ -169111,7 +169334,7 @@ async function runPostTransformPhase(args) {
169111
169334
  }
169112
169335
  }
169113
169336
  }
169114
- const deferredNoteText = peekNoteNudgeText(args.db, args.sessionId, args.currentTurnId, args.projectPath);
169337
+ const deferredNoteText = args.fullFeatureMode ? peekNoteNudgeText(args.db, args.sessionId, args.currentTurnId, args.projectPath) : null;
169115
169338
  if (deferredNoteText) {
169116
169339
  const noteInstruction = `
169117
169340
 
@@ -169396,7 +169619,11 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
169396
169619
  try {
169397
169620
  const t0 = performance.now();
169398
169621
  deps.tagger.initFromDb(sessionId, db);
169399
- const result = tagMessages(sessionId, messages, deps.tagger, db);
169622
+ const ctxReduceEnabledEffective = deps.ctxReduceEnabled !== false;
169623
+ const skipPrefixInjection = !ctxReduceEnabledEffective || reducedMode;
169624
+ const result = tagMessages(sessionId, messages, deps.tagger, db, {
169625
+ skipPrefixInjection
169626
+ });
169400
169627
  targets = result.targets;
169401
169628
  reasoningByMessage = result.reasoningByMessage;
169402
169629
  messageTagNumbers = result.messageTagNumbers;
@@ -169445,6 +169672,14 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
169445
169672
  }
169446
169673
  logTransformTiming(sessionId, "replayReasoningClearing", tReplay);
169447
169674
  }
169675
+ if (!deps.ctxReduceEnabled && !reducedMode && deps.cavemanTextCompression?.enabled) {
169676
+ const tCavemanReplay = performance.now();
169677
+ const replayedCaveman = replayCavemanCompression(sessionId, db, targets, tags);
169678
+ if (replayedCaveman > 0) {
169679
+ sessionLog(sessionId, `caveman replay: re-applied ${replayedCaveman} text tags`);
169680
+ }
169681
+ logTransformTiming(sessionId, "replayCavemanCompression", tCavemanReplay);
169682
+ }
169448
169683
  const t4 = performance.now();
169449
169684
  const strippedClearedReasoning = stripClearedReasoning(messages, skipTypedReasoningCleanup);
169450
169685
  logTransformTiming(sessionId, "stripClearedReasoning", t4, `strippedParts=${strippedClearedReasoning}`);
@@ -169534,7 +169769,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so ma
169534
169769
  hasRecentReduceCall,
169535
169770
  skipTypedReasoningCleanup,
169536
169771
  projectPath: deps.projectPath,
169537
- autoSearch: deps.autoSearch
169772
+ autoSearch: deps.autoSearch,
169773
+ cavemanTextCompression: deps.ctxReduceEnabled === false && !reducedMode ? deps.cavemanTextCompression : undefined
169538
169774
  });
169539
169775
  logTransformTiming(sessionId, "postTransformPhase", tPostProcess);
169540
169776
  const msgTokens = getMessageTokensCache(sessionId);
@@ -170510,13 +170746,21 @@ function createSystemPromptHashHandler(deps) {
170510
170746
  const sessionId = input.sessionID;
170511
170747
  if (!sessionId)
170512
170748
  return;
170749
+ let sessionMetaEarly;
170750
+ try {
170751
+ sessionMetaEarly = getOrCreateSessionMeta(deps.db, sessionId);
170752
+ } catch (error48) {
170753
+ sessionLog(sessionId, "system-prompt-hash session meta load failed:", error48);
170754
+ }
170755
+ const isSubagentSession = sessionMetaEarly?.isSubagent === true;
170756
+ const effectiveCtxReduceEnabled = isSubagentSession ? false : deps.ctxReduceEnabled;
170513
170757
  const fullPrompt = output.system.join(`
170514
170758
  `);
170515
170759
  if (fullPrompt.length > 0 && !fullPrompt.includes(MAGIC_CONTEXT_MARKER)) {
170516
170760
  const detectedAgent = detectAgentFromSystemPrompt(fullPrompt);
170517
- const guidance = buildMagicContextSection(detectedAgent, deps.protectedTags, deps.ctxReduceEnabled, deps.dreamerEnabled, deps.dropToolStructure, deps.experimentalTemporalAwareness);
170761
+ const guidance = buildMagicContextSection(detectedAgent, deps.protectedTags, effectiveCtxReduceEnabled, deps.dreamerEnabled, deps.dropToolStructure, deps.experimentalTemporalAwareness);
170518
170762
  output.system.push(guidance);
170519
- sessionLog(sessionId, `injected ${detectedAgent ?? "generic"} guidance into system prompt`);
170763
+ sessionLog(sessionId, `injected ${detectedAgent ?? "generic"} guidance into system prompt (ctxReduce=${effectiveCtxReduceEnabled}, subagent=${isSubagentSession})`);
170520
170764
  }
170521
170765
  const isCacheBusting = deps.flushedSessions.has(sessionId);
170522
170766
  if (shouldInjectDocs) {
@@ -170765,6 +171009,7 @@ function createMagicContextHook(deps) {
170765
171009
  db,
170766
171010
  nudgePlacements,
170767
171011
  protectedTags: deps.config.protected_tags,
171012
+ ctxReduceEnabled,
170768
171013
  autoDropToolAge: deps.config.auto_drop_tool_age ?? 100,
170769
171014
  dropToolStructure: deps.config.drop_tool_structure ?? true,
170770
171015
  clearReasoningAge: deps.config.clear_reasoning_age ?? 50,
@@ -170807,6 +171052,10 @@ function createMagicContextHook(deps) {
170807
171052
  memoryEnabled: deps.config.memory?.enabled !== false,
170808
171053
  embeddingEnabled: deps.config.embedding?.provider !== "off",
170809
171054
  gitCommitsEnabled: deps.config.experimental?.git_commit_indexing?.enabled === true
171055
+ } : undefined,
171056
+ cavemanTextCompression: ctxReduceEnabled === false && deps.config.experimental?.caveman_text_compression?.enabled === true ? {
171057
+ enabled: true,
171058
+ minChars: deps.config.experimental.caveman_text_compression.min_chars ?? 500
170810
171059
  } : undefined
170811
171060
  });
170812
171061
  const eventHandler = createEventHandler2({