@wolfx/pi-magic-context 0.24.1 → 0.26.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.
- package/dist/index.js +1570 -515
- package/dist/subagent-entry.js +821 -212
- package/package.json +4 -5
package/dist/index.js
CHANGED
|
@@ -8275,6 +8275,14 @@ function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
|
8275
8275
|
}
|
|
8276
8276
|
super(typeof filename === "string" ? filename : ":memory:", translated);
|
|
8277
8277
|
}
|
|
8278
|
+
prepare(sql) {
|
|
8279
|
+
const stmt = super.prepare(sql);
|
|
8280
|
+
for (const method of ["run", "get", "all"]) {
|
|
8281
|
+
const original = stmt[method].bind(stmt);
|
|
8282
|
+
stmt[method] = (...args) => args.length === 1 && Array.isArray(args[0]) ? original(...args[0]) : original(...args);
|
|
8283
|
+
}
|
|
8284
|
+
return stmt;
|
|
8285
|
+
}
|
|
8278
8286
|
transaction(fn) {
|
|
8279
8287
|
const self = this;
|
|
8280
8288
|
const wrapped = function(...args) {
|
|
@@ -141059,6 +141067,8 @@ function readRawSessionTailFromDb(db, sessionId, baseOrdinal, anchorMessageId) {
|
|
|
141059
141067
|
var encoder = new TextEncoder;
|
|
141060
141068
|
var TAG_PREFIX_REGEX = /^(?:§\d+§\s*)+/;
|
|
141061
141069
|
var MALFORMED_TAG_PREFIX_REGEX = /^(?:§\d+">§(?:\d+§)?\s*)+/;
|
|
141070
|
+
var DANGLING_TAG_GLOBAL_REGEX = /\u00a7\d+(?!\.\d)[^\s\u00a7\w.]?/g;
|
|
141071
|
+
var DANGLING_TAG_PREFIX_REGEX = /^(?:\u00a7\d+(?!\.\d)[^\s\u00a7\w.]?\s*)+/;
|
|
141062
141072
|
var COMPLETE_TAG_PAIR_GLOBAL_REGEX = /\u00a7\d+\u00a7/g;
|
|
141063
141073
|
var MALFORMED_TAG_GLOBAL_REGEX = /\u00a7\d+">(?:\u00a7(?:\d+\u00a7)?)?/g;
|
|
141064
141074
|
var STRAY_SECTION_CHAR_REGEX = /\u00a7/g;
|
|
@@ -141071,6 +141081,9 @@ function stripCompleteTagPairsGlobally(value) {
|
|
|
141071
141081
|
function stripMalformedTagNotationGlobally(value) {
|
|
141072
141082
|
return value.replace(MALFORMED_TAG_GLOBAL_REGEX, "");
|
|
141073
141083
|
}
|
|
141084
|
+
function stripDanglingTagNotationGlobally(value) {
|
|
141085
|
+
return value.replace(DANGLING_TAG_GLOBAL_REGEX, "");
|
|
141086
|
+
}
|
|
141074
141087
|
function stripTagSectionCharacters(value) {
|
|
141075
141088
|
return value.replace(STRAY_SECTION_CHAR_REGEX, "");
|
|
141076
141089
|
}
|
|
@@ -141078,6 +141091,7 @@ function stripPersistedAssistantText(value) {
|
|
|
141078
141091
|
let text = stripWellFormedLeadingTagPrefix(value);
|
|
141079
141092
|
text = stripCompleteTagPairsGlobally(text);
|
|
141080
141093
|
text = stripMalformedTagNotationGlobally(text);
|
|
141094
|
+
text = stripDanglingTagNotationGlobally(text);
|
|
141081
141095
|
text = stripTagSectionCharacters(text);
|
|
141082
141096
|
return text.trim();
|
|
141083
141097
|
}
|
|
@@ -141090,6 +141104,7 @@ function stripTagPrefix(value) {
|
|
|
141090
141104
|
const prev = stripped;
|
|
141091
141105
|
stripped = stripped.replace(MALFORMED_TAG_PREFIX_REGEX, "");
|
|
141092
141106
|
stripped = stripped.replace(TAG_PREFIX_REGEX, "");
|
|
141107
|
+
stripped = stripped.replace(DANGLING_TAG_PREFIX_REGEX, "");
|
|
141093
141108
|
if (stripped === prev)
|
|
141094
141109
|
break;
|
|
141095
141110
|
}
|
|
@@ -141197,6 +141212,24 @@ class ToolMutationBatch {
|
|
|
141197
141212
|
}
|
|
141198
141213
|
|
|
141199
141214
|
// ../plugin/src/hooks/magic-context/read-session-chunk.ts
|
|
141215
|
+
var BLOCK_TOKEN_MEMO_MAX = 2048;
|
|
141216
|
+
var blockTokenMemo = new Map;
|
|
141217
|
+
function estimateBlockTokens(blockText) {
|
|
141218
|
+
const cached = blockTokenMemo.get(blockText);
|
|
141219
|
+
if (cached !== undefined) {
|
|
141220
|
+
blockTokenMemo.delete(blockText);
|
|
141221
|
+
blockTokenMemo.set(blockText, cached);
|
|
141222
|
+
return cached;
|
|
141223
|
+
}
|
|
141224
|
+
const count = estimateTokens(blockText);
|
|
141225
|
+
if (blockTokenMemo.size >= BLOCK_TOKEN_MEMO_MAX) {
|
|
141226
|
+
const oldest = blockTokenMemo.keys().next().value;
|
|
141227
|
+
if (oldest !== undefined)
|
|
141228
|
+
blockTokenMemo.delete(oldest);
|
|
141229
|
+
}
|
|
141230
|
+
blockTokenMemo.set(blockText, count);
|
|
141231
|
+
return count;
|
|
141232
|
+
}
|
|
141200
141233
|
var activeRawMessageCache = null;
|
|
141201
141234
|
var activeAbsoluteCountCache = null;
|
|
141202
141235
|
var sessionProviders = new Map;
|
|
@@ -141379,7 +141412,7 @@ function readSessionChunk(sessionId, tokenBudget, offset = 1, eligibleEndOrdinal
|
|
|
141379
141412
|
if (!currentBlock)
|
|
141380
141413
|
return true;
|
|
141381
141414
|
const blockText = formatBlock(currentBlock);
|
|
141382
|
-
const blockTokens =
|
|
141415
|
+
const blockTokens = estimateBlockTokens(blockText);
|
|
141383
141416
|
if (totalTokens + blockTokens > tokenBudget && totalTokens > 0) {
|
|
141384
141417
|
return false;
|
|
141385
141418
|
}
|
|
@@ -141957,6 +141990,7 @@ var SESSION_META_SELECT_COLUMNS = [
|
|
|
141957
141990
|
"conversation_tokens",
|
|
141958
141991
|
"tool_call_tokens",
|
|
141959
141992
|
"cleared_reasoning_through_tag",
|
|
141993
|
+
"tool_reclaim_watermark",
|
|
141960
141994
|
"last_todo_state",
|
|
141961
141995
|
"cached_m0_bytes",
|
|
141962
141996
|
"cached_m1_bytes",
|
|
@@ -141983,6 +142017,8 @@ var SESSION_META_SELECT_COLUMNS = [
|
|
|
141983
142017
|
"recovery_no_eligible_head_count",
|
|
141984
142018
|
"force_emergency_bypass_window_start",
|
|
141985
142019
|
"force_emergency_bypass_used",
|
|
142020
|
+
"emergency_drain_active",
|
|
142021
|
+
"historian_drain_failure_at",
|
|
141986
142022
|
"upgrade_reminded_at",
|
|
141987
142023
|
"pi_stable_id_scheme"
|
|
141988
142024
|
];
|
|
@@ -142005,6 +142041,7 @@ var META_COLUMNS = {
|
|
|
142005
142041
|
conversationTokens: "conversation_tokens",
|
|
142006
142042
|
toolCallTokens: "tool_call_tokens",
|
|
142007
142043
|
clearedReasoningThroughTag: "cleared_reasoning_through_tag",
|
|
142044
|
+
toolReclaimWatermark: "tool_reclaim_watermark",
|
|
142008
142045
|
lastTodoState: "last_todo_state",
|
|
142009
142046
|
cachedM0Bytes: "cached_m0_bytes",
|
|
142010
142047
|
cachedM1Bytes: "cached_m1_bytes",
|
|
@@ -142031,6 +142068,8 @@ var META_COLUMNS = {
|
|
|
142031
142068
|
recoveryNoEligibleHeadCount: "recovery_no_eligible_head_count",
|
|
142032
142069
|
forceEmergencyBypassWindowStart: "force_emergency_bypass_window_start",
|
|
142033
142070
|
forceEmergencyBypassUsed: "force_emergency_bypass_used",
|
|
142071
|
+
emergencyDrainActive: "emergency_drain_active",
|
|
142072
|
+
historianDrainFailureAt: "historian_drain_failure_at",
|
|
142034
142073
|
upgradeRemindedAt: "upgrade_reminded_at",
|
|
142035
142074
|
piStableIdScheme: "pi_stable_id_scheme"
|
|
142036
142075
|
};
|
|
@@ -142073,7 +142112,7 @@ function isSessionMetaRow(row) {
|
|
|
142073
142112
|
if (row === null || typeof row !== "object")
|
|
142074
142113
|
return false;
|
|
142075
142114
|
const r = row;
|
|
142076
|
-
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.observed_safe_input_tokens) && isNumberOrNull(r.cache_alert_sent) && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag) && isStringOrNull(r.last_todo_state) && isBlobOrNull(r.cached_m0_bytes) && isBlobOrNull(r.cached_m1_bytes) && isNumberOrNull(r.cached_m0_project_memory_epoch) && isStringOrNull(r.cached_m0_workspace_fingerprint) && isNumberOrNull(r.cached_m0_project_user_profile_version) && isNumberOrNull(r.cached_m0_max_compartment_seq) && isNumberOrNull(r.cached_m0_max_memory_id) && isNumberOrNull(r.cached_m0_max_mutation_id) && isNumberOrNull(r.cached_m0_max_memory_mutation_id) && isStringOrNull(r.cached_m0_project_docs_hash) && isNumberOrNull(r.cached_m0_materialized_at) && isNumberOrNull(r.cached_m0_session_facts_version) && isStringOrNull(r.cached_m0_upgrade_state) && isStringOrNull(r.cached_m0_system_hash) && isStringOrNull(r.cached_m0_tool_set_hash) && isStringOrNull(r.cached_m0_model_key) && isStringOrNull(r.last_observed_model_key) && isNumberOrNull(r.last_usage_context_limit) && isNumberOrNull(r.prior_boundary_ordinal) && isNumberOrNull(r.protected_tail_policy_version) && isNumberOrNull(r.protected_tail_drain_window_started_at) && isNumberOrNull(r.protected_tail_drain_tokens) && isNumberOrNull(r.recovery_no_eligible_head_count) && isNumberOrNull(r.force_emergency_bypass_window_start) && isNumberOrNull(r.force_emergency_bypass_used) && isNumberOrNull(r.upgrade_reminded_at) && isNumberOrNull(r.pi_stable_id_scheme);
|
|
142115
|
+
return typeof r.session_id === "string" && typeof r.last_response_time === "number" && isStringOrNull(r.cache_ttl) && typeof r.counter === "number" && typeof r.last_nudge_tokens === "number" && isStringOrNull(r.last_nudge_band) && isStringOrNull(r.last_transform_error) && typeof r.is_subagent === "number" && typeof r.last_context_percentage === "number" && typeof r.last_input_tokens === "number" && isNumberOrNull(r.observed_safe_input_tokens) && isNumberOrNull(r.cache_alert_sent) && isNumberOrNull(r.times_execute_threshold_reached) && isNumberOrNull(r.compartment_in_progress) && (r.system_prompt_hash === null || typeof r.system_prompt_hash === "string" || typeof r.system_prompt_hash === "number") && isNumberOrNull(r.system_prompt_tokens) && isNumberOrNull(r.conversation_tokens) && isNumberOrNull(r.tool_call_tokens) && isNumberOrNull(r.cleared_reasoning_through_tag) && isStringOrNull(r.last_todo_state) && isBlobOrNull(r.cached_m0_bytes) && isBlobOrNull(r.cached_m1_bytes) && isNumberOrNull(r.cached_m0_project_memory_epoch) && isStringOrNull(r.cached_m0_workspace_fingerprint) && isNumberOrNull(r.cached_m0_project_user_profile_version) && isNumberOrNull(r.cached_m0_max_compartment_seq) && isNumberOrNull(r.cached_m0_max_memory_id) && isNumberOrNull(r.cached_m0_max_mutation_id) && isNumberOrNull(r.cached_m0_max_memory_mutation_id) && isStringOrNull(r.cached_m0_project_docs_hash) && isNumberOrNull(r.cached_m0_materialized_at) && isNumberOrNull(r.cached_m0_session_facts_version) && isStringOrNull(r.cached_m0_upgrade_state) && isStringOrNull(r.cached_m0_system_hash) && isStringOrNull(r.cached_m0_tool_set_hash) && isStringOrNull(r.cached_m0_model_key) && isStringOrNull(r.last_observed_model_key) && isNumberOrNull(r.last_usage_context_limit) && isNumberOrNull(r.prior_boundary_ordinal) && isNumberOrNull(r.protected_tail_policy_version) && isNumberOrNull(r.protected_tail_drain_window_started_at) && isNumberOrNull(r.protected_tail_drain_tokens) && isNumberOrNull(r.recovery_no_eligible_head_count) && isNumberOrNull(r.force_emergency_bypass_window_start) && isNumberOrNull(r.force_emergency_bypass_used) && isNumberOrNull(r.upgrade_reminded_at) && isNumberOrNull(r.pi_stable_id_scheme) && isNumberOrNull(r.tool_reclaim_watermark);
|
|
142077
142116
|
}
|
|
142078
142117
|
function getDefaultSessionMeta(sessionId) {
|
|
142079
142118
|
return {
|
|
@@ -142096,6 +142135,7 @@ function getDefaultSessionMeta(sessionId) {
|
|
|
142096
142135
|
conversationTokens: 0,
|
|
142097
142136
|
toolCallTokens: 0,
|
|
142098
142137
|
clearedReasoningThroughTag: 0,
|
|
142138
|
+
toolReclaimWatermark: 0,
|
|
142099
142139
|
lastTodoState: "",
|
|
142100
142140
|
cachedM0Bytes: null,
|
|
142101
142141
|
cachedM1Bytes: null,
|
|
@@ -142159,6 +142199,7 @@ function toSessionMeta(row) {
|
|
|
142159
142199
|
conversationTokens: numOrZero(row.conversation_tokens),
|
|
142160
142200
|
toolCallTokens: numOrZero(row.tool_call_tokens),
|
|
142161
142201
|
clearedReasoningThroughTag: numOrZero(row.cleared_reasoning_through_tag),
|
|
142202
|
+
toolReclaimWatermark: numOrZero(row.tool_reclaim_watermark),
|
|
142162
142203
|
lastTodoState: lastTodoStateRaw,
|
|
142163
142204
|
cachedM0Bytes: toBufferOrNull(row.cached_m0_bytes),
|
|
142164
142205
|
cachedM1Bytes: toBufferOrNull(row.cached_m1_bytes),
|
|
@@ -142930,8 +142971,9 @@ function backfillToolOwnersInChunks(db, result) {
|
|
|
142930
142971
|
var databases = new Map;
|
|
142931
142972
|
var persistenceByDatabase = new WeakMap;
|
|
142932
142973
|
var persistenceErrorByDatabase = new WeakMap;
|
|
142974
|
+
var pathByDatabase = new WeakMap;
|
|
142933
142975
|
var lastSchemaFenceRejection = null;
|
|
142934
|
-
var LATEST_SUPPORTED_VERSION =
|
|
142976
|
+
var LATEST_SUPPORTED_VERSION = 38;
|
|
142935
142977
|
function resolveDatabasePath(dbPathOverride) {
|
|
142936
142978
|
if (dbPathOverride) {
|
|
142937
142979
|
return { dbDir: dirname2(dbPathOverride), dbPath: dbPathOverride };
|
|
@@ -142944,6 +142986,9 @@ function resolveDatabasePath(dbPathOverride) {
|
|
|
142944
142986
|
const dbDir = getMagicContextStorageDir();
|
|
142945
142987
|
return { dbDir, dbPath: join5(dbDir, "context.db") };
|
|
142946
142988
|
}
|
|
142989
|
+
function getDatabasePath(db) {
|
|
142990
|
+
return pathByDatabase.get(db) ?? null;
|
|
142991
|
+
}
|
|
142947
142992
|
function migrateLegacyStorageIfNeeded(targetDbPath, targetDbDir) {
|
|
142948
142993
|
if (existsSync4(targetDbPath))
|
|
142949
142994
|
return;
|
|
@@ -143458,6 +143503,8 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
143458
143503
|
recovery_no_eligible_head_count INTEGER NOT NULL DEFAULT 0,
|
|
143459
143504
|
force_emergency_bypass_window_start INTEGER NOT NULL DEFAULT 0,
|
|
143460
143505
|
force_emergency_bypass_used INTEGER NOT NULL DEFAULT 0,
|
|
143506
|
+
emergency_drain_active INTEGER NOT NULL DEFAULT 0,
|
|
143507
|
+
historian_drain_failure_at INTEGER NOT NULL DEFAULT 0,
|
|
143461
143508
|
cached_m0_materialized_at INTEGER,
|
|
143462
143509
|
cached_m0_session_facts_version INTEGER,
|
|
143463
143510
|
cached_m0_upgrade_state TEXT,
|
|
@@ -143521,6 +143568,23 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
143521
143568
|
CREATE INDEX IF NOT EXISTS idx_historian_runs_status
|
|
143522
143569
|
ON historian_runs(status, created_at DESC);
|
|
143523
143570
|
|
|
143571
|
+
CREATE TABLE IF NOT EXISTS transform_decisions (
|
|
143572
|
+
session_id TEXT NOT NULL,
|
|
143573
|
+
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
143574
|
+
message_id TEXT NOT NULL,
|
|
143575
|
+
ts_ms INTEGER NOT NULL,
|
|
143576
|
+
decision TEXT NOT NULL,
|
|
143577
|
+
materialized INTEGER NOT NULL DEFAULT 0,
|
|
143578
|
+
materialize_reason TEXT,
|
|
143579
|
+
emergency INTEGER NOT NULL DEFAULT 0,
|
|
143580
|
+
dropped_tokens INTEGER NOT NULL DEFAULT 0,
|
|
143581
|
+
dropped_count INTEGER NOT NULL DEFAULT 0,
|
|
143582
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
143583
|
+
PRIMARY KEY (session_id, harness, message_id)
|
|
143584
|
+
);
|
|
143585
|
+
CREATE INDEX IF NOT EXISTS idx_transform_decisions_session_harness
|
|
143586
|
+
ON transform_decisions(session_id, harness);
|
|
143587
|
+
|
|
143524
143588
|
CREATE INDEX IF NOT EXISTS idx_tags_session_tag_number ON tags(session_id, tag_number);
|
|
143525
143589
|
CREATE INDEX IF NOT EXISTS idx_tags_session_message_id ON tags(session_id, message_id);
|
|
143526
143590
|
CREATE INDEX IF NOT EXISTS idx_pending_ops_session ON pending_ops(session_id);
|
|
@@ -143598,6 +143662,7 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
143598
143662
|
ensureColumn(db, "session_meta", "historian_last_failure_at", "INTEGER DEFAULT NULL");
|
|
143599
143663
|
ensureColumn(db, "session_meta", "system_prompt_hash", "TEXT DEFAULT ''");
|
|
143600
143664
|
ensureColumn(db, "session_meta", "cleared_reasoning_through_tag", "INTEGER DEFAULT 0");
|
|
143665
|
+
ensureColumn(db, "session_meta", "tool_reclaim_watermark", "INTEGER DEFAULT 0");
|
|
143601
143666
|
ensureColumn(db, "session_meta", "stripped_placeholder_ids", "TEXT DEFAULT ''");
|
|
143602
143667
|
ensureColumn(db, "session_meta", "stale_reduce_stripped_ids", "TEXT DEFAULT ''");
|
|
143603
143668
|
ensureColumn(db, "session_meta", "processed_image_stripped_ids", "TEXT DEFAULT ''");
|
|
@@ -143671,6 +143736,8 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
143671
143736
|
ensureColumn(db, "session_meta", "recovery_no_eligible_head_count", "INTEGER NOT NULL DEFAULT 0");
|
|
143672
143737
|
ensureColumn(db, "session_meta", "force_emergency_bypass_window_start", "INTEGER NOT NULL DEFAULT 0");
|
|
143673
143738
|
ensureColumn(db, "session_meta", "force_emergency_bypass_used", "INTEGER NOT NULL DEFAULT 0");
|
|
143739
|
+
ensureColumn(db, "session_meta", "emergency_drain_active", "INTEGER NOT NULL DEFAULT 0");
|
|
143740
|
+
ensureColumn(db, "session_meta", "historian_drain_failure_at", "INTEGER NOT NULL DEFAULT 0");
|
|
143674
143741
|
ensureColumn(db, "session_meta", "cached_m0_materialized_at", "INTEGER");
|
|
143675
143742
|
ensureColumn(db, "session_meta", "cached_m0_session_facts_version", "INTEGER");
|
|
143676
143743
|
ensureColumn(db, "session_meta", "cached_m0_upgrade_state", "TEXT");
|
|
@@ -143749,6 +143816,22 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
143749
143816
|
failed_at INTEGER NOT NULL,
|
|
143750
143817
|
UNIQUE(table_name, row_id)
|
|
143751
143818
|
);
|
|
143819
|
+
CREATE TABLE IF NOT EXISTS transform_decisions (
|
|
143820
|
+
session_id TEXT NOT NULL,
|
|
143821
|
+
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
143822
|
+
message_id TEXT NOT NULL,
|
|
143823
|
+
ts_ms INTEGER NOT NULL,
|
|
143824
|
+
decision TEXT NOT NULL,
|
|
143825
|
+
materialized INTEGER NOT NULL DEFAULT 0,
|
|
143826
|
+
materialize_reason TEXT,
|
|
143827
|
+
emergency INTEGER NOT NULL DEFAULT 0,
|
|
143828
|
+
dropped_tokens INTEGER NOT NULL DEFAULT 0,
|
|
143829
|
+
dropped_count INTEGER NOT NULL DEFAULT 0,
|
|
143830
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
143831
|
+
PRIMARY KEY (session_id, harness, message_id)
|
|
143832
|
+
);
|
|
143833
|
+
CREATE INDEX IF NOT EXISTS idx_transform_decisions_session_harness
|
|
143834
|
+
ON transform_decisions(session_id, harness);
|
|
143752
143835
|
`);
|
|
143753
143836
|
ensureColumn(db, "tags", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
143754
143837
|
ensureColumn(db, "pending_ops", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
@@ -143835,7 +143918,9 @@ function healNullIntegerColumns(db) {
|
|
|
143835
143918
|
["protected_tail_drain_tokens", 0],
|
|
143836
143919
|
["recovery_no_eligible_head_count", 0],
|
|
143837
143920
|
["force_emergency_bypass_window_start", 0],
|
|
143838
|
-
["force_emergency_bypass_used", 0]
|
|
143921
|
+
["force_emergency_bypass_used", 0],
|
|
143922
|
+
["emergency_drain_active", 0],
|
|
143923
|
+
["historian_drain_failure_at", 0]
|
|
143839
143924
|
];
|
|
143840
143925
|
for (const [column, fallback] of columns) {
|
|
143841
143926
|
try {
|
|
@@ -143911,6 +143996,7 @@ function openDatabase(dbPathOrOptions) {
|
|
|
143911
143996
|
setDatabase(db);
|
|
143912
143997
|
loadToolDefinitionMeasurements(db);
|
|
143913
143998
|
databases.set(dbPath, db);
|
|
143999
|
+
pathByDatabase.set(db, dbPath);
|
|
143914
144000
|
persistenceByDatabase.set(db, true);
|
|
143915
144001
|
persistenceErrorByDatabase.delete(db);
|
|
143916
144002
|
return db;
|
|
@@ -145152,6 +145238,41 @@ var MIGRATIONS = [
|
|
|
145152
145238
|
`);
|
|
145153
145239
|
}
|
|
145154
145240
|
}
|
|
145241
|
+
},
|
|
145242
|
+
{
|
|
145243
|
+
version: 37,
|
|
145244
|
+
description: "emergency drain catch-up latch + historian drain failure backoff",
|
|
145245
|
+
up: (db) => {
|
|
145246
|
+
const hasSessionMeta = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='session_meta'").get();
|
|
145247
|
+
if (!hasSessionMeta)
|
|
145248
|
+
return;
|
|
145249
|
+
ensureColumn(db, "session_meta", "emergency_drain_active", "INTEGER NOT NULL DEFAULT 0");
|
|
145250
|
+
ensureColumn(db, "session_meta", "historian_drain_failure_at", "INTEGER NOT NULL DEFAULT 0");
|
|
145251
|
+
}
|
|
145252
|
+
},
|
|
145253
|
+
{
|
|
145254
|
+
version: 38,
|
|
145255
|
+
description: "durable transform decisions for cache-event cause attribution",
|
|
145256
|
+
up: (db) => {
|
|
145257
|
+
db.exec(`
|
|
145258
|
+
CREATE TABLE IF NOT EXISTS transform_decisions (
|
|
145259
|
+
session_id TEXT NOT NULL,
|
|
145260
|
+
harness TEXT NOT NULL DEFAULT 'opencode',
|
|
145261
|
+
message_id TEXT NOT NULL,
|
|
145262
|
+
ts_ms INTEGER NOT NULL,
|
|
145263
|
+
decision TEXT NOT NULL,
|
|
145264
|
+
materialized INTEGER NOT NULL DEFAULT 0,
|
|
145265
|
+
materialize_reason TEXT,
|
|
145266
|
+
emergency INTEGER NOT NULL DEFAULT 0,
|
|
145267
|
+
dropped_tokens INTEGER NOT NULL DEFAULT 0,
|
|
145268
|
+
dropped_count INTEGER NOT NULL DEFAULT 0,
|
|
145269
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
145270
|
+
PRIMARY KEY (session_id, harness, message_id)
|
|
145271
|
+
);
|
|
145272
|
+
CREATE INDEX IF NOT EXISTS idx_transform_decisions_session_harness
|
|
145273
|
+
ON transform_decisions(session_id, harness);
|
|
145274
|
+
`);
|
|
145275
|
+
}
|
|
145155
145276
|
}
|
|
145156
145277
|
];
|
|
145157
145278
|
var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -145583,7 +145704,9 @@ var DEFAULT_PROTECTED_TAIL_META = {
|
|
|
145583
145704
|
protectedTailDrainTokens: 0,
|
|
145584
145705
|
recoveryNoEligibleHeadCount: 0,
|
|
145585
145706
|
forceEmergencyBypassWindowStart: 0,
|
|
145586
|
-
forceEmergencyBypassUsed: 0
|
|
145707
|
+
forceEmergencyBypassUsed: 0,
|
|
145708
|
+
emergencyDrainActive: 0,
|
|
145709
|
+
historianDrainFailureAt: 0
|
|
145587
145710
|
};
|
|
145588
145711
|
function toProtectedTailMeta(row) {
|
|
145589
145712
|
if (row === null || typeof row !== "object")
|
|
@@ -145597,7 +145720,9 @@ function toProtectedTailMeta(row) {
|
|
|
145597
145720
|
protectedTailDrainTokens: numberOr(r.protected_tail_drain_tokens, 0),
|
|
145598
145721
|
recoveryNoEligibleHeadCount: numberOr(r.recovery_no_eligible_head_count, 0),
|
|
145599
145722
|
forceEmergencyBypassWindowStart: numberOr(r.force_emergency_bypass_window_start, 0),
|
|
145600
|
-
forceEmergencyBypassUsed: numberOr(r.force_emergency_bypass_used, 0)
|
|
145723
|
+
forceEmergencyBypassUsed: numberOr(r.force_emergency_bypass_used, 0),
|
|
145724
|
+
emergencyDrainActive: numberOr(r.emergency_drain_active, 0),
|
|
145725
|
+
historianDrainFailureAt: numberOr(r.historian_drain_failure_at, 0)
|
|
145601
145726
|
};
|
|
145602
145727
|
}
|
|
145603
145728
|
function loadProtectedTailMeta(db, sessionId) {
|
|
@@ -145605,7 +145730,7 @@ function loadProtectedTailMeta(db, sessionId) {
|
|
|
145605
145730
|
const row = db.prepare(`SELECT prior_boundary_ordinal, protected_tail_policy_version,
|
|
145606
145731
|
protected_tail_drain_window_started_at, protected_tail_drain_tokens,
|
|
145607
145732
|
recovery_no_eligible_head_count, force_emergency_bypass_window_start,
|
|
145608
|
-
force_emergency_bypass_used
|
|
145733
|
+
force_emergency_bypass_used, emergency_drain_active, historian_drain_failure_at
|
|
145609
145734
|
FROM session_meta WHERE session_id = ?`).get(sessionId);
|
|
145610
145735
|
return toProtectedTailMeta(row);
|
|
145611
145736
|
}
|
|
@@ -145649,6 +145774,17 @@ function protectedTailWindowBudget(usagePercentage, usable, perRunCap) {
|
|
|
145649
145774
|
return Math.min(750000, Math.max(3 * perRunCap, Math.round(0.35 * usable)));
|
|
145650
145775
|
return Math.min(500000, Math.max(perRunCap, Math.round(0.2 * usable)));
|
|
145651
145776
|
}
|
|
145777
|
+
var EMERGENCY_DRAIN_ENTER_PERCENTAGE = 95;
|
|
145778
|
+
var EMERGENCY_DRAIN_EXIT_MARGIN = 10;
|
|
145779
|
+
var EMERGENCY_DRAIN_FALLBACK_EXIT_PERCENTAGE = 55;
|
|
145780
|
+
var EMERGENCY_DRAIN_FAILURE_BACKOFF_MS = 60000;
|
|
145781
|
+
var EMERGENCY_DRAIN_MAX_LATCH_MS = 30 * 60 * 1000;
|
|
145782
|
+
function emergencyDrainExitThreshold(executeThresholdPercentage) {
|
|
145783
|
+
if (!Number.isFinite(executeThresholdPercentage) || executeThresholdPercentage <= 0) {
|
|
145784
|
+
return EMERGENCY_DRAIN_FALLBACK_EXIT_PERCENTAGE;
|
|
145785
|
+
}
|
|
145786
|
+
return Math.max(0, executeThresholdPercentage - EMERGENCY_DRAIN_EXIT_MARGIN);
|
|
145787
|
+
}
|
|
145652
145788
|
function reserveProtectedTailDrainTokens(args) {
|
|
145653
145789
|
const now = args.now ?? Date.now();
|
|
145654
145790
|
const requested = Math.max(0, Math.floor(args.trueRawTokens));
|
|
@@ -145667,18 +145803,30 @@ function reserveProtectedTailDrainTokens(args) {
|
|
|
145667
145803
|
let meta = loadProtectedTailMeta(args.db, args.sessionId);
|
|
145668
145804
|
if (now - meta.protectedTailDrainWindowStartedAt > DRAIN_WINDOW_MS) {
|
|
145669
145805
|
args.db.prepare(`UPDATE session_meta
|
|
145670
|
-
SET protected_tail_drain_window_started_at = ?, protected_tail_drain_tokens = 0
|
|
145671
|
-
|
|
145672
|
-
WHERE session_id = ?`).run(now, now, args.sessionId);
|
|
145806
|
+
SET protected_tail_drain_window_started_at = ?, protected_tail_drain_tokens = 0
|
|
145807
|
+
WHERE session_id = ?`).run(now, args.sessionId);
|
|
145673
145808
|
meta = loadProtectedTailMeta(args.db, args.sessionId);
|
|
145674
145809
|
}
|
|
145810
|
+
const exitThreshold = emergencyDrainExitThreshold(args.executeThresholdPercentage);
|
|
145811
|
+
let latchActiveSince = meta.emergencyDrainActive;
|
|
145812
|
+
if (args.usagePercentage >= EMERGENCY_DRAIN_ENTER_PERCENTAGE) {
|
|
145813
|
+
if (latchActiveSince <= 0)
|
|
145814
|
+
latchActiveSince = now;
|
|
145815
|
+
} else if (latchActiveSince > 0) {
|
|
145816
|
+
const expired = now - latchActiveSince > EMERGENCY_DRAIN_MAX_LATCH_MS;
|
|
145817
|
+
if (args.usagePercentage < exitThreshold || expired)
|
|
145818
|
+
latchActiveSince = 0;
|
|
145819
|
+
}
|
|
145820
|
+
if (latchActiveSince !== meta.emergencyDrainActive) {
|
|
145821
|
+
args.db.prepare("UPDATE session_meta SET emergency_drain_active = ? WHERE session_id = ?").run(latchActiveSince, args.sessionId);
|
|
145822
|
+
}
|
|
145823
|
+
const latchActive = latchActiveSince > 0;
|
|
145675
145824
|
const budget = protectedTailWindowBudget(args.usagePercentage, args.usable, args.perRunCap);
|
|
145676
145825
|
const remaining = Math.max(0, budget - meta.protectedTailDrainTokens);
|
|
145677
145826
|
let reserved = Math.min(requested, args.perRunCap, remaining);
|
|
145678
145827
|
let bypass = false;
|
|
145679
|
-
const
|
|
145680
|
-
|
|
145681
|
-
if (reserved <= 0 && args.usagePercentage >= 95 && bypassUsed === 0) {
|
|
145828
|
+
const inFailureBackoff = meta.historianDrainFailureAt > 0 && now - meta.historianDrainFailureAt < EMERGENCY_DRAIN_FAILURE_BACKOFF_MS;
|
|
145829
|
+
if (reserved <= 0 && latchActive && !inFailureBackoff) {
|
|
145682
145830
|
reserved = Math.min(requested, args.perRunCap);
|
|
145683
145831
|
bypass = true;
|
|
145684
145832
|
}
|
|
@@ -145686,10 +145834,8 @@ function reserveProtectedTailDrainTokens(args) {
|
|
|
145686
145834
|
return;
|
|
145687
145835
|
args.db.prepare(`UPDATE session_meta
|
|
145688
145836
|
SET protected_tail_drain_window_started_at = CASE WHEN protected_tail_drain_window_started_at = 0 THEN ? ELSE protected_tail_drain_window_started_at END,
|
|
145689
|
-
protected_tail_drain_tokens = COALESCE(protected_tail_drain_tokens, 0) +
|
|
145690
|
-
|
|
145691
|
-
force_emergency_bypass_used = CASE WHEN ? THEN 1 ELSE force_emergency_bypass_used END
|
|
145692
|
-
WHERE session_id = ?`).run(now, reserved, bypass ? 1 : 0, now, bypass ? 1 : 0, args.sessionId);
|
|
145837
|
+
protected_tail_drain_tokens = COALESCE(protected_tail_drain_tokens, 0) + ?
|
|
145838
|
+
WHERE session_id = ?`).run(now, reserved, args.sessionId);
|
|
145693
145839
|
result = {
|
|
145694
145840
|
ok: true,
|
|
145695
145841
|
reservedTokens: reserved,
|
|
@@ -145699,6 +145845,25 @@ function reserveProtectedTailDrainTokens(args) {
|
|
|
145699
145845
|
})();
|
|
145700
145846
|
return result;
|
|
145701
145847
|
}
|
|
145848
|
+
function clearEmergencyDrainLatch(db, sessionId) {
|
|
145849
|
+
db.transaction(() => {
|
|
145850
|
+
ensureSessionMetaRow(db, sessionId);
|
|
145851
|
+
db.prepare("UPDATE session_meta SET emergency_drain_active = 0 WHERE session_id = ?").run(sessionId);
|
|
145852
|
+
})();
|
|
145853
|
+
}
|
|
145854
|
+
function recordHistorianDrainFailure(db, sessionId, now) {
|
|
145855
|
+
const ts = now ?? Date.now();
|
|
145856
|
+
db.transaction(() => {
|
|
145857
|
+
ensureSessionMetaRow(db, sessionId);
|
|
145858
|
+
db.prepare("UPDATE session_meta SET historian_drain_failure_at = ? WHERE session_id = ?").run(ts, sessionId);
|
|
145859
|
+
})();
|
|
145860
|
+
}
|
|
145861
|
+
function clearHistorianDrainFailure(db, sessionId) {
|
|
145862
|
+
db.transaction(() => {
|
|
145863
|
+
ensureSessionMetaRow(db, sessionId);
|
|
145864
|
+
db.prepare("UPDATE session_meta SET historian_drain_failure_at = 0 WHERE session_id = ?").run(sessionId);
|
|
145865
|
+
})();
|
|
145866
|
+
}
|
|
145702
145867
|
function rollbackProtectedTailDrainReservation(db, reservation) {
|
|
145703
145868
|
if (!reservation || reservation.tokens <= 0)
|
|
145704
145869
|
return;
|
|
@@ -146217,6 +146382,7 @@ var SESSION_META_FALLBACK_SELECTS = {
|
|
|
146217
146382
|
last_transform_error: "'' AS last_transform_error",
|
|
146218
146383
|
system_prompt_hash: "'' AS system_prompt_hash",
|
|
146219
146384
|
last_todo_state: "'' AS last_todo_state",
|
|
146385
|
+
tool_reclaim_watermark: "0 AS tool_reclaim_watermark",
|
|
146220
146386
|
cached_m0_bytes: "NULL AS cached_m0_bytes",
|
|
146221
146387
|
cached_m1_bytes: "NULL AS cached_m1_bytes",
|
|
146222
146388
|
cached_m0_project_memory_epoch: "NULL AS cached_m0_project_memory_epoch",
|
|
@@ -146294,6 +146460,14 @@ function updateSessionMeta(db, sessionId, updates) {
|
|
|
146294
146460
|
db.prepare(`UPDATE session_meta SET ${setClauses.join(", ")} WHERE session_id = ?`).run(...values, sessionId);
|
|
146295
146461
|
})();
|
|
146296
146462
|
}
|
|
146463
|
+
function advanceToolReclaimWatermark(db, sessionId, maxTagNumber) {
|
|
146464
|
+
if (maxTagNumber <= 0)
|
|
146465
|
+
return;
|
|
146466
|
+
db.transaction(() => {
|
|
146467
|
+
ensureSessionMetaRow(db, sessionId);
|
|
146468
|
+
db.prepare("UPDATE session_meta SET tool_reclaim_watermark = MAX(COALESCE(tool_reclaim_watermark, 0), ?) WHERE session_id = ?").run(maxTagNumber, sessionId);
|
|
146469
|
+
})();
|
|
146470
|
+
}
|
|
146297
146471
|
// ../plugin/src/features/magic-context/storage-notes.ts
|
|
146298
146472
|
var NOTE_TYPES = new Set(["session", "smart"]);
|
|
146299
146473
|
var NOTE_STATUSES = new Set(["active", "pending", "ready", "dismissed"]);
|
|
@@ -146691,12 +146865,37 @@ function getActiveTagTokenAggregate(db, sessionId, protectedTags = 0) {
|
|
|
146691
146865
|
nullCount: row?.null_count ?? 0
|
|
146692
146866
|
};
|
|
146693
146867
|
}
|
|
146694
|
-
function
|
|
146695
|
-
|
|
146868
|
+
function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, limit = 4) {
|
|
146869
|
+
if (limit <= 0)
|
|
146870
|
+
return [];
|
|
146871
|
+
const boundedLimit = Math.max(1, Math.min(10, Math.floor(limit)));
|
|
146872
|
+
const whereProtected = protectedTags > 0 ? `AND tag_number < (
|
|
146873
|
+
SELECT tag_number FROM tags
|
|
146874
|
+
WHERE session_id = ? AND status = 'active'
|
|
146875
|
+
ORDER BY tag_number DESC LIMIT 1 OFFSET ?
|
|
146876
|
+
)` : "";
|
|
146877
|
+
const params = protectedTags > 0 ? [sessionId, sessionId, protectedTags - 1, boundedLimit] : [sessionId, boundedLimit];
|
|
146878
|
+
const rows = db.prepare(`SELECT tag_number, tool_name
|
|
146879
|
+
FROM tags
|
|
146880
|
+
WHERE session_id = ? AND status = 'active' AND type = 'tool' ${whereProtected}
|
|
146881
|
+
ORDER BY tag_number ASC, id ASC
|
|
146882
|
+
LIMIT ?`).all(...params);
|
|
146883
|
+
return rows.filter((row) => typeof row.tag_number === "number").map((row) => ({
|
|
146884
|
+
tagNumber: row.tag_number,
|
|
146885
|
+
toolName: typeof row.tool_name === "string" ? row.tool_name : null
|
|
146886
|
+
}));
|
|
146887
|
+
}
|
|
146888
|
+
function getTriggerTagTokenUpperBound(db, sessionId, floor = 0) {
|
|
146889
|
+
const sql = floor > 0 ? `SELECT
|
|
146696
146890
|
COALESCE(SUM(COALESCE(token_count, 0) + COALESCE(input_token_count, 0) + COALESCE(reasoning_token_count, 0)), 0) AS bound,
|
|
146697
146891
|
COALESCE(SUM(CASE WHEN token_count IS NULL THEN 1 ELSE 0 END), 0) AS null_count
|
|
146698
146892
|
FROM tags
|
|
146699
|
-
WHERE session_id = ? AND status IN ('active', 'dropped')`
|
|
146893
|
+
WHERE session_id = ? AND status IN ('active', 'dropped') AND tag_number >= ?` : `SELECT
|
|
146894
|
+
COALESCE(SUM(COALESCE(token_count, 0) + COALESCE(input_token_count, 0) + COALESCE(reasoning_token_count, 0)), 0) AS bound,
|
|
146895
|
+
COALESCE(SUM(CASE WHEN token_count IS NULL THEN 1 ELSE 0 END), 0) AS null_count
|
|
146896
|
+
FROM tags
|
|
146897
|
+
WHERE session_id = ? AND status IN ('active', 'dropped')`;
|
|
146898
|
+
const row = floor > 0 ? db.prepare(sql).get(sessionId, floor) : db.prepare(sql).get(sessionId);
|
|
146700
146899
|
return { bound: row?.bound ?? 0, nullCount: row?.null_count ?? 0 };
|
|
146701
146900
|
}
|
|
146702
146901
|
function updateTagInputByteSize(db, sessionId, tagNumber, newInputByteSize) {
|
|
@@ -146723,10 +146922,12 @@ function getUpdateTagInputTokenCountStatement(db) {
|
|
|
146723
146922
|
function updateTagTokenCount(db, sessionId, tagNumber, newTokenCount) {
|
|
146724
146923
|
getUpdateTagTokenCountStatement(db).run(newTokenCount, sessionId, tagNumber);
|
|
146725
146924
|
}
|
|
146726
|
-
function getAllStatusTagTokenTotalsFlat(db, sessionId) {
|
|
146727
|
-
const rows = db.prepare(`SELECT type, message_id, tool_owner_message_id, token_count, input_token_count, reasoning_token_count
|
|
146728
|
-
|
|
146729
|
-
|
|
146925
|
+
function getAllStatusTagTokenTotalsFlat(db, sessionId, floor = 0) {
|
|
146926
|
+
const rows = floor > 0 ? db.prepare(`SELECT type, message_id, tool_owner_message_id, token_count, input_token_count, reasoning_token_count
|
|
146927
|
+
FROM tags
|
|
146928
|
+
WHERE session_id = ? AND tag_number >= ?`).all(sessionId, floor) : db.prepare(`SELECT type, message_id, tool_owner_message_id, token_count, input_token_count, reasoning_token_count
|
|
146929
|
+
FROM tags
|
|
146930
|
+
WHERE session_id = ?`).all(sessionId);
|
|
146730
146931
|
const totals = new Map;
|
|
146731
146932
|
const nullMessageIds = new Set;
|
|
146732
146933
|
for (const row of rows) {
|
|
@@ -146845,6 +147046,52 @@ function getTagNumberByMessageId(db, sessionId, messageId) {
|
|
|
146845
147046
|
const row = getTagNumberByMessageIdStatement(db).get(sessionId, messageId);
|
|
146846
147047
|
return isTagNumberRow(row) ? row.tag_number : null;
|
|
146847
147048
|
}
|
|
147049
|
+
var getMinMessageTagNumberForRawIdStatements = new WeakMap;
|
|
147050
|
+
function isMinTagNumberRow(row) {
|
|
147051
|
+
return row !== null && typeof row === "object" && "m" in row;
|
|
147052
|
+
}
|
|
147053
|
+
function getMinMessageTagNumberForRawId(db, sessionId, rawId) {
|
|
147054
|
+
if (rawId.includes(":"))
|
|
147055
|
+
return null;
|
|
147056
|
+
let stmt = getMinMessageTagNumberForRawIdStatements.get(db);
|
|
147057
|
+
if (!stmt) {
|
|
147058
|
+
stmt = db.prepare("SELECT MIN(tag_number) AS m FROM tags WHERE session_id = ? AND message_id >= ? AND message_id < ?");
|
|
147059
|
+
getMinMessageTagNumberForRawIdStatements.set(db, stmt);
|
|
147060
|
+
}
|
|
147061
|
+
const row = stmt.get(sessionId, `${rawId}:`, `${rawId};`);
|
|
147062
|
+
return isMinTagNumberRow(row) && typeof row.m === "number" ? row.m : null;
|
|
147063
|
+
}
|
|
147064
|
+
var TAGGER_FLOOR_SCAN_MESSAGES = 8;
|
|
147065
|
+
var TAGGER_FLOOR_MAX_PROBES = 64;
|
|
147066
|
+
var TAGGER_FLOOR_SAFETY_MARGIN = 256;
|
|
147067
|
+
var TAGGER_FLOOR_PER_SKIP_MARGIN = 64;
|
|
147068
|
+
function deriveTagLoadFloor(db, sessionId, rawIds) {
|
|
147069
|
+
let min = Number.POSITIVE_INFINITY;
|
|
147070
|
+
let probes = 0;
|
|
147071
|
+
let hits = 0;
|
|
147072
|
+
let skippedBeforeFirstHit = 0;
|
|
147073
|
+
for (const rawId of rawIds) {
|
|
147074
|
+
if (typeof rawId !== "string" || rawId.length === 0)
|
|
147075
|
+
continue;
|
|
147076
|
+
if (probes >= TAGGER_FLOOR_MAX_PROBES)
|
|
147077
|
+
break;
|
|
147078
|
+
probes++;
|
|
147079
|
+
const m = getMinMessageTagNumberForRawId(db, sessionId, rawId);
|
|
147080
|
+
if (m === null) {
|
|
147081
|
+
if (hits === 0)
|
|
147082
|
+
skippedBeforeFirstHit++;
|
|
147083
|
+
continue;
|
|
147084
|
+
}
|
|
147085
|
+
if (m < min)
|
|
147086
|
+
min = m;
|
|
147087
|
+
if (++hits >= TAGGER_FLOOR_SCAN_MESSAGES)
|
|
147088
|
+
break;
|
|
147089
|
+
}
|
|
147090
|
+
if (!Number.isFinite(min))
|
|
147091
|
+
return 0;
|
|
147092
|
+
const margin = TAGGER_FLOOR_SAFETY_MARGIN + skippedBeforeFirstHit * TAGGER_FLOOR_PER_SKIP_MARGIN;
|
|
147093
|
+
return Math.max(0, min - margin);
|
|
147094
|
+
}
|
|
146848
147095
|
var TAG_SELECT_COLUMNS = "id, message_id, type, status, drop_mode, tool_name, input_byte_size, byte_size, reasoning_byte_size, session_id, tag_number, caveman_depth, tool_owner_message_id";
|
|
146849
147096
|
function getTagsBySession(db, sessionId) {
|
|
146850
147097
|
const rows = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? ORDER BY tag_number ASC, id ASC`).all(sessionId).filter(isTagRow);
|
|
@@ -146948,6 +147195,11 @@ init_logger();
|
|
|
146948
147195
|
import { createHash as createHash5 } from "node:crypto";
|
|
146949
147196
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
146950
147197
|
import path5 from "node:path";
|
|
147198
|
+
|
|
147199
|
+
// ../plugin/src/features/magic-context/memory/relocate-memory.ts
|
|
147200
|
+
var memoryCopyColumnsCache = new WeakMap;
|
|
147201
|
+
|
|
147202
|
+
// ../plugin/src/features/magic-context/v22-deferred-backfill.ts
|
|
146951
147203
|
var BATCH_SIZE = 25;
|
|
146952
147204
|
var YIELD_EVERY_N_ROWS = 5;
|
|
146953
147205
|
var BACKFILL_META_KEY = "v22_legacy_memory_backfill";
|
|
@@ -147163,65 +147415,6 @@ async function runDeferredV22Backfill(db, options = {}) {
|
|
|
147163
147415
|
};
|
|
147164
147416
|
}
|
|
147165
147417
|
|
|
147166
|
-
// ../plugin/src/agents/historian.ts
|
|
147167
|
-
var HISTORIAN_AGENT = "historian";
|
|
147168
|
-
var HISTORIAN_EDITOR_AGENT = "historian-editor";
|
|
147169
|
-
|
|
147170
|
-
// ../plugin/src/agents/dreamer.ts
|
|
147171
|
-
var DREAMER_AGENT = "dreamer";
|
|
147172
|
-
|
|
147173
|
-
// ../plugin/src/agents/sidekick.ts
|
|
147174
|
-
var SIDEKICK_AGENT = "sidekick";
|
|
147175
|
-
|
|
147176
|
-
// ../plugin/src/shared/model-requirements.ts
|
|
147177
|
-
var HISTORIAN_FALLBACK_CHAIN = [
|
|
147178
|
-
{ providers: ["github-copilot", "anthropic", "opencode"], model: "claude-sonnet-4-6" },
|
|
147179
|
-
{ providers: ["opencode-go"], model: "minimax-m2.7" },
|
|
147180
|
-
{
|
|
147181
|
-
providers: ["zai-coding-plan", "bailian-coding-plan", "opencode-go", "opencode"],
|
|
147182
|
-
model: "glm-5"
|
|
147183
|
-
},
|
|
147184
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.4" },
|
|
147185
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3.1-pro" }
|
|
147186
|
-
];
|
|
147187
|
-
var DREAMER_FALLBACK_CHAIN = [
|
|
147188
|
-
{ providers: ["github-copilot", "anthropic", "opencode"], model: "claude-sonnet-4-6" },
|
|
147189
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
147190
|
-
{
|
|
147191
|
-
providers: ["zai-coding-plan", "bailian-coding-plan", "opencode-go", "opencode"],
|
|
147192
|
-
model: "glm-5"
|
|
147193
|
-
},
|
|
147194
|
-
{ providers: ["opencode-go"], model: "minimax-m2.7" },
|
|
147195
|
-
{ providers: ["github-copilot", "openai", "opencode"], model: "gpt-5.4-mini" }
|
|
147196
|
-
];
|
|
147197
|
-
var SIDEKICK_FALLBACK_CHAIN = [
|
|
147198
|
-
{ providers: ["cerebras"], model: "qwen-3-235b-a22b-instruct-2507" },
|
|
147199
|
-
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-flash" },
|
|
147200
|
-
{ providers: ["openai", "github-copilot", "opencode"], model: "gpt-5.4-mini" },
|
|
147201
|
-
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
147202
|
-
];
|
|
147203
|
-
var AGENT_MODEL_REQUIREMENTS = {
|
|
147204
|
-
[HISTORIAN_AGENT]: { fallbackChain: HISTORIAN_FALLBACK_CHAIN },
|
|
147205
|
-
[HISTORIAN_EDITOR_AGENT]: { fallbackChain: HISTORIAN_FALLBACK_CHAIN },
|
|
147206
|
-
[DREAMER_AGENT]: { fallbackChain: DREAMER_FALLBACK_CHAIN },
|
|
147207
|
-
[SIDEKICK_AGENT]: { fallbackChain: SIDEKICK_FALLBACK_CHAIN }
|
|
147208
|
-
};
|
|
147209
|
-
function expandFallbackChain(chain) {
|
|
147210
|
-
const models = [];
|
|
147211
|
-
for (const entry of chain) {
|
|
147212
|
-
for (const provider of entry.providers) {
|
|
147213
|
-
models.push(`${provider}/${entry.model}`);
|
|
147214
|
-
}
|
|
147215
|
-
}
|
|
147216
|
-
return models;
|
|
147217
|
-
}
|
|
147218
|
-
function getAgentFallbackModels(agent) {
|
|
147219
|
-
const requirement = AGENT_MODEL_REQUIREMENTS[agent];
|
|
147220
|
-
if (!requirement)
|
|
147221
|
-
return;
|
|
147222
|
-
return expandFallbackChain(requirement.fallbackChain);
|
|
147223
|
-
}
|
|
147224
|
-
|
|
147225
147418
|
// ../plugin/src/shared/models-dev-cache.ts
|
|
147226
147419
|
init_data_path();
|
|
147227
147420
|
init_logger();
|
|
@@ -147312,25 +147505,9 @@ function resolveHistorianContextLimit(historianModelOverride) {
|
|
|
147312
147505
|
return DEFAULT_HISTORIAN_CONTEXT_FALLBACK;
|
|
147313
147506
|
}
|
|
147314
147507
|
if (typeof historianModelOverride === "string" && historianModelOverride.trim() !== "") {
|
|
147315
|
-
console.warn(`[magic-context] historian.model "${historianModelOverride}" lacks provider prefix ("provider/model-id"); using
|
|
147508
|
+
console.warn(`[magic-context] historian.model "${historianModelOverride}" lacks provider prefix ("provider/model-id"); using the default context limit for chunk-budget derivation.`);
|
|
147316
147509
|
}
|
|
147317
|
-
|
|
147318
|
-
if (!chain || chain.length === 0)
|
|
147319
|
-
return DEFAULT_HISTORIAN_CONTEXT_FALLBACK;
|
|
147320
|
-
const expanded = expandFallbackChain(chain);
|
|
147321
|
-
let minLimit;
|
|
147322
|
-
for (const key of expanded) {
|
|
147323
|
-
const [providerID, ...rest] = key.split("/");
|
|
147324
|
-
const modelID = rest.join("/");
|
|
147325
|
-
if (!providerID || !modelID)
|
|
147326
|
-
continue;
|
|
147327
|
-
const limit = getSdkContextLimit(providerID, modelID);
|
|
147328
|
-
if (typeof limit !== "number" || limit <= 0)
|
|
147329
|
-
continue;
|
|
147330
|
-
if (minLimit === undefined || limit < minLimit)
|
|
147331
|
-
minLimit = limit;
|
|
147332
|
-
}
|
|
147333
|
-
return minLimit ?? DEFAULT_HISTORIAN_CONTEXT_FALLBACK;
|
|
147510
|
+
return DEFAULT_HISTORIAN_CONTEXT_FALLBACK;
|
|
147334
147511
|
}
|
|
147335
147512
|
|
|
147336
147513
|
// ../plugin/src/hooks/magic-context/event-resolvers.ts
|
|
@@ -147743,13 +147920,13 @@ async function maybeSendUpgradeReminder(deps, sessionId) {
|
|
|
147743
147920
|
init_data_path();
|
|
147744
147921
|
import * as fs2 from "node:fs";
|
|
147745
147922
|
import * as path6 from "node:path";
|
|
147746
|
-
var ANNOUNCEMENT_VERSION = "0.
|
|
147923
|
+
var ANNOUNCEMENT_VERSION = "0.26.0";
|
|
147747
147924
|
var ANNOUNCEMENT_FEATURES = [
|
|
147748
|
-
"
|
|
147749
|
-
"
|
|
147750
|
-
"
|
|
147751
|
-
"
|
|
147752
|
-
"
|
|
147925
|
+
"Faster on large sessions: per-message transform overhead is at least 2x lower on typical passes and up to ~10x lower when history summarization fires (no more multi-second pause on big sessions).",
|
|
147926
|
+
"No more surprise models: the built-in fallback chain is gone. Hidden agents only use the model (and fallback_models) you configure — no confusing 'model not found' for providers you never set up. `doctor` now records every historian run so real failures are visible.",
|
|
147927
|
+
"Anthropic thinking-block fix: clearing old reasoning no longer risks a stale-signature rejection on Claude / Bedrock / proxied-Claude routes. Plus fewer prompt-cache busts.",
|
|
147928
|
+
"Community fixes: TUI crash on the upgrade progress panel (#168), historian.disallowed_tools for weak models that loop on tool calls (#166), and a Pi-only config key leak (#167).",
|
|
147929
|
+
"New: doctor migrate-session re-homes a session (and optionally its memories) to another project, with a dry-run preview."
|
|
147753
147930
|
];
|
|
147754
147931
|
var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/F2uWxjGnU";
|
|
147755
147932
|
var STATE_FILENAME = "last_announced_version";
|
|
@@ -147808,15 +147985,9 @@ function shouldKeepSubagents() {
|
|
|
147808
147985
|
init_logger();
|
|
147809
147986
|
|
|
147810
147987
|
// ../plugin/src/shared/resolve-fallbacks.ts
|
|
147811
|
-
function resolveFallbackChain(
|
|
147988
|
+
function resolveFallbackChain(userFallbacks) {
|
|
147812
147989
|
const userList = normalizeUserFallbacks(userFallbacks);
|
|
147813
|
-
|
|
147814
|
-
return dedupe(userList.filter(isValidModelSpec));
|
|
147815
|
-
}
|
|
147816
|
-
const builtin = getAgentFallbackModels(agentName);
|
|
147817
|
-
if (!builtin || builtin.length === 0)
|
|
147818
|
-
return [];
|
|
147819
|
-
return dedupe(builtin.filter(isValidModelSpec));
|
|
147990
|
+
return dedupe(userList.filter(isValidModelSpec));
|
|
147820
147991
|
}
|
|
147821
147992
|
function normalizeUserFallbacks(userFallbacks) {
|
|
147822
147993
|
if (!userFallbacks)
|
|
@@ -148693,7 +148864,7 @@ function enqueueDream(db, projectIdentity, reason, force = false) {
|
|
|
148693
148864
|
return db.transaction(() => {
|
|
148694
148865
|
if (!hasActiveDreamLease(db)) {
|
|
148695
148866
|
const staleThresholdMs = force ? 2 * 60 * 1000 : 120 * 60 * 1000;
|
|
148696
|
-
db.prepare("DELETE FROM dream_queue WHERE project_path = ? AND started_at IS NOT NULL AND started_at < ?").run(
|
|
148867
|
+
db.prepare("DELETE FROM dream_queue WHERE project_path = ? AND started_at IS NOT NULL AND started_at < ?").run(projectIdentity, now - staleThresholdMs);
|
|
148697
148868
|
}
|
|
148698
148869
|
const existing = db.prepare("SELECT id FROM dream_queue WHERE project_path = ?").get(projectIdentity);
|
|
148699
148870
|
if (existing) {
|
|
@@ -148755,6 +148926,9 @@ init_logger();
|
|
|
148755
148926
|
import { existsSync as existsSync8 } from "node:fs";
|
|
148756
148927
|
import { join as join11 } from "node:path";
|
|
148757
148928
|
|
|
148929
|
+
// ../plugin/src/agents/dreamer.ts
|
|
148930
|
+
var DREAMER_AGENT = "dreamer";
|
|
148931
|
+
|
|
148758
148932
|
// ../plugin/src/shared/index.ts
|
|
148759
148933
|
init_logger();
|
|
148760
148934
|
|
|
@@ -148828,9 +149002,11 @@ async function promptWithTimeout(client, args, timeoutMs, signal) {
|
|
|
148828
149002
|
});
|
|
148829
149003
|
} catch (error) {
|
|
148830
149004
|
if (signal?.aborted) {
|
|
149005
|
+
await abortChildRun(client, args.path.id);
|
|
148831
149006
|
throw new Error("prompt aborted by external signal");
|
|
148832
149007
|
}
|
|
148833
149008
|
if (controller.signal.aborted) {
|
|
149009
|
+
await abortChildRun(client, args.path.id);
|
|
148834
149010
|
throw new Error(`prompt timed out after ${timeoutMs}ms`);
|
|
148835
149011
|
}
|
|
148836
149012
|
throw error;
|
|
@@ -148839,6 +149015,13 @@ async function promptWithTimeout(client, args, timeoutMs, signal) {
|
|
|
148839
149015
|
signal?.removeEventListener("abort", onExternalAbort);
|
|
148840
149016
|
}
|
|
148841
149017
|
}
|
|
149018
|
+
async function abortChildRun(client, sessionId) {
|
|
149019
|
+
try {
|
|
149020
|
+
await client.session.abort({ path: { id: sessionId } });
|
|
149021
|
+
} catch (error) {
|
|
149022
|
+
log(`[model-retry] child session abort failed for ${sessionId}: ${String(error)}`);
|
|
149023
|
+
}
|
|
149024
|
+
}
|
|
148842
149025
|
function isNonRetryable(error, externalSignal) {
|
|
148843
149026
|
if (externalSignal?.aborted)
|
|
148844
149027
|
return true;
|
|
@@ -149695,6 +149878,20 @@ function getDistinctStoredModelIds(db, projectPath) {
|
|
|
149695
149878
|
const rows = getDistinctStoredModelIdsStatement(db).all(projectPath);
|
|
149696
149879
|
return new Set(rows.map((row) => typeof row.modelId === "string" ? row.modelId : null));
|
|
149697
149880
|
}
|
|
149881
|
+
function getMemoryEmbedCoverage(db, projectPath, modelId) {
|
|
149882
|
+
const row = db.prepare(`SELECT
|
|
149883
|
+
COUNT(*) AS total,
|
|
149884
|
+
SUM(CASE WHEN EXISTS (
|
|
149885
|
+
SELECT 1 FROM memory_embeddings e
|
|
149886
|
+
WHERE e.memory_id = m.id AND e.model_id = ?
|
|
149887
|
+
) THEN 1 ELSE 0 END) AS embedded
|
|
149888
|
+
FROM memories m
|
|
149889
|
+
WHERE m.project_path = ? AND m.status = 'active'`).get(modelId, projectPath);
|
|
149890
|
+
return {
|
|
149891
|
+
total: typeof row?.total === "number" ? row.total : 0,
|
|
149892
|
+
embedded: typeof row?.embedded === "number" ? row.embedded : 0
|
|
149893
|
+
};
|
|
149894
|
+
}
|
|
149698
149895
|
|
|
149699
149896
|
// ../plugin/src/features/magic-context/memory/embedding-cache.ts
|
|
149700
149897
|
var DEFAULT_EMBEDDING_CACHE_TTL_MS = 60000;
|
|
@@ -150532,6 +150729,7 @@ ${modeIntro}
|
|
|
150532
150729
|
4. **Write or update** using the Write tool. Always write to project root, NOT to .planning/.
|
|
150533
150730
|
|
|
150534
150731
|
### Rules
|
|
150732
|
+
- **NEVER touch protected regions**: any content between \`<!-- mc:protected START ... -->\` and \`<!-- mc:protected END -->\` is hand-authored and cache-critical. Reproduce it BYTE-FOR-BYTE in your rewrite — do not edit, reword, reorder, summarize, trim, or drop a single line of it, and keep the marker comments themselves. Only a human edits that region.
|
|
150535
150733
|
- **Be prescriptive**: "Use X pattern" not "X pattern is used"
|
|
150536
150734
|
- **Always include file paths** in backticks
|
|
150537
150735
|
- **Write current state only**: no temporal language, no history
|
|
@@ -166170,14 +166368,16 @@ var SidekickConfigSchema = AgentOverrideConfigSchema.extend({
|
|
|
166170
166368
|
}).optional();
|
|
166171
166369
|
var HistorianConfigSchema = AgentOverrideConfigSchema.extend({
|
|
166172
166370
|
two_pass: exports_external.boolean().default(false).describe("Run a second editor pass over historian output to clean low-signal U: lines and cross-compartment duplicates. Adds ~1 extra API call and ~1.3x cost per historian run. Useful for models without extended thinking support. (default: false)"),
|
|
166173
|
-
thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level passed as --thinking <level> to Pi historian subagent invocations. Required when using reasoning models (e.g. github-copilot/gpt-5.4) because Pi's default thinking-level resolution can pick a value the provider rejects. OpenCode users set variant instead. Valid: off | minimal | low | medium | high | xhigh")
|
|
166371
|
+
thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level passed as --thinking <level> to Pi historian subagent invocations. Required when using reasoning models (e.g. github-copilot/gpt-5.4) because Pi's default thinking-level resolution can pick a value the provider rejects. OpenCode users set variant instead. Valid: off | minimal | low | medium | high | xhigh"),
|
|
166372
|
+
disallowed_tools: exports_external.array(exports_external.enum(["*", "read", "aft_outline", "aft_zoom", "aft_search"])).default([]).describe(`OpenCode only. Tools to REMOVE from the historian's default allow-list [read, aft_outline, aft_zoom, aft_search]. Applies to both historian and historian-editor agents. Use ["*"] to strip all tool definitions from the model request — this prevents weak instruction-following models (e.g. mistral-small-latest) from entering tool-calling loops. Individual tool names remove just that tool. Note: a user-supplied historian.permission override can re-allow a tool that disallowed_tools removed — disallowed_tools sets the baseline, permission overrides take precedence. (default: [])`)
|
|
166174
166373
|
}).optional();
|
|
166175
166374
|
var BaseEmbeddingConfigSchema = exports_external.object({
|
|
166176
166375
|
provider: exports_external.enum(["local", "openai-compatible", "off"]).default("local").describe("Embedding provider. 'local' uses Xenova/all-MiniLM-L6-v2, 'openai-compatible' requires endpoint and model, 'off' disables embeddings."),
|
|
166177
166376
|
model: exports_external.string().optional().describe("Embedding model name. Required for openai-compatible, ignored for local."),
|
|
166178
166377
|
endpoint: exports_external.string().optional().describe("API endpoint URL. Required when provider is openai-compatible."),
|
|
166179
166378
|
api_key: exports_external.string().optional().describe("API key for remote embedding provider (optional)"),
|
|
166180
|
-
input_type: exports_external.string().optional().describe("
|
|
166379
|
+
input_type: exports_external.string().optional().describe("Default input_type for stored/indexed (passage) embeddings in the request body. Required by some openai-compatible providers (e.g. NVIDIA NIM). Omitted from the request when unset."),
|
|
166380
|
+
query_input_type: exports_external.string().optional().describe("Optional input_type for query (search) embeddings on asymmetric models (e.g. NVIDIA NIM 'query'). When unset, query embeddings use embedding.input_type. Passage/stored content always uses embedding.input_type."),
|
|
166181
166381
|
truncate: exports_external.string().optional().describe("Optional truncate mode sent in the embedding request body (e.g. NVIDIA NIM accepts 'NONE' | 'START' | 'END'). Omitted from the request when unset."),
|
|
166182
166382
|
max_input_tokens: exports_external.number().int().positive().optional().describe("Optional maximum input tokens for chunk embeddings. Defaults conservatively to 512 when omitted.")
|
|
166183
166383
|
}).superRefine((data, ctx) => {
|
|
@@ -166207,6 +166407,7 @@ var EmbeddingConfigSchema = BaseEmbeddingConfigSchema.transform((data) => {
|
|
|
166207
166407
|
if (data.provider === "openai-compatible") {
|
|
166208
166408
|
const apiKey = data.api_key?.trim();
|
|
166209
166409
|
const inputType = data.input_type?.trim();
|
|
166410
|
+
const queryInputType = data.query_input_type?.trim();
|
|
166210
166411
|
const truncate = data.truncate?.trim();
|
|
166211
166412
|
return {
|
|
166212
166413
|
provider: "openai-compatible",
|
|
@@ -166214,6 +166415,7 @@ var EmbeddingConfigSchema = BaseEmbeddingConfigSchema.transform((data) => {
|
|
|
166214
166415
|
endpoint: data.endpoint?.trim() ?? "",
|
|
166215
166416
|
...apiKey ? { api_key: apiKey } : {},
|
|
166216
166417
|
...inputType ? { input_type: inputType } : {},
|
|
166418
|
+
...queryInputType ? { query_input_type: queryInputType } : {},
|
|
166217
166419
|
...truncate ? { truncate } : {},
|
|
166218
166420
|
...data.max_input_tokens ? { max_input_tokens: data.max_input_tokens } : {}
|
|
166219
166421
|
};
|
|
@@ -166493,6 +166695,16 @@ function buildCanonicalChunkTextFromFts(db, sessionId, startOrdinal, endOrdinal)
|
|
|
166493
166695
|
return lines.join(`
|
|
166494
166696
|
`);
|
|
166495
166697
|
}
|
|
166698
|
+
function buildCompartmentSummaryFallbackText(db, compartmentId) {
|
|
166699
|
+
const row = db.prepare("SELECT title, p1, content FROM compartments WHERE id = ?").get(compartmentId);
|
|
166700
|
+
if (!row)
|
|
166701
|
+
return "";
|
|
166702
|
+
const title = typeof row.title === "string" ? row.title.trim() : "";
|
|
166703
|
+
const p1 = typeof row.p1 === "string" ? row.p1.trim() : "";
|
|
166704
|
+
const body = p1.length > 0 ? p1 : typeof row.content === "string" ? row.content.trim() : "";
|
|
166705
|
+
return [title, body].filter((s) => s.length > 0).join(`
|
|
166706
|
+
`);
|
|
166707
|
+
}
|
|
166496
166708
|
function canonicalizeInMemoryChunkTextForEmbedding(chunkText, startOrdinal, endOrdinal) {
|
|
166497
166709
|
const lines = [];
|
|
166498
166710
|
for (const rawLine of chunkText.split(/\r?\n/)) {
|
|
@@ -166736,6 +166948,28 @@ function countUnembeddedSessionCompartments(db, projectPath, sessionId, modelId)
|
|
|
166736
166948
|
)`).get(projectPath, sessionId, projectPath, modelId);
|
|
166737
166949
|
return typeof row?.n === "number" ? row.n : 0;
|
|
166738
166950
|
}
|
|
166951
|
+
function countSessionCompartmentEmbedCoverage(db, projectPath, sessionId, modelId) {
|
|
166952
|
+
const row = db.prepare(`SELECT
|
|
166953
|
+
COUNT(*) AS total,
|
|
166954
|
+
SUM(CASE WHEN EXISTS (
|
|
166955
|
+
SELECT 1 FROM compartment_chunk_embeddings e
|
|
166956
|
+
WHERE e.compartment_id = c.id
|
|
166957
|
+
AND e.project_path = ?
|
|
166958
|
+
AND e.model_id = ?
|
|
166959
|
+
) THEN 1 ELSE 0 END) AS embedded
|
|
166960
|
+
FROM compartments c
|
|
166961
|
+
JOIN session_projects sp
|
|
166962
|
+
ON sp.session_id = c.session_id
|
|
166963
|
+
AND sp.harness = c.harness
|
|
166964
|
+
AND sp.project_path = ?
|
|
166965
|
+
WHERE c.session_id = ?
|
|
166966
|
+
AND c.start_message IS NOT NULL
|
|
166967
|
+
AND c.end_message IS NOT NULL`).get(projectPath, modelId, projectPath, sessionId);
|
|
166968
|
+
return {
|
|
166969
|
+
total: typeof row?.total === "number" ? row.total : 0,
|
|
166970
|
+
embedded: typeof row?.embedded === "number" ? row.embedded : 0
|
|
166971
|
+
};
|
|
166972
|
+
}
|
|
166739
166973
|
|
|
166740
166974
|
// ../plugin/src/features/magic-context/memory/cosine-similarity.ts
|
|
166741
166975
|
function cosineSimilarity(a, b) {
|
|
@@ -166878,6 +167112,19 @@ async function withQuietConsole(fn) {
|
|
|
166878
167112
|
console.error = origError;
|
|
166879
167113
|
}
|
|
166880
167114
|
}
|
|
167115
|
+
var nativeRuntimeMissing = false;
|
|
167116
|
+
function isNativeRuntimeMissingError(error51) {
|
|
167117
|
+
const message = error51 instanceof Error ? error51.message : String(error51 ?? "");
|
|
167118
|
+
const lower = message.toLowerCase();
|
|
167119
|
+
const code = error51?.code;
|
|
167120
|
+
const name2 = error51?.name;
|
|
167121
|
+
if (code === "ERR_DLOPEN_FAILED" && lower.includes("onnxruntime")) {
|
|
167122
|
+
return true;
|
|
167123
|
+
}
|
|
167124
|
+
if (!lower.includes("onnxruntime-node"))
|
|
167125
|
+
return false;
|
|
167126
|
+
return code === "ERR_MODULE_NOT_FOUND" || name2 === "ResolveMessage" || lower.includes("cannot find package") || lower.includes("cannot find module") || lower.includes("err_module_not_found");
|
|
167127
|
+
}
|
|
166881
167128
|
function isTransientLoadError(error51) {
|
|
166882
167129
|
const message = error51 instanceof Error ? error51.message : String(error51 ?? "");
|
|
166883
167130
|
if (!message)
|
|
@@ -166942,6 +167189,9 @@ class LocalEmbeddingProvider {
|
|
|
166942
167189
|
if (this.pipeline) {
|
|
166943
167190
|
return true;
|
|
166944
167191
|
}
|
|
167192
|
+
if (nativeRuntimeMissing) {
|
|
167193
|
+
return false;
|
|
167194
|
+
}
|
|
166945
167195
|
if (this.initPromise) {
|
|
166946
167196
|
await this.initPromise;
|
|
166947
167197
|
return this.pipeline !== null;
|
|
@@ -167008,7 +167258,12 @@ class LocalEmbeddingProvider {
|
|
|
167008
167258
|
await releaseLock();
|
|
167009
167259
|
}
|
|
167010
167260
|
} catch (error51) {
|
|
167011
|
-
|
|
167261
|
+
if (isNativeRuntimeMissingError(error51)) {
|
|
167262
|
+
nativeRuntimeMissing = true;
|
|
167263
|
+
log("[magic-context] local embedding runtime is not installed (onnxruntime-node missing from this install). Local embeddings are disabled. Fix: reinstall the plugin (run `npx @wolfx/magic-context@latest doctor --force`), or configure an `openai-compatible`/`ollama` embedding endpoint instead. Existing memories are unaffected.");
|
|
167264
|
+
} else {
|
|
167265
|
+
log("[magic-context] embedding model failed to load:", error51);
|
|
167266
|
+
}
|
|
167012
167267
|
this.pipeline = null;
|
|
167013
167268
|
} finally {
|
|
167014
167269
|
this.initPromise = null;
|
|
@@ -167034,7 +167289,7 @@ class LocalEmbeddingProvider {
|
|
|
167034
167289
|
waiter();
|
|
167035
167290
|
}
|
|
167036
167291
|
}
|
|
167037
|
-
async embed(text, signal) {
|
|
167292
|
+
async embed(text, signal, _purpose) {
|
|
167038
167293
|
if (signal?.aborted)
|
|
167039
167294
|
return null;
|
|
167040
167295
|
if (this.disposing)
|
|
@@ -167060,7 +167315,7 @@ class LocalEmbeddingProvider {
|
|
|
167060
167315
|
this.finishInFlight();
|
|
167061
167316
|
}
|
|
167062
167317
|
}
|
|
167063
|
-
async embedBatch(texts, signal) {
|
|
167318
|
+
async embedBatch(texts, signal, _purpose) {
|
|
167064
167319
|
if (texts.length === 0) {
|
|
167065
167320
|
return [];
|
|
167066
167321
|
}
|
|
@@ -167199,6 +167454,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
167199
167454
|
model;
|
|
167200
167455
|
apiKey;
|
|
167201
167456
|
inputType;
|
|
167457
|
+
queryInputType;
|
|
167202
167458
|
truncate;
|
|
167203
167459
|
initialized = false;
|
|
167204
167460
|
failureTimes = [];
|
|
@@ -167211,6 +167467,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
167211
167467
|
this.model = options.model?.trim() ?? "";
|
|
167212
167468
|
this.apiKey = options.apiKey?.trim() ?? "";
|
|
167213
167469
|
this.inputType = options.inputType?.trim() ?? "";
|
|
167470
|
+
this.queryInputType = options.queryInputType?.trim() ?? "";
|
|
167214
167471
|
this.truncate = options.truncate?.trim() ?? "";
|
|
167215
167472
|
this.maxInputTokens = typeof options.maxInputTokens === "number" && Number.isFinite(options.maxInputTokens) ? Math.max(1, Math.floor(options.maxInputTokens)) : 512;
|
|
167216
167473
|
this.modelId = getEmbeddingProviderIdentity({
|
|
@@ -167238,11 +167495,17 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
167238
167495
|
this.initialized = true;
|
|
167239
167496
|
return true;
|
|
167240
167497
|
}
|
|
167241
|
-
|
|
167242
|
-
|
|
167498
|
+
resolveInputTypeForPurpose(purpose = "passage") {
|
|
167499
|
+
if (purpose === "query") {
|
|
167500
|
+
return this.queryInputType || this.inputType;
|
|
167501
|
+
}
|
|
167502
|
+
return this.inputType;
|
|
167503
|
+
}
|
|
167504
|
+
async embed(text, signal, purpose) {
|
|
167505
|
+
const [embedding] = await this.embedBatch([text], signal, purpose);
|
|
167243
167506
|
return embedding ?? null;
|
|
167244
167507
|
}
|
|
167245
|
-
async embedBatch(texts, signal) {
|
|
167508
|
+
async embedBatch(texts, signal, purpose) {
|
|
167246
167509
|
if (texts.length === 0) {
|
|
167247
167510
|
return [];
|
|
167248
167511
|
}
|
|
@@ -167268,6 +167531,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
167268
167531
|
if (signal) {
|
|
167269
167532
|
signal.addEventListener("abort", onOuterAbort, { once: true });
|
|
167270
167533
|
}
|
|
167534
|
+
const inputTypeForRequest = this.resolveInputTypeForPurpose(purpose);
|
|
167271
167535
|
const response = await fetch(`${this.endpoint}/embeddings`, {
|
|
167272
167536
|
method: "POST",
|
|
167273
167537
|
headers: {
|
|
@@ -167277,7 +167541,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
167277
167541
|
body: JSON.stringify({
|
|
167278
167542
|
model: this.model,
|
|
167279
167543
|
input: texts,
|
|
167280
|
-
...
|
|
167544
|
+
...inputTypeForRequest ? { input_type: inputTypeForRequest } : {},
|
|
167281
167545
|
...this.truncate ? { truncate: this.truncate } : {}
|
|
167282
167546
|
}),
|
|
167283
167547
|
redirect: "error",
|
|
@@ -167522,6 +167786,118 @@ function getDistinctCommitEmbeddingModelIds(db, projectPath) {
|
|
|
167522
167786
|
return new Set(rows.map((row) => typeof row.modelId === "string" ? row.modelId : null));
|
|
167523
167787
|
}
|
|
167524
167788
|
|
|
167789
|
+
// ../plugin/src/features/magic-context/git-commits/storage-git-commits.ts
|
|
167790
|
+
init_logger();
|
|
167791
|
+
var insertStatements = new WeakMap;
|
|
167792
|
+
var existingShasStatements = new WeakMap;
|
|
167793
|
+
var projectCountStatements = new WeakMap;
|
|
167794
|
+
var evictStatements = new WeakMap;
|
|
167795
|
+
var evictOverflowStatements = new WeakMap;
|
|
167796
|
+
var latestCommitTimeStatements = new WeakMap;
|
|
167797
|
+
function getInsertStatement(db) {
|
|
167798
|
+
let stmt = insertStatements.get(db);
|
|
167799
|
+
if (!stmt) {
|
|
167800
|
+
stmt = db.prepare(`INSERT INTO git_commits (sha, project_path, short_sha, message, author, committed_at, indexed_at)
|
|
167801
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
167802
|
+
ON CONFLICT(sha) DO UPDATE SET
|
|
167803
|
+
project_path = excluded.project_path,
|
|
167804
|
+
short_sha = excluded.short_sha,
|
|
167805
|
+
message = excluded.message,
|
|
167806
|
+
author = excluded.author,
|
|
167807
|
+
committed_at = excluded.committed_at,
|
|
167808
|
+
indexed_at = excluded.indexed_at
|
|
167809
|
+
WHERE git_commits.message != excluded.message`);
|
|
167810
|
+
insertStatements.set(db, stmt);
|
|
167811
|
+
}
|
|
167812
|
+
return stmt;
|
|
167813
|
+
}
|
|
167814
|
+
function getExistingShasStatement(db) {
|
|
167815
|
+
let stmt = existingShasStatements.get(db);
|
|
167816
|
+
if (!stmt) {
|
|
167817
|
+
stmt = db.prepare("SELECT sha FROM git_commits WHERE project_path = ?");
|
|
167818
|
+
existingShasStatements.set(db, stmt);
|
|
167819
|
+
}
|
|
167820
|
+
return stmt;
|
|
167821
|
+
}
|
|
167822
|
+
function getProjectCountStatement(db) {
|
|
167823
|
+
let stmt = projectCountStatements.get(db);
|
|
167824
|
+
if (!stmt) {
|
|
167825
|
+
stmt = db.prepare("SELECT COUNT(*) AS count FROM git_commits WHERE project_path = ?");
|
|
167826
|
+
projectCountStatements.set(db, stmt);
|
|
167827
|
+
}
|
|
167828
|
+
return stmt;
|
|
167829
|
+
}
|
|
167830
|
+
function getLatestCommitTimeStatement(db) {
|
|
167831
|
+
let stmt = latestCommitTimeStatements.get(db);
|
|
167832
|
+
if (!stmt) {
|
|
167833
|
+
stmt = db.prepare("SELECT MAX(committed_at) AS latest FROM git_commits WHERE project_path = ?");
|
|
167834
|
+
latestCommitTimeStatements.set(db, stmt);
|
|
167835
|
+
}
|
|
167836
|
+
return stmt;
|
|
167837
|
+
}
|
|
167838
|
+
function getEvictOverflowStatement(db) {
|
|
167839
|
+
let stmt = evictOverflowStatements.get(db);
|
|
167840
|
+
if (!stmt) {
|
|
167841
|
+
stmt = db.prepare(`DELETE FROM git_commits
|
|
167842
|
+
WHERE rowid IN (
|
|
167843
|
+
SELECT rowid FROM git_commits
|
|
167844
|
+
WHERE project_path = ?
|
|
167845
|
+
ORDER BY committed_at DESC, sha DESC
|
|
167846
|
+
LIMIT -1 OFFSET ?
|
|
167847
|
+
)`);
|
|
167848
|
+
evictOverflowStatements.set(db, stmt);
|
|
167849
|
+
}
|
|
167850
|
+
return stmt;
|
|
167851
|
+
}
|
|
167852
|
+
function upsertCommits(db, projectPath, commits) {
|
|
167853
|
+
if (commits.length === 0)
|
|
167854
|
+
return { inserted: 0, updated: 0 };
|
|
167855
|
+
const existing = new Set;
|
|
167856
|
+
for (const row of getExistingShasStatement(db).all(projectPath)) {
|
|
167857
|
+
existing.add(row.sha);
|
|
167858
|
+
}
|
|
167859
|
+
let inserted = 0;
|
|
167860
|
+
let updated = 0;
|
|
167861
|
+
const now = Date.now();
|
|
167862
|
+
const insertStmt = getInsertStatement(db);
|
|
167863
|
+
db.transaction(() => {
|
|
167864
|
+
for (const commit of commits) {
|
|
167865
|
+
const result = insertStmt.run(commit.sha, projectPath, commit.shortSha, commit.message, commit.author, commit.committedAtMs, now);
|
|
167866
|
+
if (result.changes > 0) {
|
|
167867
|
+
if (existing.has(commit.sha)) {
|
|
167868
|
+
updated++;
|
|
167869
|
+
} else {
|
|
167870
|
+
inserted++;
|
|
167871
|
+
existing.add(commit.sha);
|
|
167872
|
+
}
|
|
167873
|
+
}
|
|
167874
|
+
}
|
|
167875
|
+
})();
|
|
167876
|
+
return { inserted, updated };
|
|
167877
|
+
}
|
|
167878
|
+
function getCommitCount(db, projectPath) {
|
|
167879
|
+
const row = getProjectCountStatement(db).get(projectPath);
|
|
167880
|
+
return row?.count ?? 0;
|
|
167881
|
+
}
|
|
167882
|
+
function getLatestIndexedCommitTimeMs(db, projectPath) {
|
|
167883
|
+
const row = getLatestCommitTimeStatement(db).get(projectPath);
|
|
167884
|
+
return row?.latest ?? null;
|
|
167885
|
+
}
|
|
167886
|
+
function enforceProjectCap(db, projectPath, maxCommits) {
|
|
167887
|
+
if (maxCommits <= 0)
|
|
167888
|
+
return 0;
|
|
167889
|
+
const count = getCommitCount(db, projectPath);
|
|
167890
|
+
if (count <= maxCommits)
|
|
167891
|
+
return 0;
|
|
167892
|
+
getEvictOverflowStatement(db).run(projectPath, maxCommits);
|
|
167893
|
+
const after = getCommitCount(db, projectPath);
|
|
167894
|
+
const evicted = Math.max(0, count - after);
|
|
167895
|
+
if (evicted > 0) {
|
|
167896
|
+
log(`[git-commits] evicted ${evicted} oldest commits for project ${projectPath} (cap=${maxCommits}, was=${count})`);
|
|
167897
|
+
}
|
|
167898
|
+
return evicted;
|
|
167899
|
+
}
|
|
167900
|
+
|
|
167525
167901
|
// ../plugin/src/features/magic-context/git-commits/sweep-coordinator.ts
|
|
167526
167902
|
var GIT_SWEEP_COOLDOWN_MS = 10 * 60 * 1000;
|
|
167527
167903
|
var GIT_SWEEP_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
@@ -167716,8 +168092,12 @@ function repairMisScopedCompartmentChunkEmbeddingsForProject(db, projectPath) {
|
|
|
167716
168092
|
var OFF_PROVIDER_IDENTITY = "embedding-provider:off";
|
|
167717
168093
|
var SWEEP_MAX_WALL_CLOCK_MS = 10 * 60 * 1000;
|
|
167718
168094
|
var CHUNK_DRAIN_BATCH_SIZE = 8;
|
|
167719
|
-
var MAX_WINDOWS_PER_EMBED_CALL =
|
|
168095
|
+
var MAX_WINDOWS_PER_EMBED_CALL = 2;
|
|
167720
168096
|
var SESSION_EMBED_LEASE_RENEWAL_MS = 60 * 1000;
|
|
168097
|
+
var EMBED_SLICE_RETRY_ATTEMPTS = 3;
|
|
168098
|
+
var EMBED_SLICE_RETRY_BASE_MS = 250;
|
|
168099
|
+
var EMBED_SLOW_FAILURE_NO_RETRY_MS = 1e4;
|
|
168100
|
+
var MAX_CONSECUTIVE_FAILED_BATCHES = 3;
|
|
167721
168101
|
var projectRegistrations = new Map;
|
|
167722
168102
|
var loadUnembeddedMemoriesStatements = new WeakMap;
|
|
167723
168103
|
var globalRegistrationGeneration = 0;
|
|
@@ -167735,6 +168115,7 @@ function resolveEmbeddingConfig(config2) {
|
|
|
167735
168115
|
if (config2.provider === "openai-compatible") {
|
|
167736
168116
|
const apiKey = config2.api_key?.trim();
|
|
167737
168117
|
const inputType = config2.input_type?.trim();
|
|
168118
|
+
const queryInputType = config2.query_input_type?.trim();
|
|
167738
168119
|
const truncate = config2.truncate?.trim();
|
|
167739
168120
|
return {
|
|
167740
168121
|
provider: "openai-compatible",
|
|
@@ -167742,6 +168123,7 @@ function resolveEmbeddingConfig(config2) {
|
|
|
167742
168123
|
endpoint: config2.endpoint.trim(),
|
|
167743
168124
|
...apiKey ? { api_key: apiKey } : {},
|
|
167744
168125
|
...inputType ? { input_type: inputType } : {},
|
|
168126
|
+
...queryInputType ? { query_input_type: queryInputType } : {},
|
|
167745
168127
|
...truncate ? { truncate } : {},
|
|
167746
168128
|
...config2.max_input_tokens ? {
|
|
167747
168129
|
max_input_tokens: normalizeCompartmentChunkMaxInputTokens(config2.max_input_tokens)
|
|
@@ -167763,6 +168145,7 @@ function createProvider(config2) {
|
|
|
167763
168145
|
model: config2.model,
|
|
167764
168146
|
apiKey: config2.api_key,
|
|
167765
168147
|
inputType: config2.input_type,
|
|
168148
|
+
queryInputType: config2.query_input_type,
|
|
167766
168149
|
truncate: config2.truncate,
|
|
167767
168150
|
maxInputTokens: config2.max_input_tokens
|
|
167768
168151
|
});
|
|
@@ -167817,7 +168200,9 @@ function snapshotFor(registration) {
|
|
|
167817
168200
|
enabled,
|
|
167818
168201
|
gitCommitEnabled,
|
|
167819
168202
|
modelId: registration.observationMode || !providerIsOn ? "off" : registration.modelId,
|
|
167820
|
-
chunkModelId: registration.observationMode || !providerIsOn ? "off" : registration.chunkModelId
|
|
168203
|
+
chunkModelId: registration.observationMode || !providerIsOn ? "off" : registration.chunkModelId,
|
|
168204
|
+
model: registration.observationMode || !providerIsOn ? "off" : ("model" in registration.config) && registration.config.model.trim() ? registration.config.model.trim() : registration.modelId,
|
|
168205
|
+
provider: registration.observationMode || !providerIsOn ? "off" : registration.config.provider ?? "local"
|
|
167821
168206
|
};
|
|
167822
168207
|
}
|
|
167823
168208
|
function disposeProvider(provider) {
|
|
@@ -167943,7 +168328,7 @@ function getOrCreateProjectProvider(registration) {
|
|
|
167943
168328
|
registration.provider = provider;
|
|
167944
168329
|
return provider;
|
|
167945
168330
|
}
|
|
167946
|
-
async function embedTextForProject(projectIdentity, text, signal) {
|
|
168331
|
+
async function embedTextForProject(projectIdentity, text, signal, purpose = "passage") {
|
|
167947
168332
|
const registration = projectRegistrations.get(projectIdentity);
|
|
167948
168333
|
if (!registration)
|
|
167949
168334
|
return null;
|
|
@@ -167952,7 +168337,7 @@ async function embedTextForProject(projectIdentity, text, signal) {
|
|
|
167952
168337
|
const provider = getOrCreateProjectProvider(registration);
|
|
167953
168338
|
if (!provider)
|
|
167954
168339
|
return null;
|
|
167955
|
-
const vector = await provider.embed(text, signal);
|
|
168340
|
+
const vector = await provider.embed(text, signal, purpose);
|
|
167956
168341
|
if (!vector)
|
|
167957
168342
|
return null;
|
|
167958
168343
|
const current = projectRegistrations.get(projectIdentity);
|
|
@@ -167961,7 +168346,7 @@ async function embedTextForProject(projectIdentity, text, signal) {
|
|
|
167961
168346
|
}
|
|
167962
168347
|
return { vector, modelId, generation };
|
|
167963
168348
|
}
|
|
167964
|
-
async function embedBatchForProject(projectIdentity, texts, signal) {
|
|
168349
|
+
async function embedBatchForProject(projectIdentity, texts, signal, purpose = "passage") {
|
|
167965
168350
|
if (texts.length === 0) {
|
|
167966
168351
|
const registration2 = projectRegistrations.get(projectIdentity);
|
|
167967
168352
|
if (!registration2 || registration2.observationMode)
|
|
@@ -167977,7 +168362,7 @@ async function embedBatchForProject(projectIdentity, texts, signal) {
|
|
|
167977
168362
|
const provider = getOrCreateProjectProvider(registration);
|
|
167978
168363
|
if (!provider)
|
|
167979
168364
|
return null;
|
|
167980
|
-
const vectors = await provider.embedBatch(texts, signal);
|
|
168365
|
+
const vectors = await provider.embedBatch(texts, signal, purpose);
|
|
167981
168366
|
const current = projectRegistrations.get(projectIdentity);
|
|
167982
168367
|
if (!current || current.generation !== generation || current.runtimeFingerprint !== runtimeFingerprint) {
|
|
167983
168368
|
return null;
|
|
@@ -168028,12 +168413,13 @@ async function embedUnembeddedMemoriesForProject(db, projectIdentity, batchSize
|
|
|
168028
168413
|
}
|
|
168029
168414
|
async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates, signal) {
|
|
168030
168415
|
const noWork = [];
|
|
168416
|
+
const failed = [];
|
|
168031
168417
|
if (candidates.length === 0)
|
|
168032
|
-
return { embedded: 0, noWork };
|
|
168418
|
+
return { embedded: 0, noWork, failed };
|
|
168033
168419
|
const maxInputTokens = getProjectEmbeddingMaxInputTokens(projectIdentity);
|
|
168034
168420
|
const prepared = [];
|
|
168035
168421
|
for (const candidate of candidates) {
|
|
168036
|
-
const canonicalText = buildCanonicalChunkTextFromFts(db, candidate.sessionId, candidate.startMessage, candidate.endMessage);
|
|
168422
|
+
const canonicalText = buildCanonicalChunkTextFromFts(db, candidate.sessionId, candidate.startMessage, candidate.endMessage) || buildCompartmentSummaryFallbackText(db, candidate.id);
|
|
168037
168423
|
if (canonicalText.length === 0) {
|
|
168038
168424
|
noWork.push(candidate.id);
|
|
168039
168425
|
continue;
|
|
@@ -168046,7 +168432,7 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
|
|
|
168046
168432
|
prepared.push({ candidate, windows });
|
|
168047
168433
|
}
|
|
168048
168434
|
if (prepared.length === 0)
|
|
168049
|
-
return { embedded: 0, noWork };
|
|
168435
|
+
return { embedded: 0, noWork, failed };
|
|
168050
168436
|
let embedded = 0;
|
|
168051
168437
|
let i = 0;
|
|
168052
168438
|
while (i < prepared.length) {
|
|
@@ -168063,35 +168449,60 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
|
|
|
168063
168449
|
const texts = [];
|
|
168064
168450
|
for (const item of slice)
|
|
168065
168451
|
texts.push(...item.windows.map((w) => w.text));
|
|
168066
|
-
|
|
168067
|
-
|
|
168068
|
-
if (!result)
|
|
168069
|
-
continue;
|
|
168452
|
+
const persistedIds = new Set;
|
|
168453
|
+
for (let attempt = 0;attempt < EMBED_SLICE_RETRY_ATTEMPTS; attempt++) {
|
|
168070
168454
|
if (signal?.aborted)
|
|
168071
168455
|
break;
|
|
168072
|
-
let
|
|
168073
|
-
|
|
168074
|
-
|
|
168075
|
-
|
|
168076
|
-
|
|
168077
|
-
|
|
168456
|
+
let result = null;
|
|
168457
|
+
const attemptStart = Date.now();
|
|
168458
|
+
try {
|
|
168459
|
+
result = await embedBatchForProject(projectIdentity, texts, signal);
|
|
168460
|
+
} catch (error51) {
|
|
168461
|
+
log("[magic-context] failed to proactively embed compartment chunks:", error51);
|
|
168462
|
+
}
|
|
168463
|
+
if (signal?.aborted)
|
|
168464
|
+
break;
|
|
168465
|
+
if (result) {
|
|
168466
|
+
let offset = 0;
|
|
168467
|
+
for (const item of slice) {
|
|
168468
|
+
const vectors = result.vectors.slice(offset, offset + item.windows.length);
|
|
168469
|
+
offset += item.windows.length;
|
|
168470
|
+
if (persistedIds.has(item.candidate.id))
|
|
168471
|
+
continue;
|
|
168472
|
+
if (vectors.length !== item.windows.length || vectors.some((v) => !v)) {
|
|
168473
|
+
continue;
|
|
168474
|
+
}
|
|
168475
|
+
const rows = item.windows.map((window, index) => ({
|
|
168476
|
+
compartmentId: item.candidate.id,
|
|
168477
|
+
sessionId: item.candidate.sessionId,
|
|
168478
|
+
projectPath: projectIdentity,
|
|
168479
|
+
window,
|
|
168480
|
+
modelId,
|
|
168481
|
+
vector: vectors[index]
|
|
168482
|
+
}));
|
|
168483
|
+
replaceCompartmentChunkEmbeddings(db, rows);
|
|
168484
|
+
persistedIds.add(item.candidate.id);
|
|
168078
168485
|
}
|
|
168079
|
-
const rows = item.windows.map((window, index) => ({
|
|
168080
|
-
compartmentId: item.candidate.id,
|
|
168081
|
-
sessionId: item.candidate.sessionId,
|
|
168082
|
-
projectPath: projectIdentity,
|
|
168083
|
-
window,
|
|
168084
|
-
modelId,
|
|
168085
|
-
vector: vectors[index]
|
|
168086
|
-
}));
|
|
168087
|
-
replaceCompartmentChunkEmbeddings(db, rows);
|
|
168088
|
-
embedded += 1;
|
|
168089
168486
|
}
|
|
168090
|
-
|
|
168091
|
-
|
|
168487
|
+
if (persistedIds.size === slice.length)
|
|
168488
|
+
break;
|
|
168489
|
+
if (persistedIds.size > 0)
|
|
168490
|
+
break;
|
|
168491
|
+
if (Date.now() - attemptStart >= EMBED_SLOW_FAILURE_NO_RETRY_MS)
|
|
168492
|
+
break;
|
|
168493
|
+
if (attempt < EMBED_SLICE_RETRY_ATTEMPTS - 1) {
|
|
168494
|
+
await new Promise((resolve4) => setTimeout(resolve4, EMBED_SLICE_RETRY_BASE_MS * 2 ** attempt));
|
|
168495
|
+
}
|
|
168496
|
+
}
|
|
168497
|
+
embedded += persistedIds.size;
|
|
168498
|
+
if (!signal?.aborted) {
|
|
168499
|
+
for (const item of slice) {
|
|
168500
|
+
if (!persistedIds.has(item.candidate.id))
|
|
168501
|
+
failed.push(item.candidate.id);
|
|
168502
|
+
}
|
|
168092
168503
|
}
|
|
168093
168504
|
}
|
|
168094
|
-
return { embedded, noWork };
|
|
168505
|
+
return { embedded, noWork, failed };
|
|
168095
168506
|
}
|
|
168096
168507
|
async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, options) {
|
|
168097
168508
|
const snapshot = getProjectEmbeddingSnapshot(projectIdentity);
|
|
@@ -168114,9 +168525,11 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
|
|
|
168114
168525
|
renewal.unref?.();
|
|
168115
168526
|
const batchSize = Math.max(1, options?.batchSize ?? CHUNK_DRAIN_BATCH_SIZE);
|
|
168116
168527
|
const skipIds = [];
|
|
168528
|
+
const failedIds = [];
|
|
168117
168529
|
let embedded = 0;
|
|
168118
168530
|
let aborted2 = false;
|
|
168119
|
-
let
|
|
168531
|
+
let providerDown = false;
|
|
168532
|
+
let consecutiveFailedBatches = 0;
|
|
168120
168533
|
try {
|
|
168121
168534
|
options?.onProgress?.({ embedded, total });
|
|
168122
168535
|
for (;; ) {
|
|
@@ -168124,15 +168537,26 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
|
|
|
168124
168537
|
aborted2 = true;
|
|
168125
168538
|
break;
|
|
168126
168539
|
}
|
|
168127
|
-
const candidates = loadUnembeddedSessionChunkCandidates(db, projectIdentity, sessionId, snapshot.chunkModelId, batchSize, skipIds);
|
|
168540
|
+
const candidates = loadUnembeddedSessionChunkCandidates(db, projectIdentity, sessionId, snapshot.chunkModelId, batchSize, [...skipIds, ...failedIds]);
|
|
168128
168541
|
if (candidates.length === 0)
|
|
168129
168542
|
break;
|
|
168130
|
-
const {
|
|
168543
|
+
const {
|
|
168544
|
+
embedded: n,
|
|
168545
|
+
noWork,
|
|
168546
|
+
failed
|
|
168547
|
+
} = await embedCandidateChunkBatch(db, projectIdentity, snapshot.chunkModelId, candidates, options?.signal);
|
|
168131
168548
|
for (const id of noWork)
|
|
168132
168549
|
skipIds.push(id);
|
|
168550
|
+
for (const id of failed)
|
|
168551
|
+
failedIds.push(id);
|
|
168133
168552
|
if (n === 0 && noWork.length === 0) {
|
|
168134
|
-
|
|
168135
|
-
|
|
168553
|
+
consecutiveFailedBatches += 1;
|
|
168554
|
+
if (consecutiveFailedBatches >= MAX_CONSECUTIVE_FAILED_BATCHES) {
|
|
168555
|
+
providerDown = true;
|
|
168556
|
+
break;
|
|
168557
|
+
}
|
|
168558
|
+
} else {
|
|
168559
|
+
consecutiveFailedBatches = 0;
|
|
168136
168560
|
}
|
|
168137
168561
|
embedded += n;
|
|
168138
168562
|
options?.onProgress?.({ embedded: Math.min(embedded, total), total });
|
|
@@ -168140,16 +168564,50 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
|
|
|
168140
168564
|
}
|
|
168141
168565
|
} finally {
|
|
168142
168566
|
clearInterval(renewal);
|
|
168143
|
-
|
|
168567
|
+
try {
|
|
168568
|
+
releaseGitSweepLease(db, projectIdentity, holderId);
|
|
168569
|
+
} catch (error51) {
|
|
168570
|
+
log("[magic-context] embed drain: lease release failed (will TTL-expire):", error51);
|
|
168571
|
+
}
|
|
168144
168572
|
}
|
|
168145
168573
|
if (aborted2)
|
|
168146
|
-
return { status: "aborted", embedded, total };
|
|
168147
|
-
if (
|
|
168574
|
+
return { status: "aborted", embedded, total, failed: failedIds.length };
|
|
168575
|
+
if (providerDown || failedIds.length > 0) {
|
|
168148
168576
|
const remaining = Math.max(0, countUnembeddedSessionCompartments(db, projectIdentity, sessionId, snapshot.chunkModelId) - skipIds.length);
|
|
168149
|
-
if (remaining > 0)
|
|
168150
|
-
return { status: "stalled", embedded, total, remaining };
|
|
168577
|
+
if (remaining > 0) {
|
|
168578
|
+
return { status: "stalled", embedded, total, remaining, failed: failedIds.length };
|
|
168579
|
+
}
|
|
168151
168580
|
}
|
|
168152
|
-
return { status: "done", embedded, total };
|
|
168581
|
+
return { status: "done", embedded, total, failed: failedIds.length };
|
|
168582
|
+
}
|
|
168583
|
+
function getEmbeddingCoverageStatus(db, projectIdentity, sessionId) {
|
|
168584
|
+
const snapshot = getProjectEmbeddingSnapshot(projectIdentity);
|
|
168585
|
+
if (!snapshot?.enabled || snapshot.chunkModelId === "off") {
|
|
168586
|
+
return {
|
|
168587
|
+
enabled: false,
|
|
168588
|
+
model: snapshot?.model ?? "off",
|
|
168589
|
+
provider: snapshot?.provider ?? "off",
|
|
168590
|
+
session: { embedded: 0, total: 0 },
|
|
168591
|
+
memories: { embedded: 0, total: 0 },
|
|
168592
|
+
commits: { embedded: 0, total: 0, gitEnabled: false }
|
|
168593
|
+
};
|
|
168594
|
+
}
|
|
168595
|
+
const session = countSessionCompartmentEmbedCoverage(db, projectIdentity, sessionId, snapshot.chunkModelId);
|
|
168596
|
+
const memories = getMemoryEmbedCoverage(db, projectIdentity, snapshot.modelId);
|
|
168597
|
+
const gitEnabled = snapshot.gitCommitEnabled;
|
|
168598
|
+
const commits = gitEnabled ? {
|
|
168599
|
+
embedded: countEmbeddedCommits(db, projectIdentity),
|
|
168600
|
+
total: getCommitCount(db, projectIdentity),
|
|
168601
|
+
gitEnabled: true
|
|
168602
|
+
} : { embedded: 0, total: 0, gitEnabled: false };
|
|
168603
|
+
return {
|
|
168604
|
+
enabled: true,
|
|
168605
|
+
model: snapshot.model,
|
|
168606
|
+
provider: snapshot.provider,
|
|
168607
|
+
session,
|
|
168608
|
+
memories,
|
|
168609
|
+
commits
|
|
168610
|
+
};
|
|
168153
168611
|
}
|
|
168154
168612
|
|
|
168155
168613
|
// ../plugin/src/features/magic-context/memory/embedding.ts
|
|
@@ -168170,6 +168628,7 @@ function createProvider2(config2) {
|
|
|
168170
168628
|
model: config2.model,
|
|
168171
168629
|
apiKey: config2.api_key,
|
|
168172
168630
|
inputType: config2.input_type,
|
|
168631
|
+
queryInputType: config2.query_input_type,
|
|
168173
168632
|
truncate: config2.truncate,
|
|
168174
168633
|
maxInputTokens: config2.max_input_tokens
|
|
168175
168634
|
});
|
|
@@ -168198,118 +168657,6 @@ async function embedText(text, signal) {
|
|
|
168198
168657
|
}
|
|
168199
168658
|
var SWEEP_MAX_WALL_CLOCK_MS2 = 10 * 60 * 1000;
|
|
168200
168659
|
|
|
168201
|
-
// ../plugin/src/features/magic-context/git-commits/storage-git-commits.ts
|
|
168202
|
-
init_logger();
|
|
168203
|
-
var insertStatements = new WeakMap;
|
|
168204
|
-
var existingShasStatements = new WeakMap;
|
|
168205
|
-
var projectCountStatements = new WeakMap;
|
|
168206
|
-
var evictStatements = new WeakMap;
|
|
168207
|
-
var evictOverflowStatements = new WeakMap;
|
|
168208
|
-
var latestCommitTimeStatements = new WeakMap;
|
|
168209
|
-
function getInsertStatement(db) {
|
|
168210
|
-
let stmt = insertStatements.get(db);
|
|
168211
|
-
if (!stmt) {
|
|
168212
|
-
stmt = db.prepare(`INSERT INTO git_commits (sha, project_path, short_sha, message, author, committed_at, indexed_at)
|
|
168213
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
168214
|
-
ON CONFLICT(sha) DO UPDATE SET
|
|
168215
|
-
project_path = excluded.project_path,
|
|
168216
|
-
short_sha = excluded.short_sha,
|
|
168217
|
-
message = excluded.message,
|
|
168218
|
-
author = excluded.author,
|
|
168219
|
-
committed_at = excluded.committed_at,
|
|
168220
|
-
indexed_at = excluded.indexed_at
|
|
168221
|
-
WHERE git_commits.message != excluded.message`);
|
|
168222
|
-
insertStatements.set(db, stmt);
|
|
168223
|
-
}
|
|
168224
|
-
return stmt;
|
|
168225
|
-
}
|
|
168226
|
-
function getExistingShasStatement(db) {
|
|
168227
|
-
let stmt = existingShasStatements.get(db);
|
|
168228
|
-
if (!stmt) {
|
|
168229
|
-
stmt = db.prepare("SELECT sha FROM git_commits WHERE project_path = ?");
|
|
168230
|
-
existingShasStatements.set(db, stmt);
|
|
168231
|
-
}
|
|
168232
|
-
return stmt;
|
|
168233
|
-
}
|
|
168234
|
-
function getProjectCountStatement(db) {
|
|
168235
|
-
let stmt = projectCountStatements.get(db);
|
|
168236
|
-
if (!stmt) {
|
|
168237
|
-
stmt = db.prepare("SELECT COUNT(*) AS count FROM git_commits WHERE project_path = ?");
|
|
168238
|
-
projectCountStatements.set(db, stmt);
|
|
168239
|
-
}
|
|
168240
|
-
return stmt;
|
|
168241
|
-
}
|
|
168242
|
-
function getLatestCommitTimeStatement(db) {
|
|
168243
|
-
let stmt = latestCommitTimeStatements.get(db);
|
|
168244
|
-
if (!stmt) {
|
|
168245
|
-
stmt = db.prepare("SELECT MAX(committed_at) AS latest FROM git_commits WHERE project_path = ?");
|
|
168246
|
-
latestCommitTimeStatements.set(db, stmt);
|
|
168247
|
-
}
|
|
168248
|
-
return stmt;
|
|
168249
|
-
}
|
|
168250
|
-
function getEvictOverflowStatement(db) {
|
|
168251
|
-
let stmt = evictOverflowStatements.get(db);
|
|
168252
|
-
if (!stmt) {
|
|
168253
|
-
stmt = db.prepare(`DELETE FROM git_commits
|
|
168254
|
-
WHERE rowid IN (
|
|
168255
|
-
SELECT rowid FROM git_commits
|
|
168256
|
-
WHERE project_path = ?
|
|
168257
|
-
ORDER BY committed_at DESC, sha DESC
|
|
168258
|
-
LIMIT -1 OFFSET ?
|
|
168259
|
-
)`);
|
|
168260
|
-
evictOverflowStatements.set(db, stmt);
|
|
168261
|
-
}
|
|
168262
|
-
return stmt;
|
|
168263
|
-
}
|
|
168264
|
-
function upsertCommits(db, projectPath, commits) {
|
|
168265
|
-
if (commits.length === 0)
|
|
168266
|
-
return { inserted: 0, updated: 0 };
|
|
168267
|
-
const existing = new Set;
|
|
168268
|
-
for (const row of getExistingShasStatement(db).all(projectPath)) {
|
|
168269
|
-
existing.add(row.sha);
|
|
168270
|
-
}
|
|
168271
|
-
let inserted = 0;
|
|
168272
|
-
let updated = 0;
|
|
168273
|
-
const now = Date.now();
|
|
168274
|
-
const insertStmt = getInsertStatement(db);
|
|
168275
|
-
db.transaction(() => {
|
|
168276
|
-
for (const commit of commits) {
|
|
168277
|
-
const result = insertStmt.run(commit.sha, projectPath, commit.shortSha, commit.message, commit.author, commit.committedAtMs, now);
|
|
168278
|
-
if (result.changes > 0) {
|
|
168279
|
-
if (existing.has(commit.sha)) {
|
|
168280
|
-
updated++;
|
|
168281
|
-
} else {
|
|
168282
|
-
inserted++;
|
|
168283
|
-
existing.add(commit.sha);
|
|
168284
|
-
}
|
|
168285
|
-
}
|
|
168286
|
-
}
|
|
168287
|
-
})();
|
|
168288
|
-
return { inserted, updated };
|
|
168289
|
-
}
|
|
168290
|
-
function getCommitCount(db, projectPath) {
|
|
168291
|
-
const row = getProjectCountStatement(db).get(projectPath);
|
|
168292
|
-
return row?.count ?? 0;
|
|
168293
|
-
}
|
|
168294
|
-
function getLatestIndexedCommitTimeMs(db, projectPath) {
|
|
168295
|
-
const row = getLatestCommitTimeStatement(db).get(projectPath);
|
|
168296
|
-
return row?.latest ?? null;
|
|
168297
|
-
}
|
|
168298
|
-
function enforceProjectCap(db, projectPath, maxCommits) {
|
|
168299
|
-
if (maxCommits <= 0)
|
|
168300
|
-
return 0;
|
|
168301
|
-
const count = getCommitCount(db, projectPath);
|
|
168302
|
-
if (count <= maxCommits)
|
|
168303
|
-
return 0;
|
|
168304
|
-
getEvictOverflowStatement(db).run(projectPath, maxCommits);
|
|
168305
|
-
const after = getCommitCount(db, projectPath);
|
|
168306
|
-
const evicted = Math.max(0, count - after);
|
|
168307
|
-
if (evicted > 0) {
|
|
168308
|
-
log(`[git-commits] evicted ${evicted} oldest commits for project ${projectPath} (cap=${maxCommits}, was=${count})`);
|
|
168309
|
-
}
|
|
168310
|
-
return evicted;
|
|
168311
|
-
}
|
|
168312
|
-
|
|
168313
168660
|
// ../plugin/src/features/magic-context/git-commits/indexer.ts
|
|
168314
168661
|
var MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
168315
168662
|
var EMBED_BATCH_SIZE = 16;
|
|
@@ -168718,7 +169065,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled = getProjectEmbedd
|
|
|
168718
169065
|
experimentalPinKeyFiles: reg.experimentalPinKeyFiles,
|
|
168719
169066
|
projectIdentity: reg.projectIdentity,
|
|
168720
169067
|
sessionDirectoryOverride: reg.directory,
|
|
168721
|
-
fallbackModels: resolveFallbackChain(
|
|
169068
|
+
fallbackModels: resolveFallbackChain(reg.dreamerConfig.fallback_models)
|
|
168722
169069
|
});
|
|
168723
169070
|
} catch (error51) {
|
|
168724
169071
|
log(`[dreamer] timer-triggered queue processing failed for ${reg.projectIdentity}:`, error51);
|
|
@@ -169598,7 +169945,7 @@ async function awaitInFlightDreamers() {
|
|
|
169598
169945
|
function createPiDreamerClient(opts) {
|
|
169599
169946
|
const runner2 = piSubagentRunnerFactory();
|
|
169600
169947
|
const model = opts.config.model;
|
|
169601
|
-
const fallbackModels = resolveFallbackChain(
|
|
169948
|
+
const fallbackModels = resolveFallbackChain(opts.config.fallback_models);
|
|
169602
169949
|
const session = {
|
|
169603
169950
|
create: async (args) => {
|
|
169604
169951
|
const sessionId = `magic-context-pi-dream-${++sessionCounter}`;
|
|
@@ -169843,87 +170190,229 @@ function registerCtxDreamCommand(pi, deps) {
|
|
|
169843
170190
|
});
|
|
169844
170191
|
}
|
|
169845
170192
|
|
|
169846
|
-
// src/
|
|
169847
|
-
|
|
169848
|
-
|
|
169849
|
-
|
|
169850
|
-
|
|
170193
|
+
// ../plugin/src/hooks/magic-context/embed-session-state.ts
|
|
170194
|
+
var embedPauseBySession = new Set;
|
|
170195
|
+
var embedRunStateBySession = new Map;
|
|
170196
|
+
var autoEmbedAttemptedBySession = new Set;
|
|
170197
|
+
|
|
170198
|
+
// ../plugin/src/hooks/magic-context/format-embed-status.ts
|
|
170199
|
+
function formatEmbedStatusText(coverage, drain) {
|
|
170200
|
+
if (!coverage.enabled) {
|
|
170201
|
+
return "Embedding is off (no provider configured).";
|
|
170202
|
+
}
|
|
170203
|
+
const lines = [];
|
|
170204
|
+
lines.push(`Embedding — model: ${coverage.model} (${coverage.provider})`);
|
|
170205
|
+
lines.push(`This session: ${coverage.session.embedded} / ${coverage.session.total} compartments embedded`);
|
|
170206
|
+
lines.push(`Project memories: ${coverage.memories.embedded} / ${coverage.memories.total} embedded`);
|
|
170207
|
+
if (coverage.commits.gitEnabled) {
|
|
170208
|
+
lines.push(`Git commits: ${coverage.commits.embedded} / ${coverage.commits.total}`);
|
|
170209
|
+
} else {
|
|
170210
|
+
lines.push("Git commits: 0 / 0 (git indexing off)");
|
|
170211
|
+
}
|
|
170212
|
+
let drainLine = "Drain: idle";
|
|
170213
|
+
switch (drain.status) {
|
|
170214
|
+
case "running": {
|
|
170215
|
+
const e = drain.embedded ?? coverage.session.embedded;
|
|
170216
|
+
const t = drain.total ?? coverage.session.total;
|
|
170217
|
+
const failedSuffix = drain.failed && drain.failed > 0 ? ` (${drain.failed} failed)` : "";
|
|
170218
|
+
drainLine = `Drain: running ${e}/${t}${failedSuffix}`;
|
|
170219
|
+
break;
|
|
170220
|
+
}
|
|
170221
|
+
case "paused": {
|
|
170222
|
+
const e = drain.embedded ?? coverage.session.embedded;
|
|
170223
|
+
const t = drain.total ?? coverage.session.total;
|
|
170224
|
+
drainLine = `Drain: paused ${e}/${t}`;
|
|
170225
|
+
break;
|
|
170226
|
+
}
|
|
170227
|
+
case "stopped":
|
|
170228
|
+
drainLine = "Drain: stopped (provider down)";
|
|
170229
|
+
break;
|
|
170230
|
+
default:
|
|
170231
|
+
drainLine = "Drain: idle";
|
|
170232
|
+
}
|
|
170233
|
+
lines.push(drainLine);
|
|
170234
|
+
return lines.join(`
|
|
170235
|
+
`);
|
|
170236
|
+
}
|
|
170237
|
+
|
|
170238
|
+
// src/commands/ctx-embed.ts
|
|
170239
|
+
function clearPiEmbedSessionState(sessionId) {
|
|
170240
|
+
embedPauseBySession.delete(sessionId);
|
|
170241
|
+
const ctrl = embedRunStateBySession.get(sessionId);
|
|
170242
|
+
if (ctrl) {
|
|
170243
|
+
ctrl.abort();
|
|
170244
|
+
embedRunStateBySession.delete(sessionId);
|
|
170245
|
+
}
|
|
170246
|
+
autoEmbedAttemptedBySession.delete(sessionId);
|
|
170247
|
+
}
|
|
170248
|
+
async function runEmbedDrain(db, projectIdentity, sessionId) {
|
|
170249
|
+
const activeCtrl = embedRunStateBySession.get(sessionId);
|
|
170250
|
+
if (activeCtrl && !activeCtrl.signal.aborted) {
|
|
170251
|
+
return {
|
|
170252
|
+
text: `## /ctx-embed
|
|
170253
|
+
|
|
170254
|
+
Embedding is already running for this session.`,
|
|
170255
|
+
level: "info"
|
|
170256
|
+
};
|
|
170257
|
+
}
|
|
170258
|
+
embedPauseBySession.delete(sessionId);
|
|
170259
|
+
const prior = embedRunStateBySession.get(sessionId);
|
|
170260
|
+
if (prior)
|
|
170261
|
+
prior.abort();
|
|
170262
|
+
const controller = new AbortController;
|
|
170263
|
+
embedRunStateBySession.set(sessionId, controller);
|
|
170264
|
+
let outcome;
|
|
170265
|
+
try {
|
|
170266
|
+
outcome = await embedSessionCompartmentChunks(db, projectIdentity, sessionId, {
|
|
170267
|
+
signal: controller.signal
|
|
170268
|
+
});
|
|
170269
|
+
} finally {
|
|
170270
|
+
if (embedRunStateBySession.get(sessionId) === controller) {
|
|
170271
|
+
embedRunStateBySession.delete(sessionId);
|
|
170272
|
+
}
|
|
170273
|
+
}
|
|
170274
|
+
switch (outcome.status) {
|
|
170275
|
+
case "nothing":
|
|
170276
|
+
return {
|
|
170277
|
+
text: `## /ctx-embed
|
|
170278
|
+
|
|
170279
|
+
All of this session's history is already embedded.`,
|
|
170280
|
+
level: "info"
|
|
170281
|
+
};
|
|
170282
|
+
case "disabled":
|
|
170283
|
+
return {
|
|
170284
|
+
text: `## /ctx-embed
|
|
170285
|
+
|
|
170286
|
+
No embedding provider is configured, so there is nothing to embed.`,
|
|
170287
|
+
level: "info"
|
|
170288
|
+
};
|
|
170289
|
+
case "busy":
|
|
170290
|
+
return {
|
|
170291
|
+
text: `## /ctx-embed
|
|
170292
|
+
|
|
170293
|
+
Embedding is already running for this project. Try again shortly.`,
|
|
170294
|
+
level: "info"
|
|
170295
|
+
};
|
|
170296
|
+
case "aborted": {
|
|
170297
|
+
const cov = getEmbeddingCoverageStatus(db, projectIdentity, sessionId);
|
|
170298
|
+
return {
|
|
170299
|
+
text: `## /ctx-embed
|
|
170300
|
+
|
|
170301
|
+
Paused at ${cov.session.embedded}/${cov.session.total} compartments embedded.`,
|
|
170302
|
+
level: "info"
|
|
170303
|
+
};
|
|
170304
|
+
}
|
|
170305
|
+
case "stalled":
|
|
170306
|
+
return {
|
|
170307
|
+
text: `## /ctx-embed
|
|
170308
|
+
|
|
170309
|
+
Embedded ${outcome.embedded} compartment${outcome.embedded === 1 ? "" : "s"}; ${outcome.remaining} could not be embedded (the provider returned no result). Run /ctx-embed start again to retry them.`,
|
|
170310
|
+
level: "info"
|
|
170311
|
+
};
|
|
170312
|
+
default:
|
|
170313
|
+
return {
|
|
170314
|
+
text: `## /ctx-embed
|
|
170315
|
+
|
|
170316
|
+
Embedded ${outcome.embedded} compartment${outcome.embedded === 1 ? "" : "s"} of history for semantic search.`,
|
|
170317
|
+
level: "success"
|
|
170318
|
+
};
|
|
170319
|
+
}
|
|
170320
|
+
}
|
|
170321
|
+
function registerCtxEmbedCommand(pi, deps) {
|
|
170322
|
+
pi.registerCommand("ctx-embed", {
|
|
170323
|
+
description: "Embedding status, or start/pause history compartment embedding (start | pause)",
|
|
170324
|
+
handler: async (args, ctx) => {
|
|
169851
170325
|
const sessionId = resolveSessionId(ctx);
|
|
169852
170326
|
if (!sessionId) {
|
|
169853
170327
|
sendCtxStatusMessage(pi, {
|
|
169854
|
-
title: "/ctx-embed
|
|
169855
|
-
text: `## /ctx-embed
|
|
170328
|
+
title: "/ctx-embed",
|
|
170329
|
+
text: `## /ctx-embed
|
|
169856
170330
|
|
|
169857
170331
|
No active Pi session is available.`,
|
|
169858
170332
|
level: "error"
|
|
169859
170333
|
});
|
|
169860
170334
|
return;
|
|
169861
170335
|
}
|
|
170336
|
+
const project = deps.resolveProject?.(ctx) ?? {
|
|
170337
|
+
projectDir: deps.projectDir,
|
|
170338
|
+
projectIdentity: deps.projectIdentity
|
|
170339
|
+
};
|
|
170340
|
+
const sub = args.trim().toLowerCase();
|
|
170341
|
+
if (sub === "pause") {
|
|
170342
|
+
embedPauseBySession.add(sessionId);
|
|
170343
|
+
const ctrl = embedRunStateBySession.get(sessionId);
|
|
170344
|
+
if (ctrl)
|
|
170345
|
+
ctrl.abort();
|
|
170346
|
+
const cov = getEmbeddingCoverageStatus(deps.db, project.projectIdentity, sessionId);
|
|
170347
|
+
sendCtxStatusMessage(pi, {
|
|
170348
|
+
title: "/ctx-embed",
|
|
170349
|
+
text: `## /ctx-embed
|
|
170350
|
+
|
|
170351
|
+
Paused at ${cov.session.embedded}/${cov.session.total} compartments embedded.`,
|
|
170352
|
+
level: "info"
|
|
170353
|
+
});
|
|
170354
|
+
return;
|
|
170355
|
+
}
|
|
169862
170356
|
if (deps.memoryEnabled === false) {
|
|
169863
170357
|
sendCtxStatusMessage(pi, {
|
|
169864
|
-
title: "/ctx-embed
|
|
169865
|
-
text: `## /ctx-embed
|
|
170358
|
+
title: "/ctx-embed",
|
|
170359
|
+
text: `## /ctx-embed
|
|
169866
170360
|
|
|
169867
170361
|
Memory is disabled for this project, so there is no semantic embedding to backfill.`,
|
|
169868
170362
|
level: "info"
|
|
169869
170363
|
});
|
|
169870
170364
|
return;
|
|
169871
170365
|
}
|
|
169872
|
-
const project = deps.resolveProject?.(ctx) ?? {
|
|
169873
|
-
projectDir: deps.projectDir,
|
|
169874
|
-
projectIdentity: deps.projectIdentity
|
|
169875
|
-
};
|
|
169876
170366
|
await ensureProjectRegisteredFromPiDirectory(project.projectDir, deps.db);
|
|
169877
|
-
|
|
169878
|
-
|
|
169879
|
-
|
|
169880
|
-
|
|
169881
|
-
|
|
169882
|
-
|
|
169883
|
-
|
|
169884
|
-
|
|
169885
|
-
|
|
169886
|
-
|
|
169887
|
-
|
|
169888
|
-
|
|
169889
|
-
|
|
169890
|
-
|
|
169891
|
-
|
|
169892
|
-
|
|
169893
|
-
|
|
169894
|
-
|
|
169895
|
-
return {
|
|
169896
|
-
text: `## /ctx-embed-history
|
|
169897
|
-
|
|
169898
|
-
Embedding is already running for this project — ${outcome.total} compartment${outcome.total === 1 ? "" : "s"} still pending. Try again shortly.`,
|
|
169899
|
-
level: "info"
|
|
169900
|
-
};
|
|
169901
|
-
case "stalled":
|
|
169902
|
-
return {
|
|
169903
|
-
text: `## /ctx-embed-history
|
|
169904
|
-
|
|
169905
|
-
Embedded ${outcome.embedded} compartment${outcome.embedded === 1 ? "" : "s"}; ${outcome.remaining} could not be embedded (the provider returned no result). Run /ctx-embed-history again to retry them.`,
|
|
169906
|
-
level: "info"
|
|
169907
|
-
};
|
|
169908
|
-
default:
|
|
169909
|
-
return {
|
|
169910
|
-
text: `## /ctx-embed-history
|
|
170367
|
+
if (sub === "start") {
|
|
170368
|
+
const { text, level } = await runEmbedDrain(deps.db, project.projectIdentity, sessionId);
|
|
170369
|
+
sendCtxStatusMessage(pi, { title: "/ctx-embed", text, level });
|
|
170370
|
+
return;
|
|
170371
|
+
}
|
|
170372
|
+
if (sub !== "") {
|
|
170373
|
+
sendCtxStatusMessage(pi, {
|
|
170374
|
+
title: "/ctx-embed",
|
|
170375
|
+
text: "## /ctx-embed\n\nUsage: `/ctx-embed` (status), `/ctx-embed start`, or `/ctx-embed pause`.",
|
|
170376
|
+
level: "info"
|
|
170377
|
+
});
|
|
170378
|
+
return;
|
|
170379
|
+
}
|
|
170380
|
+
const coverage = getEmbeddingCoverageStatus(deps.db, project.projectIdentity, sessionId);
|
|
170381
|
+
const statusText = formatEmbedStatusText(coverage, { status: "idle" });
|
|
170382
|
+
sendCtxStatusMessage(pi, {
|
|
170383
|
+
title: "/ctx-embed",
|
|
170384
|
+
text: `## Embedding Status
|
|
169911
170385
|
|
|
169912
|
-
|
|
169913
|
-
|
|
169914
|
-
};
|
|
169915
|
-
}
|
|
169916
|
-
})();
|
|
169917
|
-
sendCtxStatusMessage(pi, { title: "/ctx-embed-history", text, level }, {
|
|
169918
|
-
sessionId,
|
|
169919
|
-
projectIdentity: project.projectIdentity,
|
|
169920
|
-
status: outcome.status,
|
|
169921
|
-
embedded: outcome.embedded,
|
|
169922
|
-
total: outcome.total
|
|
170386
|
+
${statusText}`,
|
|
170387
|
+
level: "info"
|
|
169923
170388
|
});
|
|
169924
170389
|
}
|
|
169925
170390
|
});
|
|
169926
170391
|
}
|
|
170392
|
+
function maybeAutoEmbedPiSession(deps, sessionId, projectDir, projectIdentity, notify) {
|
|
170393
|
+
if (autoEmbedAttemptedBySession.has(sessionId))
|
|
170394
|
+
return;
|
|
170395
|
+
if (embedPauseBySession.has(sessionId))
|
|
170396
|
+
return;
|
|
170397
|
+
if (deps.memoryEnabled === false)
|
|
170398
|
+
return;
|
|
170399
|
+
autoEmbedAttemptedBySession.add(sessionId);
|
|
170400
|
+
(async () => {
|
|
170401
|
+
try {
|
|
170402
|
+
await new Promise((resolve5) => setTimeout(resolve5, 0));
|
|
170403
|
+
await ensureProjectRegisteredFromPiDirectory(projectDir, deps.db);
|
|
170404
|
+
const coverage = getEmbeddingCoverageStatus(deps.db, projectIdentity, sessionId);
|
|
170405
|
+
if (!coverage.enabled)
|
|
170406
|
+
return;
|
|
170407
|
+
const remaining = coverage.session.total - coverage.session.embedded;
|
|
170408
|
+
if (remaining <= 0)
|
|
170409
|
+
return;
|
|
170410
|
+
notify(`Embedding ${remaining} compartment${remaining === 1 ? "" : "s"} of history in the background…`);
|
|
170411
|
+
const { text } = await runEmbedDrain(deps.db, projectIdentity, sessionId);
|
|
170412
|
+
notify(text.replace(/^## \/ctx-embed\n\n/, ""));
|
|
170413
|
+
} catch {}
|
|
170414
|
+
})();
|
|
170415
|
+
}
|
|
169927
170416
|
|
|
169928
170417
|
// ../plugin/src/hooks/magic-context/execute-flush.ts
|
|
169929
170418
|
init_logger();
|
|
@@ -170017,10 +170506,9 @@ function makeToolCompositeKey(ownerMsgId, callId) {
|
|
|
170017
170506
|
}
|
|
170018
170507
|
var GET_COUNTER_SQL = `SELECT counter FROM session_meta WHERE session_id = ?`;
|
|
170019
170508
|
var GET_ASSIGNMENTS_SQL = "SELECT message_id, tag_number, type, tool_owner_message_id FROM tags WHERE session_id = ? ORDER BY tag_number ASC";
|
|
170509
|
+
var GET_ASSIGNMENTS_SCOPED_SQL = "SELECT message_id, tag_number, type, tool_owner_message_id FROM tags WHERE session_id = ? AND tag_number >= ? ORDER BY tag_number ASC";
|
|
170020
170510
|
var PROBE_DATA_VERSION_SQL = "PRAGMA main.data_version";
|
|
170021
|
-
var PROBE_TOTAL_CHANGES_SQL = "SELECT total_changes() AS tc";
|
|
170022
170511
|
var probeDataVersionStatements = new WeakMap;
|
|
170023
|
-
var probeTotalChangesStatements = new WeakMap;
|
|
170024
170512
|
function getProbeDataVersionStatement(db) {
|
|
170025
170513
|
let stmt = probeDataVersionStatements.get(db);
|
|
170026
170514
|
if (!stmt) {
|
|
@@ -170029,14 +170517,6 @@ function getProbeDataVersionStatement(db) {
|
|
|
170029
170517
|
}
|
|
170030
170518
|
return stmt;
|
|
170031
170519
|
}
|
|
170032
|
-
function getProbeTotalChangesStatement(db) {
|
|
170033
|
-
let stmt = probeTotalChangesStatements.get(db);
|
|
170034
|
-
if (!stmt) {
|
|
170035
|
-
stmt = db.prepare(PROBE_TOTAL_CHANGES_SQL);
|
|
170036
|
-
probeTotalChangesStatements.set(db, stmt);
|
|
170037
|
-
}
|
|
170038
|
-
return stmt;
|
|
170039
|
-
}
|
|
170040
170520
|
function isAssignmentRow(row) {
|
|
170041
170521
|
if (row === null || typeof row !== "object") {
|
|
170042
170522
|
return false;
|
|
@@ -170229,20 +170709,18 @@ function createTagger() {
|
|
|
170229
170709
|
}
|
|
170230
170710
|
function probeSignature(db) {
|
|
170231
170711
|
const dvRow = getProbeDataVersionStatement(db).get();
|
|
170232
|
-
const tcRow = getProbeTotalChangesStatement(db).get();
|
|
170233
170712
|
return {
|
|
170234
|
-
dataVersion: dvRow?.data_version ?? 0
|
|
170235
|
-
totalChanges: tcRow?.tc ?? 0
|
|
170713
|
+
dataVersion: dvRow?.data_version ?? 0
|
|
170236
170714
|
};
|
|
170237
170715
|
}
|
|
170238
|
-
function initFromDb(sessionId, db) {
|
|
170716
|
+
function initFromDb(sessionId, db, floor = 0) {
|
|
170239
170717
|
const probe = probeSignature(db);
|
|
170240
170718
|
const cached2 = loadSignatures.get(sessionId);
|
|
170241
|
-
if (cached2 !== undefined && cached2.db === db && cached2.dataVersion === probe.dataVersion && cached2.
|
|
170719
|
+
if (cached2 !== undefined && cached2.db === db && cached2.dataVersion === probe.dataVersion && cached2.floor === floor) {
|
|
170242
170720
|
return;
|
|
170243
170721
|
}
|
|
170244
170722
|
const row = db.prepare(GET_COUNTER_SQL).get(sessionId);
|
|
170245
|
-
const assignmentRows = db.prepare(GET_ASSIGNMENTS_SQL).all(sessionId).filter(isAssignmentRow);
|
|
170723
|
+
const assignmentRows = (floor > 0 ? db.prepare(GET_ASSIGNMENTS_SCOPED_SQL).all(sessionId, floor) : db.prepare(GET_ASSIGNMENTS_SQL).all(sessionId)).filter(isAssignmentRow);
|
|
170246
170724
|
const sessionAssignments = getSessionAssignments(sessionId);
|
|
170247
170725
|
sessionAssignments.clear();
|
|
170248
170726
|
let maxTagNumber = 0;
|
|
@@ -170263,7 +170741,7 @@ function createTagger() {
|
|
|
170263
170741
|
loadSignatures.set(sessionId, {
|
|
170264
170742
|
db,
|
|
170265
170743
|
dataVersion: probe.dataVersion,
|
|
170266
|
-
|
|
170744
|
+
floor
|
|
170267
170745
|
});
|
|
170268
170746
|
}
|
|
170269
170747
|
function cleanup(sessionId) {
|
|
@@ -170287,6 +170765,162 @@ function createTagger() {
|
|
|
170287
170765
|
};
|
|
170288
170766
|
}
|
|
170289
170767
|
|
|
170768
|
+
// ../plugin/src/features/magic-context/transform-decision-log.ts
|
|
170769
|
+
var canonicalReasons = new Set([
|
|
170770
|
+
"system_hash",
|
|
170771
|
+
"model_change",
|
|
170772
|
+
"project_memory_epoch",
|
|
170773
|
+
"ttl_idle",
|
|
170774
|
+
"explicit_flush",
|
|
170775
|
+
"max_mutation_id",
|
|
170776
|
+
"first_render",
|
|
170777
|
+
"pressure_refold",
|
|
170778
|
+
"upgrade_state",
|
|
170779
|
+
"cached_m1_missing"
|
|
170780
|
+
]);
|
|
170781
|
+
var piReasonAliases = {
|
|
170782
|
+
project_memory_change: "project_memory_epoch",
|
|
170783
|
+
pending_mutations: "max_mutation_id",
|
|
170784
|
+
renderer_upgrade: "upgrade_state",
|
|
170785
|
+
cache_invalid: "cached_m1_missing",
|
|
170786
|
+
drift: "pressure_refold"
|
|
170787
|
+
};
|
|
170788
|
+
var sharedReasonAliases = {
|
|
170789
|
+
model_key: "model_change",
|
|
170790
|
+
pressure: "pressure_refold"
|
|
170791
|
+
};
|
|
170792
|
+
var pendingDecisionBySession = new Map;
|
|
170793
|
+
var pendingPiDecisionBySession = new Map;
|
|
170794
|
+
var lastBoundMessageIdBySession = new Map;
|
|
170795
|
+
var scheduledWriteTokensBySession = new Map;
|
|
170796
|
+
var writerOverrideForTests = null;
|
|
170797
|
+
function normalizeMaterializeReason(harness, reason, rematerialized) {
|
|
170798
|
+
const raw = typeof reason === "string" ? reason.trim() : "";
|
|
170799
|
+
if (raw.length > 0) {
|
|
170800
|
+
const alias = sharedReasonAliases[raw] ?? (harness === "pi" ? piReasonAliases[raw] : undefined) ?? undefined;
|
|
170801
|
+
if (alias)
|
|
170802
|
+
return alias;
|
|
170803
|
+
if (canonicalReasons.has(raw))
|
|
170804
|
+
return raw;
|
|
170805
|
+
return null;
|
|
170806
|
+
}
|
|
170807
|
+
return rematerialized ? "pressure_refold" : null;
|
|
170808
|
+
}
|
|
170809
|
+
function recordPendingPiTransformDecision(sessionId, decision, snapshotNewestAssistantEntryId) {
|
|
170810
|
+
if (!decision.bustedThisPass)
|
|
170811
|
+
return;
|
|
170812
|
+
pendingPiDecisionBySession.set(sessionId, {
|
|
170813
|
+
...decision,
|
|
170814
|
+
snapshotNewestAssistantEntryId
|
|
170815
|
+
});
|
|
170816
|
+
}
|
|
170817
|
+
function findNewestPiAssistantEntryId(entries) {
|
|
170818
|
+
if (!Array.isArray(entries))
|
|
170819
|
+
return null;
|
|
170820
|
+
for (let i = entries.length - 1;i >= 0; i--) {
|
|
170821
|
+
const entry = entries[i];
|
|
170822
|
+
if (!entry || typeof entry !== "object")
|
|
170823
|
+
continue;
|
|
170824
|
+
const row = entry;
|
|
170825
|
+
if (row.type !== "message" || typeof row.id !== "string" || row.id.length === 0) {
|
|
170826
|
+
continue;
|
|
170827
|
+
}
|
|
170828
|
+
const message = row.message;
|
|
170829
|
+
if (message && typeof message === "object" && message.role === "assistant") {
|
|
170830
|
+
return row.id;
|
|
170831
|
+
}
|
|
170832
|
+
}
|
|
170833
|
+
return null;
|
|
170834
|
+
}
|
|
170835
|
+
function schedulePiTransformDecisionResolve(args) {
|
|
170836
|
+
const pending = pendingPiDecisionBySession.get(args.sessionId);
|
|
170837
|
+
if (!pending)
|
|
170838
|
+
return false;
|
|
170839
|
+
const targetMessageId = findNewestPiAssistantEntryIdAfter(args.branchEntries, pending.snapshotNewestAssistantEntryId);
|
|
170840
|
+
if (!targetMessageId)
|
|
170841
|
+
return false;
|
|
170842
|
+
const dbPath = getDatabasePath(args.db);
|
|
170843
|
+
if (!dbPath)
|
|
170844
|
+
return false;
|
|
170845
|
+
pendingPiDecisionBySession.delete(args.sessionId);
|
|
170846
|
+
const token = addScheduledWriteToken(args.sessionId);
|
|
170847
|
+
setTimeout(() => {
|
|
170848
|
+
try {
|
|
170849
|
+
if (!hasScheduledWriteToken(args.sessionId, token))
|
|
170850
|
+
return;
|
|
170851
|
+
writeTransformDecisionBestEffort(dbPath, {
|
|
170852
|
+
...pending,
|
|
170853
|
+
sessionId: args.sessionId,
|
|
170854
|
+
harness: "pi",
|
|
170855
|
+
messageId: targetMessageId
|
|
170856
|
+
});
|
|
170857
|
+
} finally {
|
|
170858
|
+
deleteScheduledWriteToken(args.sessionId, token);
|
|
170859
|
+
}
|
|
170860
|
+
}, 0);
|
|
170861
|
+
return true;
|
|
170862
|
+
}
|
|
170863
|
+
function addScheduledWriteToken(sessionId) {
|
|
170864
|
+
const token = Symbol(sessionId);
|
|
170865
|
+
let tokens = scheduledWriteTokensBySession.get(sessionId);
|
|
170866
|
+
if (!tokens) {
|
|
170867
|
+
tokens = new Set;
|
|
170868
|
+
scheduledWriteTokensBySession.set(sessionId, tokens);
|
|
170869
|
+
}
|
|
170870
|
+
tokens.add(token);
|
|
170871
|
+
return token;
|
|
170872
|
+
}
|
|
170873
|
+
function hasScheduledWriteToken(sessionId, token) {
|
|
170874
|
+
return scheduledWriteTokensBySession.get(sessionId)?.has(token) === true;
|
|
170875
|
+
}
|
|
170876
|
+
function deleteScheduledWriteToken(sessionId, token) {
|
|
170877
|
+
const tokens = scheduledWriteTokensBySession.get(sessionId);
|
|
170878
|
+
if (!tokens)
|
|
170879
|
+
return;
|
|
170880
|
+
tokens.delete(token);
|
|
170881
|
+
if (tokens.size === 0)
|
|
170882
|
+
scheduledWriteTokensBySession.delete(sessionId);
|
|
170883
|
+
}
|
|
170884
|
+
function findNewestPiAssistantEntryIdAfter(entries, snapshotNewestAssistantEntryId) {
|
|
170885
|
+
if (!Array.isArray(entries))
|
|
170886
|
+
return null;
|
|
170887
|
+
for (let i = entries.length - 1;i >= 0; i--) {
|
|
170888
|
+
const entry = entries[i];
|
|
170889
|
+
if (!entry || typeof entry !== "object")
|
|
170890
|
+
continue;
|
|
170891
|
+
const row = entry;
|
|
170892
|
+
if (row.type !== "message" || typeof row.id !== "string" || row.id.length === 0) {
|
|
170893
|
+
continue;
|
|
170894
|
+
}
|
|
170895
|
+
if (snapshotNewestAssistantEntryId !== null && row.id === snapshotNewestAssistantEntryId) {
|
|
170896
|
+
continue;
|
|
170897
|
+
}
|
|
170898
|
+
const message = row.message;
|
|
170899
|
+
if (message && typeof message === "object" && message.role === "assistant") {
|
|
170900
|
+
return row.id;
|
|
170901
|
+
}
|
|
170902
|
+
}
|
|
170903
|
+
return null;
|
|
170904
|
+
}
|
|
170905
|
+
function writeTransformDecisionBestEffort(dbPath, row) {
|
|
170906
|
+
try {
|
|
170907
|
+
const writer = writerOverrideForTests ?? writeTransformDecisionRow;
|
|
170908
|
+
writer(dbPath, row);
|
|
170909
|
+
} catch {}
|
|
170910
|
+
}
|
|
170911
|
+
function writeTransformDecisionRow(dbPath, row) {
|
|
170912
|
+
const db = new Database(dbPath);
|
|
170913
|
+
try {
|
|
170914
|
+
db.exec("PRAGMA busy_timeout=0");
|
|
170915
|
+
db.prepare(`INSERT OR REPLACE INTO transform_decisions (
|
|
170916
|
+
session_id, harness, message_id, ts_ms, decision, materialized,
|
|
170917
|
+
materialize_reason, emergency, dropped_tokens, dropped_count, input_tokens
|
|
170918
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(row.sessionId, row.harness, row.messageId, row.tsMs, row.decision, row.materialized ? 1 : 0, row.materializeReason, row.emergency ? 1 : 0, Math.max(0, Math.floor(row.droppedTokens)), Math.max(0, Math.floor(row.droppedCount)), Math.max(0, Math.floor(row.inputTokens)));
|
|
170919
|
+
} finally {
|
|
170920
|
+
closeQuietly(db);
|
|
170921
|
+
}
|
|
170922
|
+
}
|
|
170923
|
+
|
|
170290
170924
|
// ../plugin/src/features/magic-context/work-metrics.ts
|
|
170291
170925
|
function asNumber2(value) {
|
|
170292
170926
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
@@ -170338,76 +170972,12 @@ function computePiWorkMetrics(sessionEntries) {
|
|
|
170338
170972
|
return { newWorkTokens, totalInputTokens };
|
|
170339
170973
|
}
|
|
170340
170974
|
|
|
170341
|
-
// ../plugin/src/hooks/magic-context/system-injection-stripper.ts
|
|
170342
|
-
var SYSTEM_INJECTION_MARKERS = [
|
|
170343
|
-
"<!-- OMO_INTERNAL_INITIATOR -->",
|
|
170344
|
-
"[SYSTEM DIRECTIVE: MAGIC-CONTEXT",
|
|
170345
|
-
"[SYSTEM DIRECTIVE: OH-MY-OPENCODE",
|
|
170346
|
-
"[Category+Skill Reminder]",
|
|
170347
|
-
"[EDIT ERROR - IMMEDIATE ACTION REQUIRED]",
|
|
170348
|
-
"[task CALL FAILED - IMMEDIATE RETRY REQUIRED]",
|
|
170349
|
-
"[EMERGENCY CONTEXT WINDOW WARNING]",
|
|
170350
|
-
"Unstable background agent appears idle",
|
|
170351
|
-
"**THE SUBAGENT JUST CLAIMED THIS TASK IS DONE."
|
|
170352
|
-
];
|
|
170353
|
-
var SYSTEM_REMINDER_REGEX = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
|
|
170354
|
-
var OMO_MARKER_REGEX = /<!-- OMO_INTERNAL_INITIATOR -->/g;
|
|
170355
|
-
function stripSystemInjection(text) {
|
|
170356
|
-
let hasInjection = false;
|
|
170357
|
-
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
170358
|
-
if (text.includes(marker)) {
|
|
170359
|
-
hasInjection = true;
|
|
170360
|
-
break;
|
|
170361
|
-
}
|
|
170362
|
-
}
|
|
170363
|
-
if (SYSTEM_REMINDER_REGEX.test(text))
|
|
170364
|
-
hasInjection = true;
|
|
170365
|
-
SYSTEM_REMINDER_REGEX.lastIndex = 0;
|
|
170366
|
-
if (!hasInjection)
|
|
170367
|
-
return null;
|
|
170368
|
-
let cleaned = text;
|
|
170369
|
-
cleaned = cleaned.replace(SYSTEM_REMINDER_REGEX, "");
|
|
170370
|
-
cleaned = cleaned.replace(OMO_MARKER_REGEX, "");
|
|
170371
|
-
cleaned = cleaned.replace(/\[SYSTEM DIRECTIVE: OH-MY-(?:OPENCODE|CLAUDE)[^\]]*\][\s\S]*?(?=\n\n(?!\s*[-*])|$)/g, "");
|
|
170372
|
-
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
170373
|
-
if (marker.startsWith("<!-- ") || marker.startsWith("[SYSTEM DIRECTIVE"))
|
|
170374
|
-
continue;
|
|
170375
|
-
const idx = cleaned.indexOf(marker);
|
|
170376
|
-
if (idx === -1)
|
|
170377
|
-
continue;
|
|
170378
|
-
const blockEnd = cleaned.indexOf(`
|
|
170379
|
-
|
|
170380
|
-
`, idx + marker.length);
|
|
170381
|
-
cleaned = blockEnd !== -1 ? cleaned.slice(0, idx) + cleaned.slice(blockEnd) : cleaned.slice(0, idx);
|
|
170382
|
-
}
|
|
170383
|
-
return cleaned.trim();
|
|
170384
|
-
}
|
|
170385
|
-
|
|
170386
170975
|
// ../plugin/src/hooks/magic-context/apply-operations.ts
|
|
170387
|
-
var USER_DROP_PREVIEW_CHARS = 250;
|
|
170388
170976
|
var RECENT_TOOL_SKELETON_WINDOW = 20;
|
|
170389
|
-
function buildReplacementContent(tagId
|
|
170390
|
-
|
|
170391
|
-
|
|
170392
|
-
|
|
170393
|
-
}
|
|
170394
|
-
const currentContent = target.getContent?.() ?? "";
|
|
170395
|
-
const strippedInjection = stripSystemInjection(currentContent);
|
|
170396
|
-
if (strippedInjection !== null && stripTagPrefix(strippedInjection).trim().length === 0) {
|
|
170397
|
-
return `[dropped §${tagId}§]`;
|
|
170398
|
-
}
|
|
170399
|
-
const originalText = stripTagPrefix(currentContent);
|
|
170400
|
-
if (originalText.length <= USER_DROP_PREVIEW_CHARS) {
|
|
170401
|
-
return `[truncated §${tagId}§]
|
|
170402
|
-
${originalText}`;
|
|
170403
|
-
}
|
|
170404
|
-
const hardCut = originalText.slice(0, USER_DROP_PREVIEW_CHARS);
|
|
170405
|
-
const softCutIndex = hardCut.search(/\s\S*$/);
|
|
170406
|
-
const preview = softCutIndex > USER_DROP_PREVIEW_CHARS - 30 ? hardCut.slice(0, softCutIndex) : hardCut;
|
|
170407
|
-
return `[truncated §${tagId}§]
|
|
170408
|
-
${preview}…`;
|
|
170409
|
-
}
|
|
170410
|
-
function applyPendingOperations(sessionId, db, targets, protectedTags = 0, preloadedTags, preloadedPendingOps) {
|
|
170977
|
+
function buildReplacementContent(tagId) {
|
|
170978
|
+
return `[dropped §${tagId}§]`;
|
|
170979
|
+
}
|
|
170980
|
+
function applyPendingOperations(sessionId, db, targets, protectedTags = 0, preloadedTags, preloadedPendingOps, syntheticPendingOps = []) {
|
|
170411
170981
|
let didMutateMessage = false;
|
|
170412
170982
|
db.transaction(() => {
|
|
170413
170983
|
const tags = preloadedTags ?? getTagsBySession(db, sessionId);
|
|
@@ -170415,11 +170985,16 @@ function applyPendingOperations(sessionId, db, targets, protectedTags = 0, prelo
|
|
|
170415
170985
|
const tagTypeById = new Map(tags.map((tag) => [tag.tagNumber, tag.type]));
|
|
170416
170986
|
const protectedTagIds = protectedTags > 0 ? new Set(tags.filter((tag) => tag.status === "active").map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, protectedTags)) : new Set;
|
|
170417
170987
|
const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
|
|
170988
|
+
const opsToApply = [
|
|
170989
|
+
...pendingOps.map((op) => ({ op, synthetic: false })),
|
|
170990
|
+
...syntheticPendingOps.map((op) => ({ op, synthetic: true }))
|
|
170991
|
+
];
|
|
170418
170992
|
const skeletonWindow = new Set(tags.filter((tag) => tag.type === "tool").map((tag) => tag.tagNumber).sort((left, right) => right - left).slice(0, RECENT_TOOL_SKELETON_WINDOW));
|
|
170419
|
-
for (const pendingOp of
|
|
170993
|
+
for (const { op: pendingOp, synthetic } of opsToApply) {
|
|
170420
170994
|
const tagStatus = tagStatusById.get(pendingOp.tagId);
|
|
170421
170995
|
if (tagStatus === "compacted" || tagStatus === "dropped") {
|
|
170422
|
-
|
|
170996
|
+
if (!synthetic)
|
|
170997
|
+
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
170423
170998
|
continue;
|
|
170424
170999
|
}
|
|
170425
171000
|
if (protectedTagIds.has(pendingOp.tagId)) {
|
|
@@ -170427,33 +171002,46 @@ function applyPendingOperations(sessionId, db, targets, protectedTags = 0, prelo
|
|
|
170427
171002
|
}
|
|
170428
171003
|
const target = targets.get(pendingOp.tagId);
|
|
170429
171004
|
const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
|
|
171005
|
+
if (synthetic) {
|
|
171006
|
+
if (!isToolTag || target?.canDrop?.() !== true)
|
|
171007
|
+
continue;
|
|
171008
|
+
}
|
|
171009
|
+
let shouldPersistDrop = false;
|
|
170430
171010
|
if (isToolTag) {
|
|
170431
171011
|
if (skeletonWindow.has(pendingOp.tagId)) {
|
|
170432
171012
|
const truncResult = target?.truncate?.() ?? "absent";
|
|
170433
|
-
if (truncResult === "incomplete") {
|
|
171013
|
+
if (truncResult === "incomplete" || synthetic && truncResult !== "truncated") {
|
|
170434
171014
|
continue;
|
|
170435
171015
|
}
|
|
170436
171016
|
if (truncResult === "truncated") {
|
|
170437
171017
|
didMutateMessage = true;
|
|
170438
171018
|
}
|
|
170439
171019
|
updateTagDropMode(db, sessionId, pendingOp.tagId, "truncated");
|
|
171020
|
+
shouldPersistDrop = true;
|
|
170440
171021
|
} else {
|
|
170441
171022
|
const dropResult = target?.drop?.() ?? "absent";
|
|
170442
|
-
if (dropResult === "incomplete") {
|
|
171023
|
+
if (dropResult === "incomplete" || synthetic && dropResult !== "removed") {
|
|
170443
171024
|
continue;
|
|
170444
171025
|
}
|
|
170445
171026
|
if (dropResult === "removed") {
|
|
170446
171027
|
didMutateMessage = true;
|
|
170447
171028
|
}
|
|
170448
171029
|
updateTagDropMode(db, sessionId, pendingOp.tagId, "full");
|
|
171030
|
+
shouldPersistDrop = true;
|
|
170449
171031
|
}
|
|
170450
171032
|
} else if (target) {
|
|
170451
|
-
const changed = target.setContent(buildReplacementContent(pendingOp.tagId
|
|
171033
|
+
const changed = target.setContent(buildReplacementContent(pendingOp.tagId));
|
|
170452
171034
|
if (changed)
|
|
170453
171035
|
didMutateMessage = true;
|
|
171036
|
+
shouldPersistDrop = true;
|
|
171037
|
+
} else if (!synthetic) {
|
|
171038
|
+
shouldPersistDrop = true;
|
|
170454
171039
|
}
|
|
171040
|
+
if (!shouldPersistDrop)
|
|
171041
|
+
continue;
|
|
170455
171042
|
updateTagStatus(db, sessionId, pendingOp.tagId, "dropped");
|
|
170456
|
-
|
|
171043
|
+
if (!synthetic)
|
|
171044
|
+
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
170457
171045
|
}
|
|
170458
171046
|
})();
|
|
170459
171047
|
return didMutateMessage;
|
|
@@ -170477,7 +171065,7 @@ function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
|
|
|
170477
171065
|
}
|
|
170478
171066
|
}
|
|
170479
171067
|
} else if (target) {
|
|
170480
|
-
const changed = target.setContent(buildReplacementContent(tag.tagNumber
|
|
171068
|
+
const changed = target.setContent(buildReplacementContent(tag.tagNumber));
|
|
170481
171069
|
if (changed)
|
|
170482
171070
|
didMutateMessage = true;
|
|
170483
171071
|
}
|
|
@@ -170765,7 +171353,8 @@ function applyCavemanCleanup(sessionId, db, targets, tags, config2) {
|
|
|
170765
171353
|
const result = {
|
|
170766
171354
|
compressedToLite: 0,
|
|
170767
171355
|
compressedToFull: 0,
|
|
170768
|
-
compressedToUltra: 0
|
|
171356
|
+
compressedToUltra: 0,
|
|
171357
|
+
mutatedTextTags: 0
|
|
170769
171358
|
};
|
|
170770
171359
|
if (!config2.enabled)
|
|
170771
171360
|
return result;
|
|
@@ -170806,7 +171395,9 @@ function applyCavemanCleanup(sessionId, db, targets, tags, config2) {
|
|
|
170806
171395
|
const target = targets.get(tag.tagNumber);
|
|
170807
171396
|
if (!target)
|
|
170808
171397
|
continue;
|
|
170809
|
-
target.setContent(compressed);
|
|
171398
|
+
const didMutate = target.setContent(compressed);
|
|
171399
|
+
if (didMutate)
|
|
171400
|
+
result.mutatedTextTags += 1;
|
|
170810
171401
|
updateCavemanDepth(db, sessionId, tag.tagNumber, targetDepth);
|
|
170811
171402
|
if (targetDepth === DEPTH_LITE)
|
|
170812
171403
|
result.compressedToLite += 1;
|
|
@@ -171184,7 +171775,7 @@ function buildToolArcs(messages) {
|
|
|
171184
171775
|
}
|
|
171185
171776
|
return arcs.sort((a, b) => a.invOrdinal - b.invOrdinal || (a.resOrdinal ?? Number.MAX_SAFE_INTEGER) - (b.resOrdinal ?? Number.MAX_SAFE_INTEGER));
|
|
171186
171777
|
}
|
|
171187
|
-
function fenceBoundaryForToolArcs(candidate, arcs, lastCompartmentEndOrdinal) {
|
|
171778
|
+
function fenceBoundaryForToolArcs(candidate, arcs, lastCompartmentEndOrdinal, recentOpenArcCutoff) {
|
|
171188
171779
|
let boundary = candidate;
|
|
171189
171780
|
for (const arc of arcs) {
|
|
171190
171781
|
if (arc.resOrdinal !== null) {
|
|
@@ -171193,6 +171784,8 @@ function fenceBoundaryForToolArcs(candidate, arcs, lastCompartmentEndOrdinal) {
|
|
|
171193
171784
|
}
|
|
171194
171785
|
continue;
|
|
171195
171786
|
}
|
|
171787
|
+
if (arc.invOrdinal < recentOpenArcCutoff)
|
|
171788
|
+
continue;
|
|
171196
171789
|
if (arc.invOrdinal >= lastCompartmentEndOrdinal + 1 && arc.invOrdinal < boundary) {
|
|
171197
171790
|
return arc.invOrdinal;
|
|
171198
171791
|
}
|
|
@@ -171430,7 +172023,7 @@ function semanticSnapBoundary(args) {
|
|
|
171430
172023
|
return snapped;
|
|
171431
172024
|
}
|
|
171432
172025
|
function applyHeadCap(args) {
|
|
171433
|
-
const { index, protectedTailStart, offset, arcs, capTokens } = args;
|
|
172026
|
+
const { index, protectedTailStart, offset, arcs, capTokens, recentOpenArcCutoff } = args;
|
|
171434
172027
|
if (offset >= protectedTailStart)
|
|
171435
172028
|
return { eligibleEndOrdinal: offset, oversizeAtomicUnit: false };
|
|
171436
172029
|
let end = index.findHeadEndForCap(offset, protectedTailStart, capTokens);
|
|
@@ -171438,7 +172031,7 @@ function applyHeadCap(args) {
|
|
|
171438
172031
|
for (const arc of arcs) {
|
|
171439
172032
|
const resOrdinal = arc.resOrdinal;
|
|
171440
172033
|
if (resOrdinal === null) {
|
|
171441
|
-
if (arc.invOrdinal >= offset && arc.invOrdinal < end) {
|
|
172034
|
+
if (arc.invOrdinal >= recentOpenArcCutoff && arc.invOrdinal >= offset && arc.invOrdinal < end) {
|
|
171442
172035
|
end = Math.min(end, arc.invOrdinal);
|
|
171443
172036
|
}
|
|
171444
172037
|
continue;
|
|
@@ -171505,7 +172098,14 @@ function resolveProtectedTailBoundary(ctx) {
|
|
|
171505
172098
|
}
|
|
171506
172099
|
if (ctx.mode === "manual-full-recomp") {
|
|
171507
172100
|
const arcs2 = buildToolArcs(messages);
|
|
171508
|
-
const
|
|
172101
|
+
const recompTarget = deriveProtectedTailTokenTarget({
|
|
172102
|
+
contextLimit: ctx.contextLimit,
|
|
172103
|
+
executeThresholdPercentage: ctx.executeThresholdPercentage,
|
|
172104
|
+
usagePercentage: 0,
|
|
172105
|
+
triggerBudget: ctx.triggerBudget
|
|
172106
|
+
});
|
|
172107
|
+
const recentOpenArcCutoff2 = index.findSuffixStartForTokens(recompTarget.N);
|
|
172108
|
+
const firstOpenArc = arcs2.find((arc) => arc.resOrdinal === null && arc.invOrdinal >= offset && arc.invOrdinal >= recentOpenArcCutoff2);
|
|
171509
172109
|
const protectedTailStart2 = firstOpenArc?.invOrdinal ?? rawMessageCount + 1;
|
|
171510
172110
|
const rawRangeFingerprint2 = computeRawRangeFingerprint(messages, offset, protectedTailStart2);
|
|
171511
172111
|
return {
|
|
@@ -171547,13 +172147,14 @@ function resolveProtectedTailBoundary(ctx) {
|
|
|
171547
172147
|
const scaledN = ctx.emergencyTailScale ? Math.max(1, Math.floor(target.N * ctx.emergencyTailScale)) : target.N;
|
|
171548
172148
|
const arcs = buildToolArcs(messages);
|
|
171549
172149
|
let boundary = index.findSuffixStartForTokens(scaledN);
|
|
172150
|
+
const recentOpenArcCutoff = boundary;
|
|
171550
172151
|
let boundaryReason = boundary === 1 ? "whole-session-smaller-than-tail" : "size-walk";
|
|
171551
172152
|
const tokenAtBoundary = index.tokenForOrdinal(boundary);
|
|
171552
172153
|
if (boundary <= rawMessageCount && tokenAtBoundary > Math.max(2 * scaledN, 64000) && boundary < rawMessageCount) {
|
|
171553
172154
|
boundary += 1;
|
|
171554
172155
|
boundaryReason = "huge-message-exception";
|
|
171555
172156
|
}
|
|
171556
|
-
boundary = fenceBoundaryForToolArcs(boundary, arcs, ctx.lastCompartmentEndOrdinal);
|
|
172157
|
+
boundary = fenceBoundaryForToolArcs(boundary, arcs, ctx.lastCompartmentEndOrdinal, recentOpenArcCutoff);
|
|
171557
172158
|
const snapped = semanticSnapBoundary({
|
|
171558
172159
|
messages,
|
|
171559
172160
|
index,
|
|
@@ -171563,7 +172164,7 @@ function resolveProtectedTailBoundary(ctx) {
|
|
|
171563
172164
|
});
|
|
171564
172165
|
if (snapped !== boundary)
|
|
171565
172166
|
boundaryReason = "semantic-snap";
|
|
171566
|
-
boundary = fenceBoundaryForToolArcs(snapped, arcs, ctx.lastCompartmentEndOrdinal);
|
|
172167
|
+
boundary = fenceBoundaryForToolArcs(snapped, arcs, ctx.lastCompartmentEndOrdinal, recentOpenArcCutoff);
|
|
171567
172168
|
let runtimeFloor = offset;
|
|
171568
172169
|
if (ctx.migrationFloorActive)
|
|
171569
172170
|
runtimeFloor = Math.max(runtimeFloor, ctx.priorBoundaryOrdinal);
|
|
@@ -171599,7 +172200,8 @@ function resolveProtectedTailBoundary(ctx) {
|
|
|
171599
172200
|
offset,
|
|
171600
172201
|
arcs,
|
|
171601
172202
|
lastCompartmentEndOrdinal: ctx.lastCompartmentEndOrdinal,
|
|
171602
|
-
capTokens: perRunCap
|
|
172203
|
+
capTokens: perRunCap,
|
|
172204
|
+
recentOpenArcCutoff
|
|
171603
172205
|
});
|
|
171604
172206
|
const rawRangeFingerprint = computeRawRangeFingerprint(messages, offset, head.eligibleEndOrdinal);
|
|
171605
172207
|
return {
|
|
@@ -171650,7 +172252,7 @@ function resolveBoundaryContext(args) {
|
|
|
171650
172252
|
}
|
|
171651
172253
|
let storedTokenTotals;
|
|
171652
172254
|
try {
|
|
171653
|
-
storedTokenTotals = getAllStatusTagTokenTotalsFlat(args.db, args.sessionId).totals;
|
|
172255
|
+
storedTokenTotals = getAllStatusTagTokenTotalsFlat(args.db, args.sessionId, args.taggerFloor ?? 0).totals;
|
|
171654
172256
|
} catch (error51) {
|
|
171655
172257
|
sessionLog(args.sessionId, "protected-tail stored-token map unavailable (live fallback):", error51);
|
|
171656
172258
|
}
|
|
@@ -171767,6 +172369,38 @@ var DEFAULT_MIN_COMMIT_CLUSTERS_FOR_TRIGGER = 3;
|
|
|
171767
172369
|
var TAIL_SIZE_TRIGGER_MULTIPLIER = 3;
|
|
171768
172370
|
var FORCE_COMPARTMENT_PERCENTAGE = 80;
|
|
171769
172371
|
var BLOCK_UNTIL_DONE_PERCENTAGE = 95;
|
|
172372
|
+
var CONTENT_TAG_OWNER_SUFFIX = /:(?:p|file)\d+$/;
|
|
172373
|
+
function tagOwnerMessageId(row) {
|
|
172374
|
+
if (row.type === "tool")
|
|
172375
|
+
return row.tool_owner_message_id ?? row.message_id;
|
|
172376
|
+
return row.message_id.replace(CONTENT_TAG_OWNER_SUFFIX, "");
|
|
172377
|
+
}
|
|
172378
|
+
function getActiveOrDroppedTagOwnerMessageIds(db, sessionId, floor = 0) {
|
|
172379
|
+
const rows = floor > 0 ? db.prepare(`SELECT type, message_id, tool_owner_message_id
|
|
172380
|
+
FROM tags
|
|
172381
|
+
WHERE session_id = ? AND status IN ('active', 'dropped') AND tag_number >= ?`).all(sessionId, floor) : db.prepare(`SELECT type, message_id, tool_owner_message_id
|
|
172382
|
+
FROM tags
|
|
172383
|
+
WHERE session_id = ? AND status IN ('active', 'dropped')`).all(sessionId);
|
|
172384
|
+
const owners = new Set;
|
|
172385
|
+
for (const row of rows)
|
|
172386
|
+
owners.add(tagOwnerMessageId(row));
|
|
172387
|
+
return owners;
|
|
172388
|
+
}
|
|
172389
|
+
function estimateUntaggedInMemoryTailUpperBound(db, sessionId, inMemoryTail, taggerFloor = 0) {
|
|
172390
|
+
const lastCompartmentEnd = getLastCompartmentEndMessage(db, sessionId);
|
|
172391
|
+
const coveredOwnerMessageIds = getActiveOrDroppedTagOwnerMessageIds(db, sessionId, taggerFloor);
|
|
172392
|
+
let total = 0;
|
|
172393
|
+
for (const message of inMemoryTail.messages) {
|
|
172394
|
+
if (message.ordinal <= lastCompartmentEnd)
|
|
172395
|
+
continue;
|
|
172396
|
+
if (coveredOwnerMessageIds.has(message.id))
|
|
172397
|
+
continue;
|
|
172398
|
+
total += estimateTrueRawMessageTokens(message, {
|
|
172399
|
+
providerShapeVersion: "opencode-v1"
|
|
172400
|
+
}).total;
|
|
172401
|
+
}
|
|
172402
|
+
return total;
|
|
172403
|
+
}
|
|
171770
172404
|
function getProactiveCompartmentTriggerPercentage(executeThresholdPercentage) {
|
|
171771
172405
|
return Math.max(0, executeThresholdPercentage - PROACTIVE_TRIGGER_OFFSET_PERCENTAGE);
|
|
171772
172406
|
}
|
|
@@ -171820,7 +172454,7 @@ function resolveBoundaryContextLimit(usage, fallbackContextLimit) {
|
|
|
171820
172454
|
}
|
|
171821
172455
|
return 128000;
|
|
171822
172456
|
}
|
|
171823
|
-
function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail) {
|
|
172457
|
+
function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail, taggerFloor = 0) {
|
|
171824
172458
|
return withRawSessionMessageCache(() => {
|
|
171825
172459
|
try {
|
|
171826
172460
|
const memoryPrimed = inMemoryTail ? primeInMemoryTailRawMessageCache({
|
|
@@ -171849,7 +172483,8 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
|
|
|
171849
172483
|
contextLimit: resolveBoundaryContextLimit(usage, contextLimit),
|
|
171850
172484
|
executeThresholdPercentage,
|
|
171851
172485
|
usage,
|
|
171852
|
-
usageSource: "live"
|
|
172486
|
+
usageSource: "live",
|
|
172487
|
+
taggerFloor
|
|
171853
172488
|
});
|
|
171854
172489
|
const hasProtectedEligibleHead = boundary.offset < boundary.protectedTailStart;
|
|
171855
172490
|
if (!hasProtectedEligibleHead) {
|
|
@@ -171880,7 +172515,7 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
|
|
|
171880
172515
|
}
|
|
171881
172516
|
});
|
|
171882
172517
|
}
|
|
171883
|
-
function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, clearReasoningAge, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail) {
|
|
172518
|
+
function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, clearReasoningAge, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail, taggerFloorOverride) {
|
|
171884
172519
|
if (sessionMeta.compartmentInProgress) {
|
|
171885
172520
|
sessionLog(sessionId, `compartment trigger: skipped — historian already in progress (usage=${usage.percentage.toFixed(1)}%)`);
|
|
171886
172521
|
return { shouldFire: false };
|
|
@@ -171894,14 +172529,17 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
171894
172529
|
inMemoryTail = undefined;
|
|
171895
172530
|
}
|
|
171896
172531
|
}
|
|
172532
|
+
const taggerFloor = taggerFloorOverride !== undefined && taggerFloorOverride > 0 ? taggerFloorOverride : inMemoryTail ? deriveTagLoadFloor(db, sessionId, inMemoryTail.messages.map((m) => m.id)) : 0;
|
|
171897
172533
|
const proactiveFloorForGate = getProactiveCompartmentTriggerPercentage(executeThresholdPercentage);
|
|
171898
|
-
if (
|
|
172534
|
+
if (usage.percentage < proactiveFloorForGate) {
|
|
171899
172535
|
try {
|
|
171900
|
-
const { bound, nullCount } = getTriggerTagTokenUpperBound(db, sessionId);
|
|
172536
|
+
const { bound: persistedBound, nullCount } = getTriggerTagTokenUpperBound(db, sessionId, taggerFloor);
|
|
171901
172537
|
if (nullCount === 0) {
|
|
171902
|
-
const
|
|
172538
|
+
const untaggedUpperBound = inMemoryTail ? estimateUntaggedInMemoryTailUpperBound(db, sessionId, inMemoryTail, taggerFloor) : 0;
|
|
172539
|
+
const eligibleUpperBound = persistedBound + untaggedUpperBound;
|
|
171903
172540
|
if (eligibleUpperBound < triggerBudget) {
|
|
171904
|
-
|
|
172541
|
+
const memorySuffix = inMemoryTail ? ` (persisted=${persistedBound}, untagged-memory≤${untaggedUpperBound})` : "";
|
|
172542
|
+
sessionLog(sessionId, `compartment trigger: cheap-skip at ${usage.percentage.toFixed(1)}% (below proactive floor ${proactiveFloorForGate}%) — live-tail upper bound ${eligibleUpperBound}${memorySuffix} < triggerBudget ${triggerBudget}; no size trigger possible, skipped full raw read`);
|
|
171905
172543
|
return { shouldFire: false };
|
|
171906
172544
|
}
|
|
171907
172545
|
}
|
|
@@ -171909,7 +172547,7 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
171909
172547
|
sessionLog(sessionId, `compartment trigger: cheap-gate skipped (falling through to full read): ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
171910
172548
|
}
|
|
171911
172549
|
}
|
|
171912
|
-
const tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail);
|
|
172550
|
+
const tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail, taggerFloor);
|
|
171913
172551
|
if (!tailInfo.hasNewRawHistory) {
|
|
171914
172552
|
try {
|
|
171915
172553
|
const lastCompartmentEnd = getLastCompartmentEndMessage(db, sessionId);
|
|
@@ -172073,6 +172711,13 @@ function computePressure(input) {
|
|
|
172073
172711
|
function approxThousands(tokens) {
|
|
172074
172712
|
return `${Math.round(tokens / 1000)}k`;
|
|
172075
172713
|
}
|
|
172714
|
+
function formatOldestReclaimableHint(hint) {
|
|
172715
|
+
if (!hint || hint.length === 0)
|
|
172716
|
+
return "";
|
|
172717
|
+
const rendered = hint.slice(0, 4).map((tag) => `§${tag.tagNumber}§ ${tag.toolName ?? "tool"}`).join(" · ");
|
|
172718
|
+
return rendered.length > 0 ? `
|
|
172719
|
+
oldest reclaimable: ${rendered}.` : "";
|
|
172720
|
+
}
|
|
172076
172721
|
var CHANNEL2_USABLE_FRACTION = 1 / 3;
|
|
172077
172722
|
var CHANNEL2_MIN_RECLAIMABLE = 1e4;
|
|
172078
172723
|
function shouldTriggerChannel2(input) {
|
|
@@ -172082,14 +172727,16 @@ function shouldTriggerChannel2(input) {
|
|
|
172082
172727
|
return true;
|
|
172083
172728
|
return input.reclaimableTokens >= input.usableTokens * CHANNEL2_USABLE_FRACTION;
|
|
172084
172729
|
}
|
|
172085
|
-
function buildChannel2Reminder(undroppedTokens) {
|
|
172730
|
+
function buildChannel2Reminder(undroppedTokens, hint) {
|
|
172086
172731
|
const amount = approxThousands(undroppedTokens);
|
|
172732
|
+
const hintText = formatOldestReclaimableHint(hint);
|
|
172087
172733
|
return `<system-reminder>
|
|
172088
|
-
` + `Routine context housekeeping is near: a large span of this session will be comparted soon, ` + `and ~${amount} tokens of tool output remain unreduced. Drop spent outputs with ctx_reduce ` + `first so the archived span is the part that matters
|
|
172734
|
+
` + `Routine context housekeeping is near: a large span of this session will be comparted soon, ` + `and ~${amount} tokens of tool output remain unreduced. Drop spent outputs with ctx_reduce ` + `first so the archived span is the part that matters.${hintText}
|
|
172089
172735
|
` + `</system-reminder>`;
|
|
172090
172736
|
}
|
|
172091
|
-
function buildChannel1Reminder(level, undroppedTokens) {
|
|
172737
|
+
function buildChannel1Reminder(level, undroppedTokens, hint) {
|
|
172092
172738
|
const amount = approxThousands(undroppedTokens);
|
|
172739
|
+
const hintText = formatOldestReclaimableHint(hint);
|
|
172093
172740
|
let body;
|
|
172094
172741
|
switch (level) {
|
|
172095
172742
|
case "gentle":
|
|
@@ -172105,7 +172752,7 @@ function buildChannel1Reminder(level, undroppedTokens) {
|
|
|
172105
172752
|
return `
|
|
172106
172753
|
|
|
172107
172754
|
<system-reminder>
|
|
172108
|
-
${body}
|
|
172755
|
+
${body}${hintText}
|
|
172109
172756
|
</system-reminder>`;
|
|
172110
172757
|
}
|
|
172111
172758
|
|
|
@@ -172653,6 +173300,41 @@ function renderMemoryBlockV2(memories, wrapper = "project-memory", renderOptions
|
|
|
172653
173300
|
`);
|
|
172654
173301
|
}
|
|
172655
173302
|
|
|
173303
|
+
// ../plugin/src/hooks/magic-context/tool-reclaim.ts
|
|
173304
|
+
function buildSyntheticToolReclaimOps(input) {
|
|
173305
|
+
const watermark = Math.max(0, input.watermark);
|
|
173306
|
+
if (watermark <= 0)
|
|
173307
|
+
return [];
|
|
173308
|
+
const realPendingTagIds = new Set((input.pendingOps ?? []).map((op) => op.tagId));
|
|
173309
|
+
const tags = getActiveTagsBySession(input.db, input.sessionId);
|
|
173310
|
+
const synthetic = [];
|
|
173311
|
+
for (const tag of tags) {
|
|
173312
|
+
if (tag.type !== "tool")
|
|
173313
|
+
continue;
|
|
173314
|
+
if (tag.status !== "active")
|
|
173315
|
+
continue;
|
|
173316
|
+
if (tag.tagNumber > watermark)
|
|
173317
|
+
continue;
|
|
173318
|
+
if (realPendingTagIds.has(tag.tagNumber))
|
|
173319
|
+
continue;
|
|
173320
|
+
if (input.targets.get(tag.tagNumber)?.canDrop?.() !== true)
|
|
173321
|
+
continue;
|
|
173322
|
+
synthetic.push({
|
|
173323
|
+
id: 0,
|
|
173324
|
+
sessionId: input.sessionId,
|
|
173325
|
+
tagId: tag.tagNumber,
|
|
173326
|
+
operation: "drop",
|
|
173327
|
+
queuedAt: 0
|
|
173328
|
+
});
|
|
173329
|
+
}
|
|
173330
|
+
return synthetic;
|
|
173331
|
+
}
|
|
173332
|
+
function advanceToolReclaimWatermarkToCurrentMax(db, sessionId) {
|
|
173333
|
+
const maxTagNumber = getMaxTagNumberBySession(db, sessionId);
|
|
173334
|
+
advanceToolReclaimWatermark(db, sessionId, maxTagNumber);
|
|
173335
|
+
return maxTagNumber;
|
|
173336
|
+
}
|
|
173337
|
+
|
|
172656
173338
|
// src/context-handler.ts
|
|
172657
173339
|
init_logger();
|
|
172658
173340
|
|
|
@@ -173063,7 +173745,7 @@ function tagToolPart(args) {
|
|
|
173063
173745
|
const tagged = prependTag(tagId, text);
|
|
173064
173746
|
args.part.setText(tagged);
|
|
173065
173747
|
}
|
|
173066
|
-
args.targets.set(tagId, buildToolTarget(args.part, args.message));
|
|
173748
|
+
args.targets.set(tagId, buildToolTarget(args.part, args.message, tagId));
|
|
173067
173749
|
}
|
|
173068
173750
|
function setToolContentOrText(part, content) {
|
|
173069
173751
|
try {
|
|
@@ -173103,7 +173785,7 @@ function buildAggregateTarget(tagId, occurrences) {
|
|
|
173103
173785
|
return any2 ? "removed" : "absent";
|
|
173104
173786
|
},
|
|
173105
173787
|
truncate() {
|
|
173106
|
-
const sentinel =
|
|
173788
|
+
const sentinel = `[dropped §${tagId}§]`;
|
|
173107
173789
|
let any2 = false;
|
|
173108
173790
|
for (const occ of occurrences) {
|
|
173109
173791
|
if (setToolContentOrText(occ.part, sentinel)) {
|
|
@@ -173135,7 +173817,7 @@ function buildTextTarget(part, message) {
|
|
|
173135
173817
|
}
|
|
173136
173818
|
};
|
|
173137
173819
|
}
|
|
173138
|
-
function buildToolTarget(part, message) {
|
|
173820
|
+
function buildToolTarget(part, message, tagId) {
|
|
173139
173821
|
return {
|
|
173140
173822
|
setContent(content) {
|
|
173141
173823
|
return setToolContentOrText(part, content);
|
|
@@ -173144,11 +173826,11 @@ function buildToolTarget(part, message) {
|
|
|
173144
173826
|
return part.getText() ?? null;
|
|
173145
173827
|
},
|
|
173146
173828
|
drop() {
|
|
173147
|
-
const replaced = part.replaceWithSentinel(`[dropped §${
|
|
173829
|
+
const replaced = part.replaceWithSentinel(`[dropped §${tagId}§]`);
|
|
173148
173830
|
return replaced ? "removed" : "absent";
|
|
173149
173831
|
},
|
|
173150
173832
|
truncate() {
|
|
173151
|
-
const ok = setToolContentOrText(part,
|
|
173833
|
+
const ok = setToolContentOrText(part, `[dropped §${tagId}§]`);
|
|
173152
173834
|
return ok ? "truncated" : "absent";
|
|
173153
173835
|
},
|
|
173154
173836
|
message: {
|
|
@@ -174179,7 +174861,7 @@ async function runAutoSearchHintForPi(args) {
|
|
|
174179
174861
|
embeddingEnabled,
|
|
174180
174862
|
gitCommitsEnabled,
|
|
174181
174863
|
embedQuery: async (text, signal) => {
|
|
174182
|
-
const result = await embedTextForProject(options.projectPath, text, signal);
|
|
174864
|
+
const result = await embedTextForProject(options.projectPath, text, signal, "query");
|
|
174183
174865
|
return result?.vector ?? null;
|
|
174184
174866
|
},
|
|
174185
174867
|
isEmbeddingRuntimeEnabled: () => embeddingEnabled === true,
|
|
@@ -174433,9 +175115,10 @@ function maybeChannel1ReminderForToolResult(args) {
|
|
|
174433
175115
|
return null;
|
|
174434
175116
|
return {
|
|
174435
175117
|
type: "text",
|
|
174436
|
-
text: buildChannel1Reminder(decision.level, decision.undroppedTokens)
|
|
175118
|
+
text: buildChannel1Reminder(decision.level, decision.undroppedTokens, state.oldestReclaimableToolTags)
|
|
174437
175119
|
};
|
|
174438
175120
|
}
|
|
175121
|
+
var CHANNEL2_NUDGE_CUSTOM_TYPE = "magic-context:ceiling-nudge";
|
|
174439
175122
|
function maybeDeliverChannel2Pi(pi, db, sessionId, deliverAs = "followUp") {
|
|
174440
175123
|
let state;
|
|
174441
175124
|
try {
|
|
@@ -174463,9 +175146,12 @@ function maybeDeliverChannel2Pi(pi, db, sessionId, deliverAs = "followUp") {
|
|
|
174463
175146
|
if (!casChannel2NudgeState(db, sessionId, "pending", "claimed"))
|
|
174464
175147
|
return false;
|
|
174465
175148
|
try {
|
|
174466
|
-
pi.
|
|
174467
|
-
|
|
174468
|
-
|
|
175149
|
+
pi.sendMessage({
|
|
175150
|
+
customType: CHANNEL2_NUDGE_CUSTOM_TYPE,
|
|
175151
|
+
content: buildChannel2Reminder(undropped, baseline.oldestReclaimableToolTags),
|
|
175152
|
+
display: false,
|
|
175153
|
+
details: { kind: "channel-2-ceiling-nudge" }
|
|
175154
|
+
}, { deliverAs });
|
|
174469
175155
|
} catch (error51) {
|
|
174470
175156
|
try {
|
|
174471
175157
|
casChannel2NudgeState(db, sessionId, "claimed", "pending");
|
|
@@ -174657,6 +175343,51 @@ function planEmergencyDrop(input) {
|
|
|
174657
175343
|
};
|
|
174658
175344
|
}
|
|
174659
175345
|
|
|
175346
|
+
// ../plugin/src/hooks/magic-context/system-injection-stripper.ts
|
|
175347
|
+
var SYSTEM_INJECTION_MARKERS = [
|
|
175348
|
+
"<!-- OMO_INTERNAL_INITIATOR -->",
|
|
175349
|
+
"[SYSTEM DIRECTIVE: MAGIC-CONTEXT",
|
|
175350
|
+
"[SYSTEM DIRECTIVE: OH-MY-OPENCODE",
|
|
175351
|
+
"[Category+Skill Reminder]",
|
|
175352
|
+
"[EDIT ERROR - IMMEDIATE ACTION REQUIRED]",
|
|
175353
|
+
"[task CALL FAILED - IMMEDIATE RETRY REQUIRED]",
|
|
175354
|
+
"[EMERGENCY CONTEXT WINDOW WARNING]",
|
|
175355
|
+
"Unstable background agent appears idle",
|
|
175356
|
+
"**THE SUBAGENT JUST CLAIMED THIS TASK IS DONE."
|
|
175357
|
+
];
|
|
175358
|
+
var SYSTEM_REMINDER_REGEX = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
|
|
175359
|
+
var OMO_MARKER_REGEX = /<!-- OMO_INTERNAL_INITIATOR -->/g;
|
|
175360
|
+
function stripSystemInjection(text) {
|
|
175361
|
+
let hasInjection = false;
|
|
175362
|
+
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
175363
|
+
if (text.includes(marker)) {
|
|
175364
|
+
hasInjection = true;
|
|
175365
|
+
break;
|
|
175366
|
+
}
|
|
175367
|
+
}
|
|
175368
|
+
if (SYSTEM_REMINDER_REGEX.test(text))
|
|
175369
|
+
hasInjection = true;
|
|
175370
|
+
SYSTEM_REMINDER_REGEX.lastIndex = 0;
|
|
175371
|
+
if (!hasInjection)
|
|
175372
|
+
return null;
|
|
175373
|
+
let cleaned = text;
|
|
175374
|
+
cleaned = cleaned.replace(SYSTEM_REMINDER_REGEX, "");
|
|
175375
|
+
cleaned = cleaned.replace(OMO_MARKER_REGEX, "");
|
|
175376
|
+
cleaned = cleaned.replace(/\[SYSTEM DIRECTIVE: OH-MY-(?:OPENCODE|CLAUDE)[^\]]*\][\s\S]*?(?=\n\n(?!\s*[-*])|$)/g, "");
|
|
175377
|
+
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
175378
|
+
if (marker.startsWith("<!-- ") || marker.startsWith("[SYSTEM DIRECTIVE"))
|
|
175379
|
+
continue;
|
|
175380
|
+
const idx = cleaned.indexOf(marker);
|
|
175381
|
+
if (idx === -1)
|
|
175382
|
+
continue;
|
|
175383
|
+
const blockEnd = cleaned.indexOf(`
|
|
175384
|
+
|
|
175385
|
+
`, idx + marker.length);
|
|
175386
|
+
cleaned = blockEnd !== -1 ? cleaned.slice(0, idx) + cleaned.slice(blockEnd) : cleaned.slice(0, idx);
|
|
175387
|
+
}
|
|
175388
|
+
return cleaned.trim();
|
|
175389
|
+
}
|
|
175390
|
+
|
|
174660
175391
|
// src/heuristic-cleanup-pi.ts
|
|
174661
175392
|
init_logger();
|
|
174662
175393
|
var DEDUP_SAFE_TOOLS = new Set([
|
|
@@ -174760,6 +175491,7 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config2, pr
|
|
|
174760
175491
|
const protectedCutoff = maxTag - config2.protectedTags;
|
|
174761
175492
|
const toolAgeCutoff = protectedCutoff;
|
|
174762
175493
|
let droppedTools = 0;
|
|
175494
|
+
let emergencyDroppedTools = 0;
|
|
174763
175495
|
let deduplicatedTools = 0;
|
|
174764
175496
|
let droppedInjections = 0;
|
|
174765
175497
|
let droppedStaleReduceCalls = 0;
|
|
@@ -174792,6 +175524,7 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config2, pr
|
|
|
174792
175524
|
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
174793
175525
|
updateTagDropMode(db, sessionId, tag.tagNumber, "full");
|
|
174794
175526
|
droppedTools++;
|
|
175527
|
+
emergencyDroppedTools++;
|
|
174795
175528
|
}
|
|
174796
175529
|
}
|
|
174797
175530
|
setEmergencyDropSample(db, sessionId, emergency.currentTotalInputTokens);
|
|
@@ -174815,10 +175548,14 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config2, pr
|
|
|
174815
175548
|
if (!matched)
|
|
174816
175549
|
continue;
|
|
174817
175550
|
const target = targets.get(tag.tagNumber);
|
|
174818
|
-
target?.drop?.();
|
|
175551
|
+
const result = target?.drop?.() ?? "absent";
|
|
175552
|
+
if (result === "incomplete")
|
|
175553
|
+
continue;
|
|
174819
175554
|
updateTagDropMode(db, sessionId, tag.tagNumber, "full");
|
|
174820
175555
|
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
174821
|
-
|
|
175556
|
+
if (result === "removed" || result === "truncated") {
|
|
175557
|
+
droppedStaleReduceCalls++;
|
|
175558
|
+
}
|
|
174822
175559
|
}
|
|
174823
175560
|
})();
|
|
174824
175561
|
}
|
|
@@ -174890,7 +175627,9 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config2, pr
|
|
|
174890
175627
|
continue;
|
|
174891
175628
|
updateTagDropMode(db, sessionId, tag.tagNumber, "full");
|
|
174892
175629
|
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
174893
|
-
|
|
175630
|
+
if (result === "removed" || result === "truncated") {
|
|
175631
|
+
deduplicatedTools++;
|
|
175632
|
+
}
|
|
174894
175633
|
}
|
|
174895
175634
|
}
|
|
174896
175635
|
})();
|
|
@@ -174899,6 +175638,7 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config2, pr
|
|
|
174899
175638
|
sessionLog(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, stale ctx_reduce=${droppedStaleReduceCalls}, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
|
|
174900
175639
|
}
|
|
174901
175640
|
let compressedTextTags = 0;
|
|
175641
|
+
let mutatedTextTags = 0;
|
|
174902
175642
|
if (config2.caveman?.enabled) {
|
|
174903
175643
|
const cavemanResult = applyCavemanCleanup(sessionId, db, targets, tags, {
|
|
174904
175644
|
enabled: true,
|
|
@@ -174906,13 +175646,16 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config2, pr
|
|
|
174906
175646
|
protectedTags: config2.protectedTags
|
|
174907
175647
|
});
|
|
174908
175648
|
compressedTextTags = cavemanResult.compressedToLite + cavemanResult.compressedToFull + cavemanResult.compressedToUltra;
|
|
175649
|
+
mutatedTextTags = cavemanResult.mutatedTextTags;
|
|
174909
175650
|
}
|
|
174910
175651
|
return {
|
|
174911
175652
|
droppedTools,
|
|
174912
175653
|
deduplicatedTools,
|
|
174913
175654
|
droppedInjections,
|
|
174914
175655
|
droppedStaleReduceCalls,
|
|
174915
|
-
|
|
175656
|
+
emergencyDroppedTools,
|
|
175657
|
+
compressedTextTags,
|
|
175658
|
+
mutatedTextTags
|
|
174916
175659
|
};
|
|
174917
175660
|
}
|
|
174918
175661
|
function buildMessageIdToMaxTagFromTargets(targets) {
|
|
@@ -176208,7 +176951,7 @@ async function embedAndStoreCompartmentChunks(db, sessionId, projectPath, compar
|
|
|
176208
176951
|
for (const compartment of compartments) {
|
|
176209
176952
|
try {
|
|
176210
176953
|
const fromMemory = compartment.sourceChunkText ? canonicalizeInMemoryChunkTextForEmbedding(compartment.sourceChunkText, compartment.startMessage, compartment.endMessage) : "";
|
|
176211
|
-
const canonicalText = fromMemory || buildCanonicalChunkTextFromFts(db, sessionId, compartment.startMessage, compartment.endMessage);
|
|
176954
|
+
const canonicalText = fromMemory || buildCanonicalChunkTextFromFts(db, sessionId, compartment.startMessage, compartment.endMessage) || buildCompartmentSummaryFallbackText(db, compartment.id);
|
|
176212
176955
|
if (canonicalText.length === 0)
|
|
176213
176956
|
continue;
|
|
176214
176957
|
const windows = chunkCanonicalText(canonicalText, compartment.startMessage, compartment.endMessage, maxInputTokens);
|
|
@@ -179401,6 +180144,7 @@ async function runPiHistorian(deps) {
|
|
|
179401
180144
|
} else {
|
|
179402
180145
|
recordHighPressureNoEligibleHead(db, boundarySnapshot);
|
|
179403
180146
|
}
|
|
180147
|
+
clearEmergencyDrainLatch(db, sessionId);
|
|
179404
180148
|
return;
|
|
179405
180149
|
}
|
|
179406
180150
|
const perRunCap = selectPerRunCap(boundarySnapshot);
|
|
@@ -179412,7 +180156,8 @@ async function runPiHistorian(deps) {
|
|
|
179412
180156
|
trueRawTokens: boundarySnapshot.trueRawEligibleTokens,
|
|
179413
180157
|
usagePercentage: boundarySnapshot.usagePercentage,
|
|
179414
180158
|
usable,
|
|
179415
|
-
perRunCap
|
|
180159
|
+
perRunCap,
|
|
180160
|
+
executeThresholdPercentage: boundarySnapshot.executeThresholdPercentage
|
|
179416
180161
|
});
|
|
179417
180162
|
if (!reserve.ok) {
|
|
179418
180163
|
sessionLog(sessionId, `historian rate-limit skip: ${reserve.skippedReason ?? "quota exhausted"}`);
|
|
@@ -179429,6 +180174,7 @@ async function runPiHistorian(deps) {
|
|
|
179429
180174
|
} else {
|
|
179430
180175
|
recordHighPressureNoEligibleHead(db, boundarySnapshot);
|
|
179431
180176
|
}
|
|
180177
|
+
clearEmergencyDrainLatch(db, sessionId);
|
|
179432
180178
|
telemetry.status = "noop";
|
|
179433
180179
|
telemetry.failureReason = "chunk empty after filtering";
|
|
179434
180180
|
rollbackDrainReservation();
|
|
@@ -179660,6 +180406,7 @@ ${chunkText}`,
|
|
|
179660
180406
|
}
|
|
179661
180407
|
appendCompartments(db, sessionId, newCompartments);
|
|
179662
180408
|
clearHistorianFailureState(db, sessionId);
|
|
180409
|
+
clearHistorianDrainFailure(db, sessionId);
|
|
179663
180410
|
recordProtectedTailPublicationFloor(db, sessionId, lastNewEnd + 1);
|
|
179664
180411
|
clearEmergencyRecovery(db, sessionId);
|
|
179665
180412
|
if (firstKeptEntryId && lastNewEndMessageId) {
|
|
@@ -179756,8 +180503,12 @@ ${chunkText}`,
|
|
|
179756
180503
|
await notify(buildHistorianFailureNotice(failCount, desc.brief));
|
|
179757
180504
|
}
|
|
179758
180505
|
} finally {
|
|
179759
|
-
if (!completedSuccessfully
|
|
179760
|
-
|
|
180506
|
+
if (!completedSuccessfully) {
|
|
180507
|
+
if (!retainDrainReservationForRetryThrottle) {
|
|
180508
|
+
rollbackDrainReservation();
|
|
180509
|
+
} else {
|
|
180510
|
+
recordHistorianDrainFailure(db, sessionId);
|
|
180511
|
+
}
|
|
179761
180512
|
}
|
|
179762
180513
|
updateSessionMeta(db, sessionId, { compartmentInProgress: false });
|
|
179763
180514
|
try {
|
|
@@ -179996,7 +180747,7 @@ var INLINE_THINKING_PATTERNS = [
|
|
|
179996
180747
|
/<thinking>[\s\S]*?<\/thinking>\s*/gi,
|
|
179997
180748
|
/<think>[\s\S]*?<\/think>\s*/gi
|
|
179998
180749
|
];
|
|
179999
|
-
var CLEARED = "
|
|
180750
|
+
var CLEARED = "";
|
|
180000
180751
|
function stripInlineThinkingMarkup(text) {
|
|
180001
180752
|
let cleaned = text;
|
|
180002
180753
|
for (const pattern of INLINE_THINKING_PATTERNS) {
|
|
@@ -180045,8 +180796,11 @@ function clearOldReasoningPi(args) {
|
|
|
180045
180796
|
for (const part of msg.content) {
|
|
180046
180797
|
if (part && typeof part === "object" && part.type === "thinking") {
|
|
180047
180798
|
const tp = part;
|
|
180048
|
-
if (tp.
|
|
180799
|
+
if (tp.redacted)
|
|
180800
|
+
continue;
|
|
180801
|
+
if (tp.thinking !== CLEARED || tp.thinkingSignature !== undefined) {
|
|
180049
180802
|
tp.thinking = CLEARED;
|
|
180803
|
+
tp.thinkingSignature = undefined;
|
|
180050
180804
|
cleared++;
|
|
180051
180805
|
}
|
|
180052
180806
|
}
|
|
@@ -180124,8 +180878,11 @@ function replayClearedReasoningPi(args) {
|
|
|
180124
180878
|
for (const part of msg.content) {
|
|
180125
180879
|
if (part && typeof part === "object" && part.type === "thinking") {
|
|
180126
180880
|
const tp = part;
|
|
180127
|
-
if (tp.
|
|
180881
|
+
if (tp.redacted)
|
|
180882
|
+
continue;
|
|
180883
|
+
if (tp.thinking !== CLEARED || tp.thinkingSignature !== undefined) {
|
|
180128
180884
|
tp.thinking = CLEARED;
|
|
180885
|
+
tp.thinkingSignature = undefined;
|
|
180129
180886
|
cleared++;
|
|
180130
180887
|
}
|
|
180131
180888
|
}
|
|
@@ -180289,9 +181046,7 @@ Context is managed for you entirely automatically — there's nothing to prune a
|
|
|
180289
181046
|
var CTX_NOTE_GUIDANCE = `Use \`ctx_note\` ONLY for genuinely future concerns — something to revisit much later, not work coming up in the next few turns (that's already in your active context) and not active multi-step work (use todos for that). Magic Context preserves your full context across both compaction and restarts, so an upcoming restart or "let's come back to this later" is never a reason to take a note — nothing is lost either way. Notes you do take survive compression and resurface at natural work boundaries (after commits, historian runs, todo completion).`;
|
|
180290
181047
|
var TOOL_HISTORY_GUIDANCE = `Compressed history intentionally omits tool calls and their outputs — summaries like "I edited file X" are historian records, not patterns to replicate. In the live conversation, older tool calls and their results are cleaned up to save context — you may see your own past messages referencing actions without the corresponding tool call or result visible. This is normal context management. ALWAYS use real tool calls; never simulate, fabricate, or inline tool outputs in your text. If there is no tool result message, the action did not happen. NEVER simulate, hallucinate or claim tool calls, command output, search results, file edits, or diffs in plain text as if they actually occurred.`;
|
|
180291
181048
|
var BASE_INTRO = (protectedTags) => `Messages and tool outputs are tagged with §N§ identifiers (e.g., §1§, §42§).
|
|
180292
|
-
Use \`ctx_reduce\` to
|
|
180293
|
-
- \`drop\`: Remove entirely (best for tool outputs you already acted on).
|
|
180294
|
-
Syntax: "3-5", "1,2,9", or "1-5,8,12-15". Last ${protectedTags} tags are protected.
|
|
181049
|
+
Use \`ctx_reduce\` to mark spent tagged content as discardable and reclaim space. Marking is NOT an immediate delete — it queues the content, which stays fully visible until space is actually needed (as soon as the next turn if you're already under pressure, much later if not), so mark a tool output as soon as you're done with it rather than hoarding the call for the end of the turn. The last ${protectedTags} tags are protected (marking one just queues it until it ages out). Syntax: "3-5", "1,2,9", or "1-5,8,12-15".
|
|
180295
181050
|
Do not announce or narrate \`ctx_reduce\` drops — just call the tool silently. Saying "I'll drop these outputs" wastes tokens the user does not care about.
|
|
180296
181051
|
${CTX_NOTE_GUIDANCE}
|
|
180297
181052
|
Use \`ctx_memory\` for durable project knowledge: write what future sessions must know, update/archive/merge the memories you see in \`<project-memory>\` when they drift. Memories persist across sessions and every new session starts with them.
|
|
@@ -180310,7 +181065,7 @@ Use \`ctx_expand\` to recover the raw conversation behind a \`<compartment>\` su
|
|
|
180310
181065
|
\`ctx_search\` returns ranked results from memories, git commits, and raw message history. Use message ordinals from results with \`ctx_expand\` to retrieve surrounding conversation context.
|
|
180311
181066
|
${TOOL_HISTORY_GUIDANCE}
|
|
180312
181067
|
NEVER drop large ranges blindly (e.g., "1-50"). Review each tag before deciding.
|
|
180313
|
-
|
|
181068
|
+
Keep your user's instructions and intent — never drop a user message for its directive, even an old one. But a large block of pasted content inside a user message (logs, data dumps, long code, attachments) is fair to mark discardable once you've extracted what you need — it stays searchable via \`ctx_search\`.
|
|
180314
181069
|
NEVER drop assistant text messages unless they are exceptionally large. Your conversation messages are lightweight; only large tool outputs are worth dropping.
|
|
180315
181070
|
Before your turn finishes, consider using \`ctx_reduce\` to drop large tool outputs you no longer need.`;
|
|
180316
181071
|
var BASE_INTRO_NO_REDUCE = () => `${CTX_NOTE_GUIDANCE}
|
|
@@ -181442,6 +182197,11 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
181442
182197
|
updateSessionProjectTracking(sessionId, projectIdentity, options.db);
|
|
181443
182198
|
logTransformTiming(sessionId, "findSessionId", tFindSession, `messages=${event.messages.length}`);
|
|
181444
182199
|
const branchEntries = readPiBranchEntriesForContext(ctx, sessionId);
|
|
182200
|
+
schedulePiTransformDecisionResolve({
|
|
182201
|
+
db: options.db,
|
|
182202
|
+
sessionId,
|
|
182203
|
+
branchEntries
|
|
182204
|
+
});
|
|
181445
182205
|
const rawMessageProvider = {
|
|
181446
182206
|
readMessages: () => branchEntries !== null ? convertEntriesToRawMessages([...branchEntries]) : readPiSessionMessages(ctx),
|
|
181447
182207
|
readMessageById: (messageId) => readPiSessionMessageById(ctx, messageId)
|
|
@@ -181678,6 +182438,20 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
181678
182438
|
appendCompaction: resolvePiAppendCompaction(ctx),
|
|
181679
182439
|
readBranchEntries: resolvePiReadBranchEntries(ctx)
|
|
181680
182440
|
});
|
|
182441
|
+
const piDecisionSnapshotNewestAssistant = branchEntries === null ? undefined : findNewestPiAssistantEntryId(branchEntries);
|
|
182442
|
+
if (result.bustedThisPass && piDecisionSnapshotNewestAssistant !== undefined) {
|
|
182443
|
+
recordPendingPiTransformDecision(sessionId, {
|
|
182444
|
+
tsMs: Date.now(),
|
|
182445
|
+
decision: schedulerDecision,
|
|
182446
|
+
materialized: result.materialized,
|
|
182447
|
+
materializeReason: normalizeMaterializeReason("pi", result.materializeReason, result.materialized),
|
|
182448
|
+
emergency: result.emergency,
|
|
182449
|
+
droppedTokens: result.droppedTokens,
|
|
182450
|
+
droppedCount: result.droppedCount,
|
|
182451
|
+
inputTokens: usageInputTokens,
|
|
182452
|
+
bustedThisPass: true
|
|
182453
|
+
}, piDecisionSnapshotNewestAssistant);
|
|
182454
|
+
}
|
|
181681
182455
|
if (options.historian) {
|
|
181682
182456
|
maybeFireHistorian({
|
|
181683
182457
|
ctx,
|
|
@@ -181787,6 +182561,7 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
181787
182561
|
const executeThresholdTokensPi = Math.round((usageContextLimit ?? 0) * resolvedExecuteThresholdPct / 100);
|
|
181788
182562
|
const usableTokensPi = Math.max(0, executeThresholdTokensPi - usageInputTokens + liveTailTokens);
|
|
181789
182563
|
resetLastNudgeCycleIfTailShrank(options.db, sessionId, tailToolTokens);
|
|
182564
|
+
const oldestReclaimableToolTags = getOldestActiveUnprotectedToolTags(options.db, sessionId, options.protectedTags ?? 20);
|
|
181790
182565
|
setPiChannel1Baseline(sessionId, {
|
|
181791
182566
|
tailToolTokens,
|
|
181792
182567
|
historyBudgetTokens: historyBudgetTokens ?? 0,
|
|
@@ -181795,7 +182570,8 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
181795
182570
|
lastInputTokens: usageInputTokens,
|
|
181796
182571
|
turnToolTokens: 0,
|
|
181797
182572
|
usableTokens: usableTokensPi,
|
|
181798
|
-
reducedSinceRefresh: false
|
|
182573
|
+
reducedSinceRefresh: false,
|
|
182574
|
+
oldestReclaimableToolTags
|
|
181799
182575
|
});
|
|
181800
182576
|
if (usageContextLimit && usageContextLimit > 0 && resolvedExecuteThresholdPct > 0) {
|
|
181801
182577
|
const channel2ShouldTrigger = shouldTriggerChannel2({
|
|
@@ -181823,6 +182599,7 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
181823
182599
|
logTransformTiming(sessionId, "postTransformPhase", tPostTransform);
|
|
181824
182600
|
sessionLog(sessionId, `transform completed in ${(performance.now() - transformStartTime).toFixed(1)}ms (${outputMessages.length} messages, ${result.targetCount} targets, watermark: ${result.reasoningWatermark})`);
|
|
181825
182601
|
clearLastTransformErrorIfSet(options.db, sessionId);
|
|
182602
|
+
options.maybeAutoEmbedSession?.(sessionId, projectDirectory, projectIdentity);
|
|
181826
182603
|
return { messages: outputMessages };
|
|
181827
182604
|
} catch (err) {
|
|
181828
182605
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -182169,6 +182946,13 @@ async function runPipeline(args) {
|
|
|
182169
182946
|
let historyWasConsumedThisPass = false;
|
|
182170
182947
|
let materializationSatisfiedThisPass = false;
|
|
182171
182948
|
let pendingOpsAppliedThisPass = false;
|
|
182949
|
+
let pendingOpsDidMutate = false;
|
|
182950
|
+
let heuristicOrReasoningDidMutate = false;
|
|
182951
|
+
let didMutateFromFlushedStatuses = false;
|
|
182952
|
+
let droppedCount = 0;
|
|
182953
|
+
const droppedTokens = 0;
|
|
182954
|
+
let emergency = false;
|
|
182955
|
+
let autoReclaimDidMutateThisPass = false;
|
|
182172
182956
|
let suppressDeferredHistoryDrain = false;
|
|
182173
182957
|
let casLost = false;
|
|
182174
182958
|
const deferredHistoryWasPendingAtPassStart = deferredHistoryRefreshSessions.has(args.sessionId);
|
|
@@ -182254,7 +183038,10 @@ async function runPipeline(args) {
|
|
|
182254
183038
|
sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${pendingOps.length}, context=${args.contextUsage.percentage.toFixed(1)}%`);
|
|
182255
183039
|
try {
|
|
182256
183040
|
const tApplyPending = performance.now();
|
|
182257
|
-
applyPendingOperations(args.sessionId, args.db, targets, args.protectedTags, undefined, pendingOps);
|
|
183041
|
+
pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, targets, args.protectedTags, undefined, pendingOps);
|
|
183042
|
+
if (pendingOpsDidMutate) {
|
|
183043
|
+
droppedCount += pendingOps.length;
|
|
183044
|
+
}
|
|
182258
183045
|
logTransformTiming(args.sessionId, "applyPendingOperations", tApplyPending);
|
|
182259
183046
|
executedWorkThisPass = true;
|
|
182260
183047
|
materializationSatisfiedThisPass = true;
|
|
@@ -182276,7 +183063,7 @@ async function runPipeline(args) {
|
|
|
182276
183063
|
const flushedSliceTags = getTagsByNumbers(args.db, args.sessionId, targetTagNumbers);
|
|
182277
183064
|
logTransformTiming(args.sessionId, "getTagsByNumbers", tGetTags, `targets=${targetTagNumbers.length} fetched=${flushedSliceTags.length}`);
|
|
182278
183065
|
const tFlushed = performance.now();
|
|
182279
|
-
applyFlushedStatuses(args.sessionId, args.db, targets, flushedSliceTags);
|
|
183066
|
+
didMutateFromFlushedStatuses = applyFlushedStatuses(args.sessionId, args.db, targets, flushedSliceTags);
|
|
182280
183067
|
logTransformTiming(args.sessionId, "applyFlushedStatuses", tFlushed);
|
|
182281
183068
|
logTransformTiming(args.sessionId, "batchFinalize:flushed", tFlushed);
|
|
182282
183069
|
const messageIdToMaxTag = buildMessageIdToMaxTag(targets);
|
|
@@ -182338,6 +183125,11 @@ async function runPipeline(args) {
|
|
|
182338
183125
|
} : undefined,
|
|
182339
183126
|
caveman: args.heuristics.caveman
|
|
182340
183127
|
}, activeTags, stableIdResolver);
|
|
183128
|
+
const heuristicMutationCount = heuristicsResult.droppedTools + heuristicsResult.deduplicatedTools + heuristicsResult.droppedInjections + heuristicsResult.droppedStaleReduceCalls + heuristicsResult.mutatedTextTags;
|
|
183129
|
+
droppedCount += heuristicsResult.droppedTools + heuristicsResult.deduplicatedTools + heuristicsResult.droppedInjections + heuristicsResult.droppedStaleReduceCalls + heuristicsResult.mutatedTextTags;
|
|
183130
|
+
emergency ||= heuristicsResult.emergencyDroppedTools > 0;
|
|
183131
|
+
if (heuristicMutationCount > 0)
|
|
183132
|
+
heuristicOrReasoningDidMutate = true;
|
|
182341
183133
|
heuristicsExecuted = true;
|
|
182342
183134
|
executedWorkThisPass = true;
|
|
182343
183135
|
if (hasPendingMaterializeSignal) {
|
|
@@ -182346,7 +183138,7 @@ async function runPipeline(args) {
|
|
|
182346
183138
|
if (currentTurnId !== null) {
|
|
182347
183139
|
lastHeuristicsTurnIdBySession.set(args.sessionId, currentTurnId);
|
|
182348
183140
|
}
|
|
182349
|
-
logTransformTiming(args.sessionId, "applyHeuristicCleanup", tHeuristic, `droppedTools=${heuristicsResult.droppedTools} deduplicatedTools=${heuristicsResult.deduplicatedTools} droppedInjections=${heuristicsResult.droppedInjections} compressedTextTags=${heuristicsResult.compressedTextTags}`);
|
|
183141
|
+
logTransformTiming(args.sessionId, "applyHeuristicCleanup", tHeuristic, `droppedTools=${heuristicsResult.droppedTools} deduplicatedTools=${heuristicsResult.deduplicatedTools} droppedInjections=${heuristicsResult.droppedInjections} staleReduce=${heuristicsResult.droppedStaleReduceCalls} compressedTextTags=${heuristicsResult.compressedTextTags} mutatedTextTags=${heuristicsResult.mutatedTextTags}`);
|
|
182350
183142
|
} catch (err) {
|
|
182351
183143
|
sessionLog(args.sessionId, `heuristic cleanup failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
182352
183144
|
}
|
|
@@ -182383,6 +183175,10 @@ async function runPipeline(args) {
|
|
|
182383
183175
|
}
|
|
182384
183176
|
logTransformTiming(args.sessionId, "clearOldReasoning", tClearReasoning);
|
|
182385
183177
|
logTransformTiming(args.sessionId, "watermarkCleanup", tClearReasoning);
|
|
183178
|
+
if (clearOutcome.cleared > 0 || stripOutcome.stripped > 0) {
|
|
183179
|
+
heuristicOrReasoningDidMutate = true;
|
|
183180
|
+
droppedCount += clearOutcome.cleared + stripOutcome.stripped;
|
|
183181
|
+
}
|
|
182386
183182
|
if (combinedWatermark > prevWatermark || clearOutcome.cleared > 0 || stripOutcome.stripped > 0) {
|
|
182387
183183
|
executedWorkThisPass = true;
|
|
182388
183184
|
}
|
|
@@ -182390,7 +183186,36 @@ async function runPipeline(args) {
|
|
|
182390
183186
|
sessionLog(args.sessionId, `reasoning clearing failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
182391
183187
|
}
|
|
182392
183188
|
}
|
|
183189
|
+
const toolReclaimExecutePass = args.schedulerDecision === "execute";
|
|
183190
|
+
const alreadyMutatingThisPass = pendingOpsDidMutate || heuristicOrReasoningDidMutate;
|
|
183191
|
+
const emergencyDropEligible = args.forceMaterialization === true || args.contextUsage.percentage >= FORCE_MATERIALIZATION_PERCENTAGE;
|
|
183192
|
+
let autoReclaimTargetCount = 0;
|
|
183193
|
+
let autoReclaimDidMutate = false;
|
|
183194
|
+
if (toolReclaimExecutePass && alreadyMutatingThisPass && !emergencyDropEligible) {
|
|
183195
|
+
const reclaimMeta = getOrCreateSessionMeta(args.db, args.sessionId);
|
|
183196
|
+
const syntheticPendingOps = buildSyntheticToolReclaimOps({
|
|
183197
|
+
db: args.db,
|
|
183198
|
+
sessionId: args.sessionId,
|
|
183199
|
+
targets,
|
|
183200
|
+
watermark: reclaimMeta.toolReclaimWatermark ?? 0,
|
|
183201
|
+
pendingOps
|
|
183202
|
+
});
|
|
183203
|
+
autoReclaimTargetCount = syntheticPendingOps.length;
|
|
183204
|
+
if (syntheticPendingOps.length > 0) {
|
|
183205
|
+
autoReclaimDidMutate = applyPendingOperations(args.sessionId, args.db, targets, args.protectedTags, undefined, [], syntheticPendingOps);
|
|
183206
|
+
if (autoReclaimDidMutate) {
|
|
183207
|
+
droppedCount += syntheticPendingOps.length;
|
|
183208
|
+
autoReclaimDidMutateThisPass = true;
|
|
183209
|
+
}
|
|
183210
|
+
}
|
|
183211
|
+
}
|
|
182393
183212
|
transcript.commit();
|
|
183213
|
+
if (toolReclaimExecutePass) {
|
|
183214
|
+
advanceToolReclaimWatermarkToCurrentMax(args.db, args.sessionId);
|
|
183215
|
+
}
|
|
183216
|
+
if (autoReclaimTargetCount > 0) {
|
|
183217
|
+
sessionLog(args.sessionId, `tool reclaim auto-drop: targets=${autoReclaimTargetCount} mutated=${autoReclaimDidMutate}`);
|
|
183218
|
+
}
|
|
182394
183219
|
const postCommitStableIdByRef = new Map;
|
|
182395
183220
|
const postCommitEntryIdByRef = new Map;
|
|
182396
183221
|
for (let i = 0;i < args.messages.length; i++) {
|
|
@@ -182490,6 +183315,9 @@ async function runPipeline(args) {
|
|
|
182490
183315
|
} catch (err) {
|
|
182491
183316
|
sessionLog(args.sessionId, `token accounting failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
182492
183317
|
}
|
|
183318
|
+
const materialized = injectionResult?.m0Materialized === true;
|
|
183319
|
+
const materializeReason = injectionResult?.m0Reason ?? null;
|
|
183320
|
+
const bustedThisPass = didMutateFromFlushedStatuses || pendingOpsDidMutate || heuristicOrReasoningDidMutate || autoReclaimDidMutateThisPass || materialized || historyWasConsumedThisPass;
|
|
182493
183321
|
return {
|
|
182494
183322
|
messages: outputMessages,
|
|
182495
183323
|
heuristicsExecuted,
|
|
@@ -182498,6 +183326,12 @@ async function runPipeline(args) {
|
|
|
182498
183326
|
syntheticLeadingCount: injectionResult?.syntheticLeadingCount ?? 0,
|
|
182499
183327
|
heuristicsResult,
|
|
182500
183328
|
injectionResult,
|
|
183329
|
+
materialized,
|
|
183330
|
+
materializeReason,
|
|
183331
|
+
droppedTokens,
|
|
183332
|
+
droppedCount,
|
|
183333
|
+
emergency,
|
|
183334
|
+
bustedThisPass,
|
|
182501
183335
|
targetCount: targets.size,
|
|
182502
183336
|
reasoningWatermark: getOrCreateSessionMeta(args.db, args.sessionId).clearedReasoningThroughTag ?? 0,
|
|
182503
183337
|
activeTags,
|
|
@@ -182674,6 +183508,7 @@ function clearContextHandlerSession(sessionId) {
|
|
|
182674
183508
|
rawMessageProviderUnregistersBySession.delete(sessionId);
|
|
182675
183509
|
}
|
|
182676
183510
|
clearSessionTracking(sessionId);
|
|
183511
|
+
clearPiEmbedSessionState(sessionId);
|
|
182677
183512
|
}
|
|
182678
183513
|
|
|
182679
183514
|
// src/commands/ctx-flush.ts
|
|
@@ -182923,6 +183758,12 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
|
|
|
182923
183758
|
// ../plugin/src/hooks/magic-context/compartment-runner-historian.ts
|
|
182924
183759
|
import { mkdirSync as mkdirSync7, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
182925
183760
|
import { join as join16 } from "node:path";
|
|
183761
|
+
|
|
183762
|
+
// ../plugin/src/agents/historian.ts
|
|
183763
|
+
var HISTORIAN_AGENT = "historian";
|
|
183764
|
+
var HISTORIAN_EDITOR_AGENT = "historian-editor";
|
|
183765
|
+
|
|
183766
|
+
// ../plugin/src/hooks/magic-context/compartment-runner-historian.ts
|
|
182926
183767
|
init_data_path();
|
|
182927
183768
|
function historianResponseDumpDir(directory) {
|
|
182928
183769
|
return getProjectMagicContextHistorianDir(directory);
|
|
@@ -185176,7 +186017,7 @@ function formatThresholdPercent(value) {
|
|
|
185176
186017
|
// package.json
|
|
185177
186018
|
var package_default = {
|
|
185178
186019
|
name: "@wolfx/pi-magic-context",
|
|
185179
|
-
version: "0.
|
|
186020
|
+
version: "0.26.0",
|
|
185180
186021
|
type: "module",
|
|
185181
186022
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
185182
186023
|
main: "dist/index.js",
|
|
@@ -185202,7 +186043,7 @@ var package_default = {
|
|
|
185202
186043
|
"README.md"
|
|
185203
186044
|
],
|
|
185204
186045
|
scripts: {
|
|
185205
|
-
build: "bun build src/index.ts src/subagent-entry.ts --outdir dist --target node --format esm --external @earendil-works/pi-coding-agent --external @earendil-works/pi-tui --external @huggingface/transformers --external
|
|
186046
|
+
build: "bun build src/index.ts src/subagent-entry.ts --outdir dist --target node --format esm --external @earendil-works/pi-coding-agent --external @earendil-works/pi-tui --external @huggingface/transformers --external node:sqlite",
|
|
185206
186047
|
typecheck: "tsc --noEmit",
|
|
185207
186048
|
test: "bun test",
|
|
185208
186049
|
lint: "biome check src",
|
|
@@ -185225,13 +186066,12 @@ var package_default = {
|
|
|
185225
186066
|
"@earendil-works/pi-tui": "^0.74.0",
|
|
185226
186067
|
"@types/better-sqlite3": "^7.6.13",
|
|
185227
186068
|
"@types/bun": "^1.3.10",
|
|
185228
|
-
"better-sqlite3": "^12.9.0",
|
|
185229
186069
|
"@types/node": "^22.0.0",
|
|
185230
186070
|
typescript: "^5.8.0"
|
|
185231
186071
|
},
|
|
185232
186072
|
peerDependencies: {
|
|
185233
|
-
"@earendil-works/pi-coding-agent": "
|
|
185234
|
-
"@earendil-works/pi-tui": "
|
|
186073
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
186074
|
+
"@earendil-works/pi-tui": "*"
|
|
185235
186075
|
},
|
|
185236
186076
|
exports: {
|
|
185237
186077
|
".": {
|
|
@@ -185816,9 +186656,184 @@ Older parts of this session are summarized into <compartment> blocks inside <ses
|
|
|
185816
186656
|
|
|
185817
186657
|
ctx_expand(start=120, end=245) ← the compartment's own start/end attributes
|
|
185818
186658
|
|
|
185819
|
-
Returns the raw transcript as [N] U:/A: lines, capped at ~15K tokens; an oversized range returns the head and tells you where to continue. Also works with ordinals from ctx_search message results — expand a window around a hit (e.g. start=N-10, end=N+5). Ranges after the last compartment are your live tail — already visible in context, not expandable
|
|
186659
|
+
Returns the raw transcript as [N] U:/A: lines, capped at ~15K tokens; an oversized range returns the head and tells you where to continue. Also works with ordinals from ctx_search message results — expand a window around a hit (e.g. start=N-10, end=N+5). Ranges after the last compartment are your live tail — already visible in context, not expandable.
|
|
186660
|
+
|
|
186661
|
+
Two recovery modes for finer detail:
|
|
186662
|
+
- ctx_expand(start=120, end=245, verbose=true) — lists each message SEPARATELY with its ordinal [N] and a per-part preview (each tool call shown with its output size). Use this to find the exact message or tool call you want, then recover it in full by ordinal.
|
|
186663
|
+
- ctx_expand(message=138) — returns the FULL untruncated content of the message at that ordinal: every text part, and every tool call's complete input + output, read from stored history. This is the cheap way to get back a tool output you dropped with ctx_reduce — the original is still in storage even though the wire shows [dropped §N§]. If the message was deleted from history (session prune/revert), it says so.`;
|
|
185820
186664
|
var CTX_EXPAND_TOKEN_BUDGET = 15000;
|
|
185821
186665
|
|
|
186666
|
+
// ../plugin/src/tools/ctx-expand/render.ts
|
|
186667
|
+
function isRecord3(value) {
|
|
186668
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
186669
|
+
}
|
|
186670
|
+
function roleLabel(role) {
|
|
186671
|
+
if (role === "assistant")
|
|
186672
|
+
return "A (assistant)";
|
|
186673
|
+
if (role === "user")
|
|
186674
|
+
return "U (user)";
|
|
186675
|
+
return role;
|
|
186676
|
+
}
|
|
186677
|
+
function truncate2(value, max) {
|
|
186678
|
+
const t = value.trim();
|
|
186679
|
+
return t.length <= max ? t : `${t.slice(0, max)}…`;
|
|
186680
|
+
}
|
|
186681
|
+
function keyArg(input) {
|
|
186682
|
+
if (!input)
|
|
186683
|
+
return "";
|
|
186684
|
+
for (const k of ["filePath", "path", "pattern", "query", "symbol", "module", "action"]) {
|
|
186685
|
+
const v = input[k];
|
|
186686
|
+
if (typeof v === "string" && v.length > 0)
|
|
186687
|
+
return truncate2(v, 60);
|
|
186688
|
+
}
|
|
186689
|
+
if (typeof input.description === "string")
|
|
186690
|
+
return truncate2(input.description, 60);
|
|
186691
|
+
return "";
|
|
186692
|
+
}
|
|
186693
|
+
function asToolPart(part) {
|
|
186694
|
+
const type = typeof part.type === "string" ? part.type : "";
|
|
186695
|
+
if (type === "tool") {
|
|
186696
|
+
const state = isRecord3(part.state) ? part.state : null;
|
|
186697
|
+
const output = state && typeof state.output === "string" ? state.output : state && state.output != null ? JSON.stringify(state.output) : null;
|
|
186698
|
+
const metadata = state && isRecord3(state.metadata) ? state.metadata : null;
|
|
186699
|
+
const title = state && typeof state.title === "string" && state.title || metadata && typeof metadata.title === "string" && metadata.title || null;
|
|
186700
|
+
return {
|
|
186701
|
+
name: typeof part.tool === "string" ? part.tool : "tool",
|
|
186702
|
+
callId: typeof part.callID === "string" ? part.callID : "",
|
|
186703
|
+
title,
|
|
186704
|
+
input: state && isRecord3(state.input) ? state.input : null,
|
|
186705
|
+
output
|
|
186706
|
+
};
|
|
186707
|
+
}
|
|
186708
|
+
if (type === "tool_use") {
|
|
186709
|
+
return {
|
|
186710
|
+
name: typeof part.name === "string" ? part.name : "tool",
|
|
186711
|
+
callId: typeof part.id === "string" ? part.id : "",
|
|
186712
|
+
title: null,
|
|
186713
|
+
input: isRecord3(part.input) ? part.input : null,
|
|
186714
|
+
output: null
|
|
186715
|
+
};
|
|
186716
|
+
}
|
|
186717
|
+
if (type === "tool_result") {
|
|
186718
|
+
const content = part.content;
|
|
186719
|
+
const output = typeof content === "string" ? content : content != null ? JSON.stringify(content) : null;
|
|
186720
|
+
return {
|
|
186721
|
+
name: "tool_result",
|
|
186722
|
+
callId: typeof part.tool_use_id === "string" ? part.tool_use_id : "",
|
|
186723
|
+
title: null,
|
|
186724
|
+
input: null,
|
|
186725
|
+
output
|
|
186726
|
+
};
|
|
186727
|
+
}
|
|
186728
|
+
return null;
|
|
186729
|
+
}
|
|
186730
|
+
function textOf(part) {
|
|
186731
|
+
if (part.type === "text" && typeof part.text === "string")
|
|
186732
|
+
return part.text;
|
|
186733
|
+
return null;
|
|
186734
|
+
}
|
|
186735
|
+
function reasoningOf(part) {
|
|
186736
|
+
if ((part.type === "reasoning" || part.type === "thinking") && typeof part.text === "string") {
|
|
186737
|
+
return part.text;
|
|
186738
|
+
}
|
|
186739
|
+
return null;
|
|
186740
|
+
}
|
|
186741
|
+
function renderPartPreview(part) {
|
|
186742
|
+
if (!isRecord3(part))
|
|
186743
|
+
return null;
|
|
186744
|
+
const text = textOf(part);
|
|
186745
|
+
if (text !== null) {
|
|
186746
|
+
const t = truncate2(text, 200);
|
|
186747
|
+
return t.length > 0 ? ` • ${t}` : null;
|
|
186748
|
+
}
|
|
186749
|
+
const tool = asToolPart(part);
|
|
186750
|
+
if (tool) {
|
|
186751
|
+
const arg = keyArg(tool.input);
|
|
186752
|
+
const head = arg ? `${tool.name}(${arg})` : tool.name;
|
|
186753
|
+
return tool.output !== null ? ` • tool ${head} → output ~${estimateTokens(tool.output)} tok` : ` • tool ${head}`;
|
|
186754
|
+
}
|
|
186755
|
+
const reasoning = reasoningOf(part);
|
|
186756
|
+
if (reasoning !== null)
|
|
186757
|
+
return ` • [reasoning] ${truncate2(reasoning, 120)}`;
|
|
186758
|
+
const type = typeof part.type === "string" ? part.type : "part";
|
|
186759
|
+
if (type === "file")
|
|
186760
|
+
return " • [file]";
|
|
186761
|
+
if (type === "step-start" || type === "step-finish")
|
|
186762
|
+
return null;
|
|
186763
|
+
return ` • [${type}]`;
|
|
186764
|
+
}
|
|
186765
|
+
function renderPartFull(part) {
|
|
186766
|
+
if (!isRecord3(part))
|
|
186767
|
+
return null;
|
|
186768
|
+
const text = textOf(part);
|
|
186769
|
+
if (text !== null) {
|
|
186770
|
+
return text.trim().length > 0 ? ` [text]
|
|
186771
|
+
${text}` : null;
|
|
186772
|
+
}
|
|
186773
|
+
const tool = asToolPart(part);
|
|
186774
|
+
if (tool) {
|
|
186775
|
+
const lines = [];
|
|
186776
|
+
const idSuffix = tool.callId ? ` #${tool.callId}` : "";
|
|
186777
|
+
lines.push(` [tool: ${tool.name}${idSuffix}]`);
|
|
186778
|
+
if (tool.title && tool.title.trim().length > 0) {
|
|
186779
|
+
lines.push(` description: ${tool.title.trim()}`);
|
|
186780
|
+
}
|
|
186781
|
+
if (tool.input)
|
|
186782
|
+
lines.push(` input: ${JSON.stringify(tool.input)}`);
|
|
186783
|
+
if (tool.output !== null)
|
|
186784
|
+
lines.push(` output:
|
|
186785
|
+
${tool.output}`);
|
|
186786
|
+
return lines.join(`
|
|
186787
|
+
`);
|
|
186788
|
+
}
|
|
186789
|
+
const type = typeof part.type === "string" ? part.type : "part";
|
|
186790
|
+
if (type === "file") {
|
|
186791
|
+
const name2 = typeof part.filename === "string" && part.filename || typeof part.url === "string" && part.url || "";
|
|
186792
|
+
return ` [file]${name2 ? ` ${name2}` : ""}`;
|
|
186793
|
+
}
|
|
186794
|
+
return null;
|
|
186795
|
+
}
|
|
186796
|
+
function renderMessageByOrdinal(sessionId, ordinal) {
|
|
186797
|
+
const msg = readRawSessionMessages(sessionId).find((m) => m.ordinal === ordinal);
|
|
186798
|
+
if (!msg) {
|
|
186799
|
+
return `No message at ordinal ${ordinal} in this session's stored history — it was deleted ` + `(session prune/revert) or the ordinal is wrong, so it can't be recovered. ` + `Re-run the tool if you still need the data.`;
|
|
186800
|
+
}
|
|
186801
|
+
const rendered = msg.parts.map(renderPartFull).filter((l) => l !== null);
|
|
186802
|
+
const lines = [`[${msg.ordinal}] ${roleLabel(msg.role)} — full recovery:`, ""];
|
|
186803
|
+
if (rendered.length === 0) {
|
|
186804
|
+
lines.push(" (no recoverable content — message had only structural/reasoning parts)");
|
|
186805
|
+
} else {
|
|
186806
|
+
lines.push(...rendered);
|
|
186807
|
+
}
|
|
186808
|
+
return lines.join(`
|
|
186809
|
+
`);
|
|
186810
|
+
}
|
|
186811
|
+
function renderVerboseRange(sessionId, start, end, tokenBudget) {
|
|
186812
|
+
const messages = readRawSessionMessages(sessionId).filter((m) => m.ordinal >= start && m.ordinal <= end);
|
|
186813
|
+
const out = [];
|
|
186814
|
+
let usedTokens = 0;
|
|
186815
|
+
let lastOrdinal = start - 1;
|
|
186816
|
+
let truncated = false;
|
|
186817
|
+
for (const msg of messages) {
|
|
186818
|
+
const header = `[${msg.ordinal}] ${roleLabel(msg.role)}`;
|
|
186819
|
+
const partLines = msg.parts.map(renderPartPreview).filter((l) => l !== null);
|
|
186820
|
+
const block = partLines.length > 0 ? `${header}
|
|
186821
|
+
${partLines.join(`
|
|
186822
|
+
`)}` : header;
|
|
186823
|
+
const blockTokens = estimateTokens(block);
|
|
186824
|
+
if (usedTokens + blockTokens > tokenBudget && out.length > 0) {
|
|
186825
|
+
truncated = true;
|
|
186826
|
+
break;
|
|
186827
|
+
}
|
|
186828
|
+
out.push(block);
|
|
186829
|
+
usedTokens += blockTokens;
|
|
186830
|
+
lastOrdinal = msg.ordinal;
|
|
186831
|
+
}
|
|
186832
|
+
return { text: out.join(`
|
|
186833
|
+
|
|
186834
|
+
`), lastOrdinal, truncated };
|
|
186835
|
+
}
|
|
186836
|
+
|
|
185822
186837
|
// ../../node_modules/.bun/typebox@1.1.38/node_modules/typebox/build/system/memory/memory.mjs
|
|
185823
186838
|
var exports_memory = {};
|
|
185824
186839
|
__export(exports_memory, {
|
|
@@ -189884,12 +190899,18 @@ __export(exports_typebox, {
|
|
|
189884
190899
|
});
|
|
189885
190900
|
// src/tools/ctx-expand.ts
|
|
189886
190901
|
var ParamsSchema = exports_typebox.Object({
|
|
189887
|
-
start: exports_typebox.Number({
|
|
190902
|
+
start: exports_typebox.Optional(exports_typebox.Number({
|
|
189888
190903
|
description: "Start message ordinal (from compartment start attribute)"
|
|
189889
|
-
}),
|
|
189890
|
-
end: exports_typebox.Number({
|
|
190904
|
+
})),
|
|
190905
|
+
end: exports_typebox.Optional(exports_typebox.Number({
|
|
189891
190906
|
description: "End message ordinal (from compartment end attribute)"
|
|
189892
|
-
})
|
|
190907
|
+
})),
|
|
190908
|
+
verbose: exports_typebox.Optional(exports_typebox.Boolean({
|
|
190909
|
+
description: "With start/end: list each message separately with its ordinal [N] and per-part preview, so you can recover one in full by ordinal."
|
|
190910
|
+
})),
|
|
190911
|
+
message: exports_typebox.Optional(exports_typebox.Number({
|
|
190912
|
+
description: "Full untruncated recovery of ONE message by its ordinal (text + every tool call's full input/output). Recovers a tool output you dropped with ctx_reduce."
|
|
190913
|
+
}))
|
|
189893
190914
|
});
|
|
189894
190915
|
function ok(text) {
|
|
189895
190916
|
return { content: [{ type: "text", text }], details: undefined };
|
|
@@ -189908,22 +190929,41 @@ function createCtxExpandTool(deps) {
|
|
|
189908
190929
|
description: CTX_EXPAND_DESCRIPTION,
|
|
189909
190930
|
parameters: ParamsSchema,
|
|
189910
190931
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
189911
|
-
if (typeof params.start !== "number" || typeof params.end !== "number" || params.start < 1 || params.end < params.start) {
|
|
189912
|
-
return err("Error: start and end must be positive integers with start <= end.");
|
|
189913
|
-
}
|
|
189914
190932
|
const sessionId = ctx.sessionManager.getSessionId();
|
|
189915
190933
|
if (!sessionId) {
|
|
189916
190934
|
return err("Error: no active Pi session.");
|
|
189917
190935
|
}
|
|
189918
|
-
const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
|
|
189919
|
-
if (lastCompartmentEnd >= 0 && params.start > lastCompartmentEnd) {
|
|
189920
|
-
return ok(`Range ${params.start}-${params.end} is entirely within the live tail (after the last compacted message ${lastCompartmentEnd}); those messages are already visible in context.`);
|
|
189921
|
-
}
|
|
189922
|
-
const effectiveEnd = lastCompartmentEnd >= 0 ? Math.min(params.end, lastCompartmentEnd) : params.end;
|
|
189923
190936
|
const unregister = setRawMessageProvider(sessionId, {
|
|
189924
190937
|
readMessages: () => readPiSessionMessages(ctx)
|
|
189925
190938
|
});
|
|
189926
190939
|
try {
|
|
190940
|
+
if (typeof params.message === "number" && params.message >= 1) {
|
|
190941
|
+
return ok(renderMessageByOrdinal(sessionId, params.message));
|
|
190942
|
+
}
|
|
190943
|
+
if (typeof params.start !== "number" || typeof params.end !== "number" || params.start < 1 || params.end < params.start) {
|
|
190944
|
+
return err("Error: provide either message=<ordinal>, or start and end (positive integers, start <= end).");
|
|
190945
|
+
}
|
|
190946
|
+
const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
|
|
190947
|
+
if (lastCompartmentEnd >= 0 && params.start > lastCompartmentEnd) {
|
|
190948
|
+
return ok(`Range ${params.start}-${params.end} is entirely within the live tail (after the last compacted message ${lastCompartmentEnd}); those messages are already visible in context.`);
|
|
190949
|
+
}
|
|
190950
|
+
const effectiveEnd = lastCompartmentEnd >= 0 ? Math.min(params.end, lastCompartmentEnd) : params.end;
|
|
190951
|
+
if (params.verbose === true) {
|
|
190952
|
+
const v = renderVerboseRange(sessionId, params.start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET);
|
|
190953
|
+
if (!v.text) {
|
|
190954
|
+
return ok(`No messages found in range ${params.start}-${effectiveEnd}. The range may be outside this session's history.`);
|
|
190955
|
+
}
|
|
190956
|
+
const out = [
|
|
190957
|
+
`Messages ${params.start}-${v.lastOrdinal} (verbose). Recover any one in full with ctx_expand(message=<ordinal>):`,
|
|
190958
|
+
"",
|
|
190959
|
+
v.text
|
|
190960
|
+
];
|
|
190961
|
+
if (v.truncated) {
|
|
190962
|
+
out.push("", `Truncated at message ${v.lastOrdinal} (budget: ~${CTX_EXPAND_TOKEN_BUDGET} tokens). Call again with start=${v.lastOrdinal + 1} end=${effectiveEnd} verbose=true for more.`);
|
|
190963
|
+
}
|
|
190964
|
+
return ok(out.join(`
|
|
190965
|
+
`));
|
|
190966
|
+
}
|
|
189927
190967
|
const chunk = readSessionChunk(sessionId, CTX_EXPAND_TOKEN_BUDGET, params.start, effectiveEnd + 1);
|
|
189928
190968
|
if (!chunk.text || chunk.messageCount === 0) {
|
|
189929
190969
|
return ok(`No messages found in range ${params.start}-${params.end}. The range may be outside this session's history.`);
|
|
@@ -190642,15 +191682,16 @@ function parseInteger(str) {
|
|
|
190642
191682
|
}
|
|
190643
191683
|
|
|
190644
191684
|
// ../plugin/src/tools/ctx-reduce/constants.ts
|
|
190645
|
-
var CTX_REDUCE_DESCRIPTION = `
|
|
190646
|
-
|
|
191685
|
+
var CTX_REDUCE_DESCRIPTION = `Mark spent tagged content as discardable to reclaim context space. This is NOT an immediate delete. Use §N§ identifiers visible in the conversation. The \`drop\` param accepts ranges: "3-5", "1,2,9", "1-5,8".
|
|
191686
|
+
|
|
191687
|
+
How it works:
|
|
191688
|
+
- Marking QUEUES content for release. It stays fully visible to you until context space is actually needed — which may be as soon as the next turn if you are already under pressure, or many turns later if not. So mark spent outputs as soon as you finish with them; don't hoard the call for the end of the turn.
|
|
191689
|
+
- The newest tags are protected: marking one just queues it until it ages out of the recent window, so marking recent output is harmless.
|
|
191690
|
+
- When content is finally released it becomes a short placeholder, and re-running the tool is the only way to get it back. So mark only what you are genuinely DONE with — the test is "have I extracted what I need from this?", not "is it safe / do I have time before it drops?".
|
|
190647
191691
|
|
|
190648
|
-
|
|
190649
|
-
|
|
190650
|
-
-
|
|
190651
|
-
- Protected tags are accepted but deferred until they leave the last protected range.
|
|
190652
|
-
- Keep recent context — only reduce OLD content that is no longer relevant to current work.
|
|
190653
|
-
- Dropped content is gone forever.`;
|
|
191692
|
+
Mark discardable once processed: large outputs you've summarized, repeated or redundant dumps, data written to disk, status/log output that only confirmed an expected state.
|
|
191693
|
+
Keep: user messages, unresolved errors, raw evidence you haven't extracted yet, and outputs whose exact wording may matter later.
|
|
191694
|
+
Never blanket-mark large ranges (e.g. "1-50") — review what each tag holds first.`;
|
|
190654
191695
|
|
|
190655
191696
|
// src/tools/ctx-reduce.ts
|
|
190656
191697
|
var ParamsSchema4 = exports_typebox.Object({
|
|
@@ -190877,7 +191918,7 @@ function createCtxSearchTool(deps) {
|
|
|
190877
191918
|
memoryEnabled,
|
|
190878
191919
|
embeddingEnabled,
|
|
190879
191920
|
embedQuery: async (text, signal) => {
|
|
190880
|
-
const result = await embedTextForProject(projectIdentity, text, signal);
|
|
191921
|
+
const result = await embedTextForProject(projectIdentity, text, signal, "query");
|
|
190881
191922
|
return result?.vector ?? null;
|
|
190882
191923
|
},
|
|
190883
191924
|
isEmbeddingRuntimeEnabled: () => embeddingEnabled === true,
|
|
@@ -191105,7 +192146,7 @@ function resolveSidekickFromConfig(config2) {
|
|
|
191105
192146
|
systemPrompt: sidekick.system_prompt,
|
|
191106
192147
|
timeoutMs: sidekick.timeout_ms,
|
|
191107
192148
|
thinking_level: sidekick.thinking_level,
|
|
191108
|
-
fallbackModels: resolveFallbackChain(
|
|
192149
|
+
fallbackModels: resolveFallbackChain(sidekick.fallback_models)
|
|
191109
192150
|
};
|
|
191110
192151
|
}
|
|
191111
192152
|
function resolveHistorianFromConfig(config2) {
|
|
@@ -191117,7 +192158,7 @@ function resolveHistorianFromConfig(config2) {
|
|
|
191117
192158
|
return;
|
|
191118
192159
|
const historianContextLimit = resolveHistorianContextLimit(model);
|
|
191119
192160
|
const historianChunkTokens = deriveHistorianChunkTokens(historianContextLimit);
|
|
191120
|
-
const fallbackModels = resolveFallbackChain(
|
|
192161
|
+
const fallbackModels = resolveFallbackChain(historian?.fallback_models);
|
|
191121
192162
|
return {
|
|
191122
192163
|
runner: new PiSubagentRunner,
|
|
191123
192164
|
model,
|
|
@@ -191251,7 +192292,21 @@ async function src_default2(pi) {
|
|
|
191251
192292
|
},
|
|
191252
192293
|
historian: hist,
|
|
191253
192294
|
autoSearch: auto,
|
|
191254
|
-
resolveForProject: resolveContextOptionsForProject
|
|
192295
|
+
resolveForProject: resolveContextOptionsForProject,
|
|
192296
|
+
maybeAutoEmbedSession: (sessionId, dir, identity) => {
|
|
192297
|
+
maybeAutoEmbedPiSession({
|
|
192298
|
+
db: database,
|
|
192299
|
+
projectDir: dir,
|
|
192300
|
+
projectIdentity: identity,
|
|
192301
|
+
memoryEnabled: cfg.memory.enabled
|
|
192302
|
+
}, sessionId, dir, identity, (text) => {
|
|
192303
|
+
pi.sendMessage({
|
|
192304
|
+
customType: "ctx-status",
|
|
192305
|
+
content: text,
|
|
192306
|
+
display: true
|
|
192307
|
+
}, { triggerTurn: false });
|
|
192308
|
+
});
|
|
192309
|
+
}
|
|
191255
192310
|
});
|
|
191256
192311
|
function resolveContextOptionsForProject(dir) {
|
|
191257
192312
|
const cached2 = contextOptionsByDir.get(dir);
|
|
@@ -191333,14 +192388,14 @@ async function src_default2(pi) {
|
|
|
191333
192388
|
onProjectSeen: (identity) => seenDreamerProjectIdentities.add(identity)
|
|
191334
192389
|
});
|
|
191335
192390
|
info("registered /ctx-dream");
|
|
191336
|
-
|
|
192391
|
+
registerCtxEmbedCommand(pi, {
|
|
191337
192392
|
db,
|
|
191338
192393
|
projectDir,
|
|
191339
192394
|
projectIdentity,
|
|
191340
192395
|
memoryEnabled: config2.memory.enabled,
|
|
191341
192396
|
resolveProject: resolveCurrentProject
|
|
191342
192397
|
});
|
|
191343
|
-
info("registered /ctx-embed
|
|
192398
|
+
info("registered /ctx-embed");
|
|
191344
192399
|
const dreamerConfig = resolveDreamerFromConfig(config2);
|
|
191345
192400
|
if (dreamerConfig) {
|
|
191346
192401
|
registerPiDreamerProject({
|