@cortexkit/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 +1567 -511
- package/dist/subagent-entry.js +821 -212
- package/package.json +1 -1
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
|
};
|
|
@@ -166490,6 +166692,16 @@ function buildCanonicalChunkTextFromFts(db, sessionId, startOrdinal, endOrdinal)
|
|
|
166490
166692
|
return lines.join(`
|
|
166491
166693
|
`);
|
|
166492
166694
|
}
|
|
166695
|
+
function buildCompartmentSummaryFallbackText(db, compartmentId) {
|
|
166696
|
+
const row = db.prepare("SELECT title, p1, content FROM compartments WHERE id = ?").get(compartmentId);
|
|
166697
|
+
if (!row)
|
|
166698
|
+
return "";
|
|
166699
|
+
const title = typeof row.title === "string" ? row.title.trim() : "";
|
|
166700
|
+
const p1 = typeof row.p1 === "string" ? row.p1.trim() : "";
|
|
166701
|
+
const body = p1.length > 0 ? p1 : typeof row.content === "string" ? row.content.trim() : "";
|
|
166702
|
+
return [title, body].filter((s) => s.length > 0).join(`
|
|
166703
|
+
`);
|
|
166704
|
+
}
|
|
166493
166705
|
function canonicalizeInMemoryChunkTextForEmbedding(chunkText, startOrdinal, endOrdinal) {
|
|
166494
166706
|
const lines = [];
|
|
166495
166707
|
for (const rawLine of chunkText.split(/\r?\n/)) {
|
|
@@ -166733,6 +166945,28 @@ function countUnembeddedSessionCompartments(db, projectPath, sessionId, modelId)
|
|
|
166733
166945
|
)`).get(projectPath, sessionId, projectPath, modelId);
|
|
166734
166946
|
return typeof row?.n === "number" ? row.n : 0;
|
|
166735
166947
|
}
|
|
166948
|
+
function countSessionCompartmentEmbedCoverage(db, projectPath, sessionId, modelId) {
|
|
166949
|
+
const row = db.prepare(`SELECT
|
|
166950
|
+
COUNT(*) AS total,
|
|
166951
|
+
SUM(CASE WHEN EXISTS (
|
|
166952
|
+
SELECT 1 FROM compartment_chunk_embeddings e
|
|
166953
|
+
WHERE e.compartment_id = c.id
|
|
166954
|
+
AND e.project_path = ?
|
|
166955
|
+
AND e.model_id = ?
|
|
166956
|
+
) THEN 1 ELSE 0 END) AS embedded
|
|
166957
|
+
FROM compartments c
|
|
166958
|
+
JOIN session_projects sp
|
|
166959
|
+
ON sp.session_id = c.session_id
|
|
166960
|
+
AND sp.harness = c.harness
|
|
166961
|
+
AND sp.project_path = ?
|
|
166962
|
+
WHERE c.session_id = ?
|
|
166963
|
+
AND c.start_message IS NOT NULL
|
|
166964
|
+
AND c.end_message IS NOT NULL`).get(projectPath, modelId, projectPath, sessionId);
|
|
166965
|
+
return {
|
|
166966
|
+
total: typeof row?.total === "number" ? row.total : 0,
|
|
166967
|
+
embedded: typeof row?.embedded === "number" ? row.embedded : 0
|
|
166968
|
+
};
|
|
166969
|
+
}
|
|
166736
166970
|
|
|
166737
166971
|
// ../plugin/src/features/magic-context/memory/cosine-similarity.ts
|
|
166738
166972
|
function cosineSimilarity(a, b) {
|
|
@@ -166875,6 +167109,19 @@ async function withQuietConsole(fn) {
|
|
|
166875
167109
|
console.error = origError;
|
|
166876
167110
|
}
|
|
166877
167111
|
}
|
|
167112
|
+
var nativeRuntimeMissing = false;
|
|
167113
|
+
function isNativeRuntimeMissingError(error51) {
|
|
167114
|
+
const message = error51 instanceof Error ? error51.message : String(error51 ?? "");
|
|
167115
|
+
const lower = message.toLowerCase();
|
|
167116
|
+
const code = error51?.code;
|
|
167117
|
+
const name2 = error51?.name;
|
|
167118
|
+
if (code === "ERR_DLOPEN_FAILED" && lower.includes("onnxruntime")) {
|
|
167119
|
+
return true;
|
|
167120
|
+
}
|
|
167121
|
+
if (!lower.includes("onnxruntime-node"))
|
|
167122
|
+
return false;
|
|
167123
|
+
return code === "ERR_MODULE_NOT_FOUND" || name2 === "ResolveMessage" || lower.includes("cannot find package") || lower.includes("cannot find module") || lower.includes("err_module_not_found");
|
|
167124
|
+
}
|
|
166878
167125
|
function isTransientLoadError(error51) {
|
|
166879
167126
|
const message = error51 instanceof Error ? error51.message : String(error51 ?? "");
|
|
166880
167127
|
if (!message)
|
|
@@ -166939,6 +167186,9 @@ class LocalEmbeddingProvider {
|
|
|
166939
167186
|
if (this.pipeline) {
|
|
166940
167187
|
return true;
|
|
166941
167188
|
}
|
|
167189
|
+
if (nativeRuntimeMissing) {
|
|
167190
|
+
return false;
|
|
167191
|
+
}
|
|
166942
167192
|
if (this.initPromise) {
|
|
166943
167193
|
await this.initPromise;
|
|
166944
167194
|
return this.pipeline !== null;
|
|
@@ -167005,7 +167255,12 @@ class LocalEmbeddingProvider {
|
|
|
167005
167255
|
await releaseLock();
|
|
167006
167256
|
}
|
|
167007
167257
|
} catch (error51) {
|
|
167008
|
-
|
|
167258
|
+
if (isNativeRuntimeMissingError(error51)) {
|
|
167259
|
+
nativeRuntimeMissing = true;
|
|
167260
|
+
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 @cortexkit/magic-context@latest doctor --force`), or configure an `openai-compatible`/`ollama` embedding endpoint instead. Existing memories are unaffected.");
|
|
167261
|
+
} else {
|
|
167262
|
+
log("[magic-context] embedding model failed to load:", error51);
|
|
167263
|
+
}
|
|
167009
167264
|
this.pipeline = null;
|
|
167010
167265
|
} finally {
|
|
167011
167266
|
this.initPromise = null;
|
|
@@ -167031,7 +167286,7 @@ class LocalEmbeddingProvider {
|
|
|
167031
167286
|
waiter();
|
|
167032
167287
|
}
|
|
167033
167288
|
}
|
|
167034
|
-
async embed(text, signal) {
|
|
167289
|
+
async embed(text, signal, _purpose) {
|
|
167035
167290
|
if (signal?.aborted)
|
|
167036
167291
|
return null;
|
|
167037
167292
|
if (this.disposing)
|
|
@@ -167057,7 +167312,7 @@ class LocalEmbeddingProvider {
|
|
|
167057
167312
|
this.finishInFlight();
|
|
167058
167313
|
}
|
|
167059
167314
|
}
|
|
167060
|
-
async embedBatch(texts, signal) {
|
|
167315
|
+
async embedBatch(texts, signal, _purpose) {
|
|
167061
167316
|
if (texts.length === 0) {
|
|
167062
167317
|
return [];
|
|
167063
167318
|
}
|
|
@@ -167196,6 +167451,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
167196
167451
|
model;
|
|
167197
167452
|
apiKey;
|
|
167198
167453
|
inputType;
|
|
167454
|
+
queryInputType;
|
|
167199
167455
|
truncate;
|
|
167200
167456
|
initialized = false;
|
|
167201
167457
|
failureTimes = [];
|
|
@@ -167208,6 +167464,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
167208
167464
|
this.model = options.model?.trim() ?? "";
|
|
167209
167465
|
this.apiKey = options.apiKey?.trim() ?? "";
|
|
167210
167466
|
this.inputType = options.inputType?.trim() ?? "";
|
|
167467
|
+
this.queryInputType = options.queryInputType?.trim() ?? "";
|
|
167211
167468
|
this.truncate = options.truncate?.trim() ?? "";
|
|
167212
167469
|
this.maxInputTokens = typeof options.maxInputTokens === "number" && Number.isFinite(options.maxInputTokens) ? Math.max(1, Math.floor(options.maxInputTokens)) : 512;
|
|
167213
167470
|
this.modelId = getEmbeddingProviderIdentity({
|
|
@@ -167235,11 +167492,17 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
167235
167492
|
this.initialized = true;
|
|
167236
167493
|
return true;
|
|
167237
167494
|
}
|
|
167238
|
-
|
|
167239
|
-
|
|
167495
|
+
resolveInputTypeForPurpose(purpose = "passage") {
|
|
167496
|
+
if (purpose === "query") {
|
|
167497
|
+
return this.queryInputType || this.inputType;
|
|
167498
|
+
}
|
|
167499
|
+
return this.inputType;
|
|
167500
|
+
}
|
|
167501
|
+
async embed(text, signal, purpose) {
|
|
167502
|
+
const [embedding] = await this.embedBatch([text], signal, purpose);
|
|
167240
167503
|
return embedding ?? null;
|
|
167241
167504
|
}
|
|
167242
|
-
async embedBatch(texts, signal) {
|
|
167505
|
+
async embedBatch(texts, signal, purpose) {
|
|
167243
167506
|
if (texts.length === 0) {
|
|
167244
167507
|
return [];
|
|
167245
167508
|
}
|
|
@@ -167265,6 +167528,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
167265
167528
|
if (signal) {
|
|
167266
167529
|
signal.addEventListener("abort", onOuterAbort, { once: true });
|
|
167267
167530
|
}
|
|
167531
|
+
const inputTypeForRequest = this.resolveInputTypeForPurpose(purpose);
|
|
167268
167532
|
const response = await fetch(`${this.endpoint}/embeddings`, {
|
|
167269
167533
|
method: "POST",
|
|
167270
167534
|
headers: {
|
|
@@ -167274,7 +167538,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
167274
167538
|
body: JSON.stringify({
|
|
167275
167539
|
model: this.model,
|
|
167276
167540
|
input: texts,
|
|
167277
|
-
...
|
|
167541
|
+
...inputTypeForRequest ? { input_type: inputTypeForRequest } : {},
|
|
167278
167542
|
...this.truncate ? { truncate: this.truncate } : {}
|
|
167279
167543
|
}),
|
|
167280
167544
|
redirect: "error",
|
|
@@ -167519,6 +167783,118 @@ function getDistinctCommitEmbeddingModelIds(db, projectPath) {
|
|
|
167519
167783
|
return new Set(rows.map((row) => typeof row.modelId === "string" ? row.modelId : null));
|
|
167520
167784
|
}
|
|
167521
167785
|
|
|
167786
|
+
// ../plugin/src/features/magic-context/git-commits/storage-git-commits.ts
|
|
167787
|
+
init_logger();
|
|
167788
|
+
var insertStatements = new WeakMap;
|
|
167789
|
+
var existingShasStatements = new WeakMap;
|
|
167790
|
+
var projectCountStatements = new WeakMap;
|
|
167791
|
+
var evictStatements = new WeakMap;
|
|
167792
|
+
var evictOverflowStatements = new WeakMap;
|
|
167793
|
+
var latestCommitTimeStatements = new WeakMap;
|
|
167794
|
+
function getInsertStatement(db) {
|
|
167795
|
+
let stmt = insertStatements.get(db);
|
|
167796
|
+
if (!stmt) {
|
|
167797
|
+
stmt = db.prepare(`INSERT INTO git_commits (sha, project_path, short_sha, message, author, committed_at, indexed_at)
|
|
167798
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
167799
|
+
ON CONFLICT(sha) DO UPDATE SET
|
|
167800
|
+
project_path = excluded.project_path,
|
|
167801
|
+
short_sha = excluded.short_sha,
|
|
167802
|
+
message = excluded.message,
|
|
167803
|
+
author = excluded.author,
|
|
167804
|
+
committed_at = excluded.committed_at,
|
|
167805
|
+
indexed_at = excluded.indexed_at
|
|
167806
|
+
WHERE git_commits.message != excluded.message`);
|
|
167807
|
+
insertStatements.set(db, stmt);
|
|
167808
|
+
}
|
|
167809
|
+
return stmt;
|
|
167810
|
+
}
|
|
167811
|
+
function getExistingShasStatement(db) {
|
|
167812
|
+
let stmt = existingShasStatements.get(db);
|
|
167813
|
+
if (!stmt) {
|
|
167814
|
+
stmt = db.prepare("SELECT sha FROM git_commits WHERE project_path = ?");
|
|
167815
|
+
existingShasStatements.set(db, stmt);
|
|
167816
|
+
}
|
|
167817
|
+
return stmt;
|
|
167818
|
+
}
|
|
167819
|
+
function getProjectCountStatement(db) {
|
|
167820
|
+
let stmt = projectCountStatements.get(db);
|
|
167821
|
+
if (!stmt) {
|
|
167822
|
+
stmt = db.prepare("SELECT COUNT(*) AS count FROM git_commits WHERE project_path = ?");
|
|
167823
|
+
projectCountStatements.set(db, stmt);
|
|
167824
|
+
}
|
|
167825
|
+
return stmt;
|
|
167826
|
+
}
|
|
167827
|
+
function getLatestCommitTimeStatement(db) {
|
|
167828
|
+
let stmt = latestCommitTimeStatements.get(db);
|
|
167829
|
+
if (!stmt) {
|
|
167830
|
+
stmt = db.prepare("SELECT MAX(committed_at) AS latest FROM git_commits WHERE project_path = ?");
|
|
167831
|
+
latestCommitTimeStatements.set(db, stmt);
|
|
167832
|
+
}
|
|
167833
|
+
return stmt;
|
|
167834
|
+
}
|
|
167835
|
+
function getEvictOverflowStatement(db) {
|
|
167836
|
+
let stmt = evictOverflowStatements.get(db);
|
|
167837
|
+
if (!stmt) {
|
|
167838
|
+
stmt = db.prepare(`DELETE FROM git_commits
|
|
167839
|
+
WHERE rowid IN (
|
|
167840
|
+
SELECT rowid FROM git_commits
|
|
167841
|
+
WHERE project_path = ?
|
|
167842
|
+
ORDER BY committed_at DESC, sha DESC
|
|
167843
|
+
LIMIT -1 OFFSET ?
|
|
167844
|
+
)`);
|
|
167845
|
+
evictOverflowStatements.set(db, stmt);
|
|
167846
|
+
}
|
|
167847
|
+
return stmt;
|
|
167848
|
+
}
|
|
167849
|
+
function upsertCommits(db, projectPath, commits) {
|
|
167850
|
+
if (commits.length === 0)
|
|
167851
|
+
return { inserted: 0, updated: 0 };
|
|
167852
|
+
const existing = new Set;
|
|
167853
|
+
for (const row of getExistingShasStatement(db).all(projectPath)) {
|
|
167854
|
+
existing.add(row.sha);
|
|
167855
|
+
}
|
|
167856
|
+
let inserted = 0;
|
|
167857
|
+
let updated = 0;
|
|
167858
|
+
const now = Date.now();
|
|
167859
|
+
const insertStmt = getInsertStatement(db);
|
|
167860
|
+
db.transaction(() => {
|
|
167861
|
+
for (const commit of commits) {
|
|
167862
|
+
const result = insertStmt.run(commit.sha, projectPath, commit.shortSha, commit.message, commit.author, commit.committedAtMs, now);
|
|
167863
|
+
if (result.changes > 0) {
|
|
167864
|
+
if (existing.has(commit.sha)) {
|
|
167865
|
+
updated++;
|
|
167866
|
+
} else {
|
|
167867
|
+
inserted++;
|
|
167868
|
+
existing.add(commit.sha);
|
|
167869
|
+
}
|
|
167870
|
+
}
|
|
167871
|
+
}
|
|
167872
|
+
})();
|
|
167873
|
+
return { inserted, updated };
|
|
167874
|
+
}
|
|
167875
|
+
function getCommitCount(db, projectPath) {
|
|
167876
|
+
const row = getProjectCountStatement(db).get(projectPath);
|
|
167877
|
+
return row?.count ?? 0;
|
|
167878
|
+
}
|
|
167879
|
+
function getLatestIndexedCommitTimeMs(db, projectPath) {
|
|
167880
|
+
const row = getLatestCommitTimeStatement(db).get(projectPath);
|
|
167881
|
+
return row?.latest ?? null;
|
|
167882
|
+
}
|
|
167883
|
+
function enforceProjectCap(db, projectPath, maxCommits) {
|
|
167884
|
+
if (maxCommits <= 0)
|
|
167885
|
+
return 0;
|
|
167886
|
+
const count = getCommitCount(db, projectPath);
|
|
167887
|
+
if (count <= maxCommits)
|
|
167888
|
+
return 0;
|
|
167889
|
+
getEvictOverflowStatement(db).run(projectPath, maxCommits);
|
|
167890
|
+
const after = getCommitCount(db, projectPath);
|
|
167891
|
+
const evicted = Math.max(0, count - after);
|
|
167892
|
+
if (evicted > 0) {
|
|
167893
|
+
log(`[git-commits] evicted ${evicted} oldest commits for project ${projectPath} (cap=${maxCommits}, was=${count})`);
|
|
167894
|
+
}
|
|
167895
|
+
return evicted;
|
|
167896
|
+
}
|
|
167897
|
+
|
|
167522
167898
|
// ../plugin/src/features/magic-context/git-commits/sweep-coordinator.ts
|
|
167523
167899
|
var GIT_SWEEP_COOLDOWN_MS = 10 * 60 * 1000;
|
|
167524
167900
|
var GIT_SWEEP_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
@@ -167713,8 +168089,12 @@ function repairMisScopedCompartmentChunkEmbeddingsForProject(db, projectPath) {
|
|
|
167713
168089
|
var OFF_PROVIDER_IDENTITY = "embedding-provider:off";
|
|
167714
168090
|
var SWEEP_MAX_WALL_CLOCK_MS = 10 * 60 * 1000;
|
|
167715
168091
|
var CHUNK_DRAIN_BATCH_SIZE = 8;
|
|
167716
|
-
var MAX_WINDOWS_PER_EMBED_CALL =
|
|
168092
|
+
var MAX_WINDOWS_PER_EMBED_CALL = 2;
|
|
167717
168093
|
var SESSION_EMBED_LEASE_RENEWAL_MS = 60 * 1000;
|
|
168094
|
+
var EMBED_SLICE_RETRY_ATTEMPTS = 3;
|
|
168095
|
+
var EMBED_SLICE_RETRY_BASE_MS = 250;
|
|
168096
|
+
var EMBED_SLOW_FAILURE_NO_RETRY_MS = 1e4;
|
|
168097
|
+
var MAX_CONSECUTIVE_FAILED_BATCHES = 3;
|
|
167718
168098
|
var projectRegistrations = new Map;
|
|
167719
168099
|
var loadUnembeddedMemoriesStatements = new WeakMap;
|
|
167720
168100
|
var globalRegistrationGeneration = 0;
|
|
@@ -167732,6 +168112,7 @@ function resolveEmbeddingConfig(config2) {
|
|
|
167732
168112
|
if (config2.provider === "openai-compatible") {
|
|
167733
168113
|
const apiKey = config2.api_key?.trim();
|
|
167734
168114
|
const inputType = config2.input_type?.trim();
|
|
168115
|
+
const queryInputType = config2.query_input_type?.trim();
|
|
167735
168116
|
const truncate = config2.truncate?.trim();
|
|
167736
168117
|
return {
|
|
167737
168118
|
provider: "openai-compatible",
|
|
@@ -167739,6 +168120,7 @@ function resolveEmbeddingConfig(config2) {
|
|
|
167739
168120
|
endpoint: config2.endpoint.trim(),
|
|
167740
168121
|
...apiKey ? { api_key: apiKey } : {},
|
|
167741
168122
|
...inputType ? { input_type: inputType } : {},
|
|
168123
|
+
...queryInputType ? { query_input_type: queryInputType } : {},
|
|
167742
168124
|
...truncate ? { truncate } : {},
|
|
167743
168125
|
...config2.max_input_tokens ? {
|
|
167744
168126
|
max_input_tokens: normalizeCompartmentChunkMaxInputTokens(config2.max_input_tokens)
|
|
@@ -167760,6 +168142,7 @@ function createProvider(config2) {
|
|
|
167760
168142
|
model: config2.model,
|
|
167761
168143
|
apiKey: config2.api_key,
|
|
167762
168144
|
inputType: config2.input_type,
|
|
168145
|
+
queryInputType: config2.query_input_type,
|
|
167763
168146
|
truncate: config2.truncate,
|
|
167764
168147
|
maxInputTokens: config2.max_input_tokens
|
|
167765
168148
|
});
|
|
@@ -167814,7 +168197,9 @@ function snapshotFor(registration) {
|
|
|
167814
168197
|
enabled,
|
|
167815
168198
|
gitCommitEnabled,
|
|
167816
168199
|
modelId: registration.observationMode || !providerIsOn ? "off" : registration.modelId,
|
|
167817
|
-
chunkModelId: registration.observationMode || !providerIsOn ? "off" : registration.chunkModelId
|
|
168200
|
+
chunkModelId: registration.observationMode || !providerIsOn ? "off" : registration.chunkModelId,
|
|
168201
|
+
model: registration.observationMode || !providerIsOn ? "off" : ("model" in registration.config) && registration.config.model.trim() ? registration.config.model.trim() : registration.modelId,
|
|
168202
|
+
provider: registration.observationMode || !providerIsOn ? "off" : registration.config.provider ?? "local"
|
|
167818
168203
|
};
|
|
167819
168204
|
}
|
|
167820
168205
|
function disposeProvider(provider) {
|
|
@@ -167940,7 +168325,7 @@ function getOrCreateProjectProvider(registration) {
|
|
|
167940
168325
|
registration.provider = provider;
|
|
167941
168326
|
return provider;
|
|
167942
168327
|
}
|
|
167943
|
-
async function embedTextForProject(projectIdentity, text, signal) {
|
|
168328
|
+
async function embedTextForProject(projectIdentity, text, signal, purpose = "passage") {
|
|
167944
168329
|
const registration = projectRegistrations.get(projectIdentity);
|
|
167945
168330
|
if (!registration)
|
|
167946
168331
|
return null;
|
|
@@ -167949,7 +168334,7 @@ async function embedTextForProject(projectIdentity, text, signal) {
|
|
|
167949
168334
|
const provider = getOrCreateProjectProvider(registration);
|
|
167950
168335
|
if (!provider)
|
|
167951
168336
|
return null;
|
|
167952
|
-
const vector = await provider.embed(text, signal);
|
|
168337
|
+
const vector = await provider.embed(text, signal, purpose);
|
|
167953
168338
|
if (!vector)
|
|
167954
168339
|
return null;
|
|
167955
168340
|
const current = projectRegistrations.get(projectIdentity);
|
|
@@ -167958,7 +168343,7 @@ async function embedTextForProject(projectIdentity, text, signal) {
|
|
|
167958
168343
|
}
|
|
167959
168344
|
return { vector, modelId, generation };
|
|
167960
168345
|
}
|
|
167961
|
-
async function embedBatchForProject(projectIdentity, texts, signal) {
|
|
168346
|
+
async function embedBatchForProject(projectIdentity, texts, signal, purpose = "passage") {
|
|
167962
168347
|
if (texts.length === 0) {
|
|
167963
168348
|
const registration2 = projectRegistrations.get(projectIdentity);
|
|
167964
168349
|
if (!registration2 || registration2.observationMode)
|
|
@@ -167974,7 +168359,7 @@ async function embedBatchForProject(projectIdentity, texts, signal) {
|
|
|
167974
168359
|
const provider = getOrCreateProjectProvider(registration);
|
|
167975
168360
|
if (!provider)
|
|
167976
168361
|
return null;
|
|
167977
|
-
const vectors = await provider.embedBatch(texts, signal);
|
|
168362
|
+
const vectors = await provider.embedBatch(texts, signal, purpose);
|
|
167978
168363
|
const current = projectRegistrations.get(projectIdentity);
|
|
167979
168364
|
if (!current || current.generation !== generation || current.runtimeFingerprint !== runtimeFingerprint) {
|
|
167980
168365
|
return null;
|
|
@@ -168025,12 +168410,13 @@ async function embedUnembeddedMemoriesForProject(db, projectIdentity, batchSize
|
|
|
168025
168410
|
}
|
|
168026
168411
|
async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates, signal) {
|
|
168027
168412
|
const noWork = [];
|
|
168413
|
+
const failed = [];
|
|
168028
168414
|
if (candidates.length === 0)
|
|
168029
|
-
return { embedded: 0, noWork };
|
|
168415
|
+
return { embedded: 0, noWork, failed };
|
|
168030
168416
|
const maxInputTokens = getProjectEmbeddingMaxInputTokens(projectIdentity);
|
|
168031
168417
|
const prepared = [];
|
|
168032
168418
|
for (const candidate of candidates) {
|
|
168033
|
-
const canonicalText = buildCanonicalChunkTextFromFts(db, candidate.sessionId, candidate.startMessage, candidate.endMessage);
|
|
168419
|
+
const canonicalText = buildCanonicalChunkTextFromFts(db, candidate.sessionId, candidate.startMessage, candidate.endMessage) || buildCompartmentSummaryFallbackText(db, candidate.id);
|
|
168034
168420
|
if (canonicalText.length === 0) {
|
|
168035
168421
|
noWork.push(candidate.id);
|
|
168036
168422
|
continue;
|
|
@@ -168043,7 +168429,7 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
|
|
|
168043
168429
|
prepared.push({ candidate, windows });
|
|
168044
168430
|
}
|
|
168045
168431
|
if (prepared.length === 0)
|
|
168046
|
-
return { embedded: 0, noWork };
|
|
168432
|
+
return { embedded: 0, noWork, failed };
|
|
168047
168433
|
let embedded = 0;
|
|
168048
168434
|
let i = 0;
|
|
168049
168435
|
while (i < prepared.length) {
|
|
@@ -168060,35 +168446,60 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
|
|
|
168060
168446
|
const texts = [];
|
|
168061
168447
|
for (const item of slice)
|
|
168062
168448
|
texts.push(...item.windows.map((w) => w.text));
|
|
168063
|
-
|
|
168064
|
-
|
|
168065
|
-
if (!result)
|
|
168066
|
-
continue;
|
|
168449
|
+
const persistedIds = new Set;
|
|
168450
|
+
for (let attempt = 0;attempt < EMBED_SLICE_RETRY_ATTEMPTS; attempt++) {
|
|
168067
168451
|
if (signal?.aborted)
|
|
168068
168452
|
break;
|
|
168069
|
-
let
|
|
168070
|
-
|
|
168071
|
-
|
|
168072
|
-
|
|
168073
|
-
|
|
168074
|
-
|
|
168453
|
+
let result = null;
|
|
168454
|
+
const attemptStart = Date.now();
|
|
168455
|
+
try {
|
|
168456
|
+
result = await embedBatchForProject(projectIdentity, texts, signal);
|
|
168457
|
+
} catch (error51) {
|
|
168458
|
+
log("[magic-context] failed to proactively embed compartment chunks:", error51);
|
|
168459
|
+
}
|
|
168460
|
+
if (signal?.aborted)
|
|
168461
|
+
break;
|
|
168462
|
+
if (result) {
|
|
168463
|
+
let offset = 0;
|
|
168464
|
+
for (const item of slice) {
|
|
168465
|
+
const vectors = result.vectors.slice(offset, offset + item.windows.length);
|
|
168466
|
+
offset += item.windows.length;
|
|
168467
|
+
if (persistedIds.has(item.candidate.id))
|
|
168468
|
+
continue;
|
|
168469
|
+
if (vectors.length !== item.windows.length || vectors.some((v) => !v)) {
|
|
168470
|
+
continue;
|
|
168471
|
+
}
|
|
168472
|
+
const rows = item.windows.map((window, index) => ({
|
|
168473
|
+
compartmentId: item.candidate.id,
|
|
168474
|
+
sessionId: item.candidate.sessionId,
|
|
168475
|
+
projectPath: projectIdentity,
|
|
168476
|
+
window,
|
|
168477
|
+
modelId,
|
|
168478
|
+
vector: vectors[index]
|
|
168479
|
+
}));
|
|
168480
|
+
replaceCompartmentChunkEmbeddings(db, rows);
|
|
168481
|
+
persistedIds.add(item.candidate.id);
|
|
168075
168482
|
}
|
|
168076
|
-
const rows = item.windows.map((window, index) => ({
|
|
168077
|
-
compartmentId: item.candidate.id,
|
|
168078
|
-
sessionId: item.candidate.sessionId,
|
|
168079
|
-
projectPath: projectIdentity,
|
|
168080
|
-
window,
|
|
168081
|
-
modelId,
|
|
168082
|
-
vector: vectors[index]
|
|
168083
|
-
}));
|
|
168084
|
-
replaceCompartmentChunkEmbeddings(db, rows);
|
|
168085
|
-
embedded += 1;
|
|
168086
168483
|
}
|
|
168087
|
-
|
|
168088
|
-
|
|
168484
|
+
if (persistedIds.size === slice.length)
|
|
168485
|
+
break;
|
|
168486
|
+
if (persistedIds.size > 0)
|
|
168487
|
+
break;
|
|
168488
|
+
if (Date.now() - attemptStart >= EMBED_SLOW_FAILURE_NO_RETRY_MS)
|
|
168489
|
+
break;
|
|
168490
|
+
if (attempt < EMBED_SLICE_RETRY_ATTEMPTS - 1) {
|
|
168491
|
+
await new Promise((resolve4) => setTimeout(resolve4, EMBED_SLICE_RETRY_BASE_MS * 2 ** attempt));
|
|
168492
|
+
}
|
|
168493
|
+
}
|
|
168494
|
+
embedded += persistedIds.size;
|
|
168495
|
+
if (!signal?.aborted) {
|
|
168496
|
+
for (const item of slice) {
|
|
168497
|
+
if (!persistedIds.has(item.candidate.id))
|
|
168498
|
+
failed.push(item.candidate.id);
|
|
168499
|
+
}
|
|
168089
168500
|
}
|
|
168090
168501
|
}
|
|
168091
|
-
return { embedded, noWork };
|
|
168502
|
+
return { embedded, noWork, failed };
|
|
168092
168503
|
}
|
|
168093
168504
|
async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, options) {
|
|
168094
168505
|
const snapshot = getProjectEmbeddingSnapshot(projectIdentity);
|
|
@@ -168111,9 +168522,11 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
|
|
|
168111
168522
|
renewal.unref?.();
|
|
168112
168523
|
const batchSize = Math.max(1, options?.batchSize ?? CHUNK_DRAIN_BATCH_SIZE);
|
|
168113
168524
|
const skipIds = [];
|
|
168525
|
+
const failedIds = [];
|
|
168114
168526
|
let embedded = 0;
|
|
168115
168527
|
let aborted2 = false;
|
|
168116
|
-
let
|
|
168528
|
+
let providerDown = false;
|
|
168529
|
+
let consecutiveFailedBatches = 0;
|
|
168117
168530
|
try {
|
|
168118
168531
|
options?.onProgress?.({ embedded, total });
|
|
168119
168532
|
for (;; ) {
|
|
@@ -168121,15 +168534,26 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
|
|
|
168121
168534
|
aborted2 = true;
|
|
168122
168535
|
break;
|
|
168123
168536
|
}
|
|
168124
|
-
const candidates = loadUnembeddedSessionChunkCandidates(db, projectIdentity, sessionId, snapshot.chunkModelId, batchSize, skipIds);
|
|
168537
|
+
const candidates = loadUnembeddedSessionChunkCandidates(db, projectIdentity, sessionId, snapshot.chunkModelId, batchSize, [...skipIds, ...failedIds]);
|
|
168125
168538
|
if (candidates.length === 0)
|
|
168126
168539
|
break;
|
|
168127
|
-
const {
|
|
168540
|
+
const {
|
|
168541
|
+
embedded: n,
|
|
168542
|
+
noWork,
|
|
168543
|
+
failed
|
|
168544
|
+
} = await embedCandidateChunkBatch(db, projectIdentity, snapshot.chunkModelId, candidates, options?.signal);
|
|
168128
168545
|
for (const id of noWork)
|
|
168129
168546
|
skipIds.push(id);
|
|
168547
|
+
for (const id of failed)
|
|
168548
|
+
failedIds.push(id);
|
|
168130
168549
|
if (n === 0 && noWork.length === 0) {
|
|
168131
|
-
|
|
168132
|
-
|
|
168550
|
+
consecutiveFailedBatches += 1;
|
|
168551
|
+
if (consecutiveFailedBatches >= MAX_CONSECUTIVE_FAILED_BATCHES) {
|
|
168552
|
+
providerDown = true;
|
|
168553
|
+
break;
|
|
168554
|
+
}
|
|
168555
|
+
} else {
|
|
168556
|
+
consecutiveFailedBatches = 0;
|
|
168133
168557
|
}
|
|
168134
168558
|
embedded += n;
|
|
168135
168559
|
options?.onProgress?.({ embedded: Math.min(embedded, total), total });
|
|
@@ -168137,16 +168561,50 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
|
|
|
168137
168561
|
}
|
|
168138
168562
|
} finally {
|
|
168139
168563
|
clearInterval(renewal);
|
|
168140
|
-
|
|
168564
|
+
try {
|
|
168565
|
+
releaseGitSweepLease(db, projectIdentity, holderId);
|
|
168566
|
+
} catch (error51) {
|
|
168567
|
+
log("[magic-context] embed drain: lease release failed (will TTL-expire):", error51);
|
|
168568
|
+
}
|
|
168141
168569
|
}
|
|
168142
168570
|
if (aborted2)
|
|
168143
|
-
return { status: "aborted", embedded, total };
|
|
168144
|
-
if (
|
|
168571
|
+
return { status: "aborted", embedded, total, failed: failedIds.length };
|
|
168572
|
+
if (providerDown || failedIds.length > 0) {
|
|
168145
168573
|
const remaining = Math.max(0, countUnembeddedSessionCompartments(db, projectIdentity, sessionId, snapshot.chunkModelId) - skipIds.length);
|
|
168146
|
-
if (remaining > 0)
|
|
168147
|
-
return { status: "stalled", embedded, total, remaining };
|
|
168574
|
+
if (remaining > 0) {
|
|
168575
|
+
return { status: "stalled", embedded, total, remaining, failed: failedIds.length };
|
|
168576
|
+
}
|
|
168148
168577
|
}
|
|
168149
|
-
return { status: "done", embedded, total };
|
|
168578
|
+
return { status: "done", embedded, total, failed: failedIds.length };
|
|
168579
|
+
}
|
|
168580
|
+
function getEmbeddingCoverageStatus(db, projectIdentity, sessionId) {
|
|
168581
|
+
const snapshot = getProjectEmbeddingSnapshot(projectIdentity);
|
|
168582
|
+
if (!snapshot?.enabled || snapshot.chunkModelId === "off") {
|
|
168583
|
+
return {
|
|
168584
|
+
enabled: false,
|
|
168585
|
+
model: snapshot?.model ?? "off",
|
|
168586
|
+
provider: snapshot?.provider ?? "off",
|
|
168587
|
+
session: { embedded: 0, total: 0 },
|
|
168588
|
+
memories: { embedded: 0, total: 0 },
|
|
168589
|
+
commits: { embedded: 0, total: 0, gitEnabled: false }
|
|
168590
|
+
};
|
|
168591
|
+
}
|
|
168592
|
+
const session = countSessionCompartmentEmbedCoverage(db, projectIdentity, sessionId, snapshot.chunkModelId);
|
|
168593
|
+
const memories = getMemoryEmbedCoverage(db, projectIdentity, snapshot.modelId);
|
|
168594
|
+
const gitEnabled = snapshot.gitCommitEnabled;
|
|
168595
|
+
const commits = gitEnabled ? {
|
|
168596
|
+
embedded: countEmbeddedCommits(db, projectIdentity),
|
|
168597
|
+
total: getCommitCount(db, projectIdentity),
|
|
168598
|
+
gitEnabled: true
|
|
168599
|
+
} : { embedded: 0, total: 0, gitEnabled: false };
|
|
168600
|
+
return {
|
|
168601
|
+
enabled: true,
|
|
168602
|
+
model: snapshot.model,
|
|
168603
|
+
provider: snapshot.provider,
|
|
168604
|
+
session,
|
|
168605
|
+
memories,
|
|
168606
|
+
commits
|
|
168607
|
+
};
|
|
168150
168608
|
}
|
|
168151
168609
|
|
|
168152
168610
|
// ../plugin/src/features/magic-context/memory/embedding.ts
|
|
@@ -168167,6 +168625,7 @@ function createProvider2(config2) {
|
|
|
168167
168625
|
model: config2.model,
|
|
168168
168626
|
apiKey: config2.api_key,
|
|
168169
168627
|
inputType: config2.input_type,
|
|
168628
|
+
queryInputType: config2.query_input_type,
|
|
168170
168629
|
truncate: config2.truncate,
|
|
168171
168630
|
maxInputTokens: config2.max_input_tokens
|
|
168172
168631
|
});
|
|
@@ -168195,118 +168654,6 @@ async function embedText(text, signal) {
|
|
|
168195
168654
|
}
|
|
168196
168655
|
var SWEEP_MAX_WALL_CLOCK_MS2 = 10 * 60 * 1000;
|
|
168197
168656
|
|
|
168198
|
-
// ../plugin/src/features/magic-context/git-commits/storage-git-commits.ts
|
|
168199
|
-
init_logger();
|
|
168200
|
-
var insertStatements = new WeakMap;
|
|
168201
|
-
var existingShasStatements = new WeakMap;
|
|
168202
|
-
var projectCountStatements = new WeakMap;
|
|
168203
|
-
var evictStatements = new WeakMap;
|
|
168204
|
-
var evictOverflowStatements = new WeakMap;
|
|
168205
|
-
var latestCommitTimeStatements = new WeakMap;
|
|
168206
|
-
function getInsertStatement(db) {
|
|
168207
|
-
let stmt = insertStatements.get(db);
|
|
168208
|
-
if (!stmt) {
|
|
168209
|
-
stmt = db.prepare(`INSERT INTO git_commits (sha, project_path, short_sha, message, author, committed_at, indexed_at)
|
|
168210
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
168211
|
-
ON CONFLICT(sha) DO UPDATE SET
|
|
168212
|
-
project_path = excluded.project_path,
|
|
168213
|
-
short_sha = excluded.short_sha,
|
|
168214
|
-
message = excluded.message,
|
|
168215
|
-
author = excluded.author,
|
|
168216
|
-
committed_at = excluded.committed_at,
|
|
168217
|
-
indexed_at = excluded.indexed_at
|
|
168218
|
-
WHERE git_commits.message != excluded.message`);
|
|
168219
|
-
insertStatements.set(db, stmt);
|
|
168220
|
-
}
|
|
168221
|
-
return stmt;
|
|
168222
|
-
}
|
|
168223
|
-
function getExistingShasStatement(db) {
|
|
168224
|
-
let stmt = existingShasStatements.get(db);
|
|
168225
|
-
if (!stmt) {
|
|
168226
|
-
stmt = db.prepare("SELECT sha FROM git_commits WHERE project_path = ?");
|
|
168227
|
-
existingShasStatements.set(db, stmt);
|
|
168228
|
-
}
|
|
168229
|
-
return stmt;
|
|
168230
|
-
}
|
|
168231
|
-
function getProjectCountStatement(db) {
|
|
168232
|
-
let stmt = projectCountStatements.get(db);
|
|
168233
|
-
if (!stmt) {
|
|
168234
|
-
stmt = db.prepare("SELECT COUNT(*) AS count FROM git_commits WHERE project_path = ?");
|
|
168235
|
-
projectCountStatements.set(db, stmt);
|
|
168236
|
-
}
|
|
168237
|
-
return stmt;
|
|
168238
|
-
}
|
|
168239
|
-
function getLatestCommitTimeStatement(db) {
|
|
168240
|
-
let stmt = latestCommitTimeStatements.get(db);
|
|
168241
|
-
if (!stmt) {
|
|
168242
|
-
stmt = db.prepare("SELECT MAX(committed_at) AS latest FROM git_commits WHERE project_path = ?");
|
|
168243
|
-
latestCommitTimeStatements.set(db, stmt);
|
|
168244
|
-
}
|
|
168245
|
-
return stmt;
|
|
168246
|
-
}
|
|
168247
|
-
function getEvictOverflowStatement(db) {
|
|
168248
|
-
let stmt = evictOverflowStatements.get(db);
|
|
168249
|
-
if (!stmt) {
|
|
168250
|
-
stmt = db.prepare(`DELETE FROM git_commits
|
|
168251
|
-
WHERE rowid IN (
|
|
168252
|
-
SELECT rowid FROM git_commits
|
|
168253
|
-
WHERE project_path = ?
|
|
168254
|
-
ORDER BY committed_at DESC, sha DESC
|
|
168255
|
-
LIMIT -1 OFFSET ?
|
|
168256
|
-
)`);
|
|
168257
|
-
evictOverflowStatements.set(db, stmt);
|
|
168258
|
-
}
|
|
168259
|
-
return stmt;
|
|
168260
|
-
}
|
|
168261
|
-
function upsertCommits(db, projectPath, commits) {
|
|
168262
|
-
if (commits.length === 0)
|
|
168263
|
-
return { inserted: 0, updated: 0 };
|
|
168264
|
-
const existing = new Set;
|
|
168265
|
-
for (const row of getExistingShasStatement(db).all(projectPath)) {
|
|
168266
|
-
existing.add(row.sha);
|
|
168267
|
-
}
|
|
168268
|
-
let inserted = 0;
|
|
168269
|
-
let updated = 0;
|
|
168270
|
-
const now = Date.now();
|
|
168271
|
-
const insertStmt = getInsertStatement(db);
|
|
168272
|
-
db.transaction(() => {
|
|
168273
|
-
for (const commit of commits) {
|
|
168274
|
-
const result = insertStmt.run(commit.sha, projectPath, commit.shortSha, commit.message, commit.author, commit.committedAtMs, now);
|
|
168275
|
-
if (result.changes > 0) {
|
|
168276
|
-
if (existing.has(commit.sha)) {
|
|
168277
|
-
updated++;
|
|
168278
|
-
} else {
|
|
168279
|
-
inserted++;
|
|
168280
|
-
existing.add(commit.sha);
|
|
168281
|
-
}
|
|
168282
|
-
}
|
|
168283
|
-
}
|
|
168284
|
-
})();
|
|
168285
|
-
return { inserted, updated };
|
|
168286
|
-
}
|
|
168287
|
-
function getCommitCount(db, projectPath) {
|
|
168288
|
-
const row = getProjectCountStatement(db).get(projectPath);
|
|
168289
|
-
return row?.count ?? 0;
|
|
168290
|
-
}
|
|
168291
|
-
function getLatestIndexedCommitTimeMs(db, projectPath) {
|
|
168292
|
-
const row = getLatestCommitTimeStatement(db).get(projectPath);
|
|
168293
|
-
return row?.latest ?? null;
|
|
168294
|
-
}
|
|
168295
|
-
function enforceProjectCap(db, projectPath, maxCommits) {
|
|
168296
|
-
if (maxCommits <= 0)
|
|
168297
|
-
return 0;
|
|
168298
|
-
const count = getCommitCount(db, projectPath);
|
|
168299
|
-
if (count <= maxCommits)
|
|
168300
|
-
return 0;
|
|
168301
|
-
getEvictOverflowStatement(db).run(projectPath, maxCommits);
|
|
168302
|
-
const after = getCommitCount(db, projectPath);
|
|
168303
|
-
const evicted = Math.max(0, count - after);
|
|
168304
|
-
if (evicted > 0) {
|
|
168305
|
-
log(`[git-commits] evicted ${evicted} oldest commits for project ${projectPath} (cap=${maxCommits}, was=${count})`);
|
|
168306
|
-
}
|
|
168307
|
-
return evicted;
|
|
168308
|
-
}
|
|
168309
|
-
|
|
168310
168657
|
// ../plugin/src/features/magic-context/git-commits/indexer.ts
|
|
168311
168658
|
var MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
168312
168659
|
var EMBED_BATCH_SIZE = 16;
|
|
@@ -168715,7 +169062,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled = getProjectEmbedd
|
|
|
168715
169062
|
experimentalPinKeyFiles: reg.experimentalPinKeyFiles,
|
|
168716
169063
|
projectIdentity: reg.projectIdentity,
|
|
168717
169064
|
sessionDirectoryOverride: reg.directory,
|
|
168718
|
-
fallbackModels: resolveFallbackChain(
|
|
169065
|
+
fallbackModels: resolveFallbackChain(reg.dreamerConfig.fallback_models)
|
|
168719
169066
|
});
|
|
168720
169067
|
} catch (error51) {
|
|
168721
169068
|
log(`[dreamer] timer-triggered queue processing failed for ${reg.projectIdentity}:`, error51);
|
|
@@ -169591,7 +169938,7 @@ async function awaitInFlightDreamers() {
|
|
|
169591
169938
|
function createPiDreamerClient(opts) {
|
|
169592
169939
|
const runner2 = piSubagentRunnerFactory();
|
|
169593
169940
|
const model = opts.config.model;
|
|
169594
|
-
const fallbackModels = resolveFallbackChain(
|
|
169941
|
+
const fallbackModels = resolveFallbackChain(opts.config.fallback_models);
|
|
169595
169942
|
const session = {
|
|
169596
169943
|
create: async (args) => {
|
|
169597
169944
|
const sessionId = `magic-context-pi-dream-${++sessionCounter}`;
|
|
@@ -169836,87 +170183,229 @@ function registerCtxDreamCommand(pi, deps) {
|
|
|
169836
170183
|
});
|
|
169837
170184
|
}
|
|
169838
170185
|
|
|
169839
|
-
// src/
|
|
169840
|
-
|
|
169841
|
-
|
|
169842
|
-
|
|
169843
|
-
|
|
170186
|
+
// ../plugin/src/hooks/magic-context/embed-session-state.ts
|
|
170187
|
+
var embedPauseBySession = new Set;
|
|
170188
|
+
var embedRunStateBySession = new Map;
|
|
170189
|
+
var autoEmbedAttemptedBySession = new Set;
|
|
170190
|
+
|
|
170191
|
+
// ../plugin/src/hooks/magic-context/format-embed-status.ts
|
|
170192
|
+
function formatEmbedStatusText(coverage, drain) {
|
|
170193
|
+
if (!coverage.enabled) {
|
|
170194
|
+
return "Embedding is off (no provider configured).";
|
|
170195
|
+
}
|
|
170196
|
+
const lines = [];
|
|
170197
|
+
lines.push(`Embedding — model: ${coverage.model} (${coverage.provider})`);
|
|
170198
|
+
lines.push(`This session: ${coverage.session.embedded} / ${coverage.session.total} compartments embedded`);
|
|
170199
|
+
lines.push(`Project memories: ${coverage.memories.embedded} / ${coverage.memories.total} embedded`);
|
|
170200
|
+
if (coverage.commits.gitEnabled) {
|
|
170201
|
+
lines.push(`Git commits: ${coverage.commits.embedded} / ${coverage.commits.total}`);
|
|
170202
|
+
} else {
|
|
170203
|
+
lines.push("Git commits: 0 / 0 (git indexing off)");
|
|
170204
|
+
}
|
|
170205
|
+
let drainLine = "Drain: idle";
|
|
170206
|
+
switch (drain.status) {
|
|
170207
|
+
case "running": {
|
|
170208
|
+
const e = drain.embedded ?? coverage.session.embedded;
|
|
170209
|
+
const t = drain.total ?? coverage.session.total;
|
|
170210
|
+
const failedSuffix = drain.failed && drain.failed > 0 ? ` (${drain.failed} failed)` : "";
|
|
170211
|
+
drainLine = `Drain: running ${e}/${t}${failedSuffix}`;
|
|
170212
|
+
break;
|
|
170213
|
+
}
|
|
170214
|
+
case "paused": {
|
|
170215
|
+
const e = drain.embedded ?? coverage.session.embedded;
|
|
170216
|
+
const t = drain.total ?? coverage.session.total;
|
|
170217
|
+
drainLine = `Drain: paused ${e}/${t}`;
|
|
170218
|
+
break;
|
|
170219
|
+
}
|
|
170220
|
+
case "stopped":
|
|
170221
|
+
drainLine = "Drain: stopped (provider down)";
|
|
170222
|
+
break;
|
|
170223
|
+
default:
|
|
170224
|
+
drainLine = "Drain: idle";
|
|
170225
|
+
}
|
|
170226
|
+
lines.push(drainLine);
|
|
170227
|
+
return lines.join(`
|
|
170228
|
+
`);
|
|
170229
|
+
}
|
|
170230
|
+
|
|
170231
|
+
// src/commands/ctx-embed.ts
|
|
170232
|
+
function clearPiEmbedSessionState(sessionId) {
|
|
170233
|
+
embedPauseBySession.delete(sessionId);
|
|
170234
|
+
const ctrl = embedRunStateBySession.get(sessionId);
|
|
170235
|
+
if (ctrl) {
|
|
170236
|
+
ctrl.abort();
|
|
170237
|
+
embedRunStateBySession.delete(sessionId);
|
|
170238
|
+
}
|
|
170239
|
+
autoEmbedAttemptedBySession.delete(sessionId);
|
|
170240
|
+
}
|
|
170241
|
+
async function runEmbedDrain(db, projectIdentity, sessionId) {
|
|
170242
|
+
const activeCtrl = embedRunStateBySession.get(sessionId);
|
|
170243
|
+
if (activeCtrl && !activeCtrl.signal.aborted) {
|
|
170244
|
+
return {
|
|
170245
|
+
text: `## /ctx-embed
|
|
170246
|
+
|
|
170247
|
+
Embedding is already running for this session.`,
|
|
170248
|
+
level: "info"
|
|
170249
|
+
};
|
|
170250
|
+
}
|
|
170251
|
+
embedPauseBySession.delete(sessionId);
|
|
170252
|
+
const prior = embedRunStateBySession.get(sessionId);
|
|
170253
|
+
if (prior)
|
|
170254
|
+
prior.abort();
|
|
170255
|
+
const controller = new AbortController;
|
|
170256
|
+
embedRunStateBySession.set(sessionId, controller);
|
|
170257
|
+
let outcome;
|
|
170258
|
+
try {
|
|
170259
|
+
outcome = await embedSessionCompartmentChunks(db, projectIdentity, sessionId, {
|
|
170260
|
+
signal: controller.signal
|
|
170261
|
+
});
|
|
170262
|
+
} finally {
|
|
170263
|
+
if (embedRunStateBySession.get(sessionId) === controller) {
|
|
170264
|
+
embedRunStateBySession.delete(sessionId);
|
|
170265
|
+
}
|
|
170266
|
+
}
|
|
170267
|
+
switch (outcome.status) {
|
|
170268
|
+
case "nothing":
|
|
170269
|
+
return {
|
|
170270
|
+
text: `## /ctx-embed
|
|
170271
|
+
|
|
170272
|
+
All of this session's history is already embedded.`,
|
|
170273
|
+
level: "info"
|
|
170274
|
+
};
|
|
170275
|
+
case "disabled":
|
|
170276
|
+
return {
|
|
170277
|
+
text: `## /ctx-embed
|
|
170278
|
+
|
|
170279
|
+
No embedding provider is configured, so there is nothing to embed.`,
|
|
170280
|
+
level: "info"
|
|
170281
|
+
};
|
|
170282
|
+
case "busy":
|
|
170283
|
+
return {
|
|
170284
|
+
text: `## /ctx-embed
|
|
170285
|
+
|
|
170286
|
+
Embedding is already running for this project. Try again shortly.`,
|
|
170287
|
+
level: "info"
|
|
170288
|
+
};
|
|
170289
|
+
case "aborted": {
|
|
170290
|
+
const cov = getEmbeddingCoverageStatus(db, projectIdentity, sessionId);
|
|
170291
|
+
return {
|
|
170292
|
+
text: `## /ctx-embed
|
|
170293
|
+
|
|
170294
|
+
Paused at ${cov.session.embedded}/${cov.session.total} compartments embedded.`,
|
|
170295
|
+
level: "info"
|
|
170296
|
+
};
|
|
170297
|
+
}
|
|
170298
|
+
case "stalled":
|
|
170299
|
+
return {
|
|
170300
|
+
text: `## /ctx-embed
|
|
170301
|
+
|
|
170302
|
+
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.`,
|
|
170303
|
+
level: "info"
|
|
170304
|
+
};
|
|
170305
|
+
default:
|
|
170306
|
+
return {
|
|
170307
|
+
text: `## /ctx-embed
|
|
170308
|
+
|
|
170309
|
+
Embedded ${outcome.embedded} compartment${outcome.embedded === 1 ? "" : "s"} of history for semantic search.`,
|
|
170310
|
+
level: "success"
|
|
170311
|
+
};
|
|
170312
|
+
}
|
|
170313
|
+
}
|
|
170314
|
+
function registerCtxEmbedCommand(pi, deps) {
|
|
170315
|
+
pi.registerCommand("ctx-embed", {
|
|
170316
|
+
description: "Embedding status, or start/pause history compartment embedding (start | pause)",
|
|
170317
|
+
handler: async (args, ctx) => {
|
|
169844
170318
|
const sessionId = resolveSessionId(ctx);
|
|
169845
170319
|
if (!sessionId) {
|
|
169846
170320
|
sendCtxStatusMessage(pi, {
|
|
169847
|
-
title: "/ctx-embed
|
|
169848
|
-
text: `## /ctx-embed
|
|
170321
|
+
title: "/ctx-embed",
|
|
170322
|
+
text: `## /ctx-embed
|
|
169849
170323
|
|
|
169850
170324
|
No active Pi session is available.`,
|
|
169851
170325
|
level: "error"
|
|
169852
170326
|
});
|
|
169853
170327
|
return;
|
|
169854
170328
|
}
|
|
170329
|
+
const project = deps.resolveProject?.(ctx) ?? {
|
|
170330
|
+
projectDir: deps.projectDir,
|
|
170331
|
+
projectIdentity: deps.projectIdentity
|
|
170332
|
+
};
|
|
170333
|
+
const sub = args.trim().toLowerCase();
|
|
170334
|
+
if (sub === "pause") {
|
|
170335
|
+
embedPauseBySession.add(sessionId);
|
|
170336
|
+
const ctrl = embedRunStateBySession.get(sessionId);
|
|
170337
|
+
if (ctrl)
|
|
170338
|
+
ctrl.abort();
|
|
170339
|
+
const cov = getEmbeddingCoverageStatus(deps.db, project.projectIdentity, sessionId);
|
|
170340
|
+
sendCtxStatusMessage(pi, {
|
|
170341
|
+
title: "/ctx-embed",
|
|
170342
|
+
text: `## /ctx-embed
|
|
170343
|
+
|
|
170344
|
+
Paused at ${cov.session.embedded}/${cov.session.total} compartments embedded.`,
|
|
170345
|
+
level: "info"
|
|
170346
|
+
});
|
|
170347
|
+
return;
|
|
170348
|
+
}
|
|
169855
170349
|
if (deps.memoryEnabled === false) {
|
|
169856
170350
|
sendCtxStatusMessage(pi, {
|
|
169857
|
-
title: "/ctx-embed
|
|
169858
|
-
text: `## /ctx-embed
|
|
170351
|
+
title: "/ctx-embed",
|
|
170352
|
+
text: `## /ctx-embed
|
|
169859
170353
|
|
|
169860
170354
|
Memory is disabled for this project, so there is no semantic embedding to backfill.`,
|
|
169861
170355
|
level: "info"
|
|
169862
170356
|
});
|
|
169863
170357
|
return;
|
|
169864
170358
|
}
|
|
169865
|
-
const project = deps.resolveProject?.(ctx) ?? {
|
|
169866
|
-
projectDir: deps.projectDir,
|
|
169867
|
-
projectIdentity: deps.projectIdentity
|
|
169868
|
-
};
|
|
169869
170359
|
await ensureProjectRegisteredFromPiDirectory(project.projectDir, deps.db);
|
|
169870
|
-
|
|
169871
|
-
|
|
169872
|
-
|
|
169873
|
-
|
|
169874
|
-
|
|
169875
|
-
|
|
169876
|
-
|
|
169877
|
-
|
|
169878
|
-
|
|
169879
|
-
|
|
169880
|
-
|
|
169881
|
-
|
|
169882
|
-
|
|
169883
|
-
|
|
169884
|
-
|
|
169885
|
-
|
|
169886
|
-
|
|
169887
|
-
|
|
169888
|
-
return {
|
|
169889
|
-
text: `## /ctx-embed-history
|
|
169890
|
-
|
|
169891
|
-
Embedding is already running for this project — ${outcome.total} compartment${outcome.total === 1 ? "" : "s"} still pending. Try again shortly.`,
|
|
169892
|
-
level: "info"
|
|
169893
|
-
};
|
|
169894
|
-
case "stalled":
|
|
169895
|
-
return {
|
|
169896
|
-
text: `## /ctx-embed-history
|
|
169897
|
-
|
|
169898
|
-
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.`,
|
|
169899
|
-
level: "info"
|
|
169900
|
-
};
|
|
169901
|
-
default:
|
|
169902
|
-
return {
|
|
169903
|
-
text: `## /ctx-embed-history
|
|
170360
|
+
if (sub === "start") {
|
|
170361
|
+
const { text, level } = await runEmbedDrain(deps.db, project.projectIdentity, sessionId);
|
|
170362
|
+
sendCtxStatusMessage(pi, { title: "/ctx-embed", text, level });
|
|
170363
|
+
return;
|
|
170364
|
+
}
|
|
170365
|
+
if (sub !== "") {
|
|
170366
|
+
sendCtxStatusMessage(pi, {
|
|
170367
|
+
title: "/ctx-embed",
|
|
170368
|
+
text: "## /ctx-embed\n\nUsage: `/ctx-embed` (status), `/ctx-embed start`, or `/ctx-embed pause`.",
|
|
170369
|
+
level: "info"
|
|
170370
|
+
});
|
|
170371
|
+
return;
|
|
170372
|
+
}
|
|
170373
|
+
const coverage = getEmbeddingCoverageStatus(deps.db, project.projectIdentity, sessionId);
|
|
170374
|
+
const statusText = formatEmbedStatusText(coverage, { status: "idle" });
|
|
170375
|
+
sendCtxStatusMessage(pi, {
|
|
170376
|
+
title: "/ctx-embed",
|
|
170377
|
+
text: `## Embedding Status
|
|
169904
170378
|
|
|
169905
|
-
|
|
169906
|
-
|
|
169907
|
-
};
|
|
169908
|
-
}
|
|
169909
|
-
})();
|
|
169910
|
-
sendCtxStatusMessage(pi, { title: "/ctx-embed-history", text, level }, {
|
|
169911
|
-
sessionId,
|
|
169912
|
-
projectIdentity: project.projectIdentity,
|
|
169913
|
-
status: outcome.status,
|
|
169914
|
-
embedded: outcome.embedded,
|
|
169915
|
-
total: outcome.total
|
|
170379
|
+
${statusText}`,
|
|
170380
|
+
level: "info"
|
|
169916
170381
|
});
|
|
169917
170382
|
}
|
|
169918
170383
|
});
|
|
169919
170384
|
}
|
|
170385
|
+
function maybeAutoEmbedPiSession(deps, sessionId, projectDir, projectIdentity, notify) {
|
|
170386
|
+
if (autoEmbedAttemptedBySession.has(sessionId))
|
|
170387
|
+
return;
|
|
170388
|
+
if (embedPauseBySession.has(sessionId))
|
|
170389
|
+
return;
|
|
170390
|
+
if (deps.memoryEnabled === false)
|
|
170391
|
+
return;
|
|
170392
|
+
autoEmbedAttemptedBySession.add(sessionId);
|
|
170393
|
+
(async () => {
|
|
170394
|
+
try {
|
|
170395
|
+
await new Promise((resolve5) => setTimeout(resolve5, 0));
|
|
170396
|
+
await ensureProjectRegisteredFromPiDirectory(projectDir, deps.db);
|
|
170397
|
+
const coverage = getEmbeddingCoverageStatus(deps.db, projectIdentity, sessionId);
|
|
170398
|
+
if (!coverage.enabled)
|
|
170399
|
+
return;
|
|
170400
|
+
const remaining = coverage.session.total - coverage.session.embedded;
|
|
170401
|
+
if (remaining <= 0)
|
|
170402
|
+
return;
|
|
170403
|
+
notify(`Embedding ${remaining} compartment${remaining === 1 ? "" : "s"} of history in the background…`);
|
|
170404
|
+
const { text } = await runEmbedDrain(deps.db, projectIdentity, sessionId);
|
|
170405
|
+
notify(text.replace(/^## \/ctx-embed\n\n/, ""));
|
|
170406
|
+
} catch {}
|
|
170407
|
+
})();
|
|
170408
|
+
}
|
|
169920
170409
|
|
|
169921
170410
|
// ../plugin/src/hooks/magic-context/execute-flush.ts
|
|
169922
170411
|
init_logger();
|
|
@@ -170010,10 +170499,9 @@ function makeToolCompositeKey(ownerMsgId, callId) {
|
|
|
170010
170499
|
}
|
|
170011
170500
|
var GET_COUNTER_SQL = `SELECT counter FROM session_meta WHERE session_id = ?`;
|
|
170012
170501
|
var GET_ASSIGNMENTS_SQL = "SELECT message_id, tag_number, type, tool_owner_message_id FROM tags WHERE session_id = ? ORDER BY tag_number ASC";
|
|
170502
|
+
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";
|
|
170013
170503
|
var PROBE_DATA_VERSION_SQL = "PRAGMA main.data_version";
|
|
170014
|
-
var PROBE_TOTAL_CHANGES_SQL = "SELECT total_changes() AS tc";
|
|
170015
170504
|
var probeDataVersionStatements = new WeakMap;
|
|
170016
|
-
var probeTotalChangesStatements = new WeakMap;
|
|
170017
170505
|
function getProbeDataVersionStatement(db) {
|
|
170018
170506
|
let stmt = probeDataVersionStatements.get(db);
|
|
170019
170507
|
if (!stmt) {
|
|
@@ -170022,14 +170510,6 @@ function getProbeDataVersionStatement(db) {
|
|
|
170022
170510
|
}
|
|
170023
170511
|
return stmt;
|
|
170024
170512
|
}
|
|
170025
|
-
function getProbeTotalChangesStatement(db) {
|
|
170026
|
-
let stmt = probeTotalChangesStatements.get(db);
|
|
170027
|
-
if (!stmt) {
|
|
170028
|
-
stmt = db.prepare(PROBE_TOTAL_CHANGES_SQL);
|
|
170029
|
-
probeTotalChangesStatements.set(db, stmt);
|
|
170030
|
-
}
|
|
170031
|
-
return stmt;
|
|
170032
|
-
}
|
|
170033
170513
|
function isAssignmentRow(row) {
|
|
170034
170514
|
if (row === null || typeof row !== "object") {
|
|
170035
170515
|
return false;
|
|
@@ -170222,20 +170702,18 @@ function createTagger() {
|
|
|
170222
170702
|
}
|
|
170223
170703
|
function probeSignature(db) {
|
|
170224
170704
|
const dvRow = getProbeDataVersionStatement(db).get();
|
|
170225
|
-
const tcRow = getProbeTotalChangesStatement(db).get();
|
|
170226
170705
|
return {
|
|
170227
|
-
dataVersion: dvRow?.data_version ?? 0
|
|
170228
|
-
totalChanges: tcRow?.tc ?? 0
|
|
170706
|
+
dataVersion: dvRow?.data_version ?? 0
|
|
170229
170707
|
};
|
|
170230
170708
|
}
|
|
170231
|
-
function initFromDb(sessionId, db) {
|
|
170709
|
+
function initFromDb(sessionId, db, floor = 0) {
|
|
170232
170710
|
const probe = probeSignature(db);
|
|
170233
170711
|
const cached2 = loadSignatures.get(sessionId);
|
|
170234
|
-
if (cached2 !== undefined && cached2.db === db && cached2.dataVersion === probe.dataVersion && cached2.
|
|
170712
|
+
if (cached2 !== undefined && cached2.db === db && cached2.dataVersion === probe.dataVersion && cached2.floor === floor) {
|
|
170235
170713
|
return;
|
|
170236
170714
|
}
|
|
170237
170715
|
const row = db.prepare(GET_COUNTER_SQL).get(sessionId);
|
|
170238
|
-
const assignmentRows = db.prepare(GET_ASSIGNMENTS_SQL).all(sessionId).filter(isAssignmentRow);
|
|
170716
|
+
const assignmentRows = (floor > 0 ? db.prepare(GET_ASSIGNMENTS_SCOPED_SQL).all(sessionId, floor) : db.prepare(GET_ASSIGNMENTS_SQL).all(sessionId)).filter(isAssignmentRow);
|
|
170239
170717
|
const sessionAssignments = getSessionAssignments(sessionId);
|
|
170240
170718
|
sessionAssignments.clear();
|
|
170241
170719
|
let maxTagNumber = 0;
|
|
@@ -170256,7 +170734,7 @@ function createTagger() {
|
|
|
170256
170734
|
loadSignatures.set(sessionId, {
|
|
170257
170735
|
db,
|
|
170258
170736
|
dataVersion: probe.dataVersion,
|
|
170259
|
-
|
|
170737
|
+
floor
|
|
170260
170738
|
});
|
|
170261
170739
|
}
|
|
170262
170740
|
function cleanup(sessionId) {
|
|
@@ -170280,6 +170758,162 @@ function createTagger() {
|
|
|
170280
170758
|
};
|
|
170281
170759
|
}
|
|
170282
170760
|
|
|
170761
|
+
// ../plugin/src/features/magic-context/transform-decision-log.ts
|
|
170762
|
+
var canonicalReasons = new Set([
|
|
170763
|
+
"system_hash",
|
|
170764
|
+
"model_change",
|
|
170765
|
+
"project_memory_epoch",
|
|
170766
|
+
"ttl_idle",
|
|
170767
|
+
"explicit_flush",
|
|
170768
|
+
"max_mutation_id",
|
|
170769
|
+
"first_render",
|
|
170770
|
+
"pressure_refold",
|
|
170771
|
+
"upgrade_state",
|
|
170772
|
+
"cached_m1_missing"
|
|
170773
|
+
]);
|
|
170774
|
+
var piReasonAliases = {
|
|
170775
|
+
project_memory_change: "project_memory_epoch",
|
|
170776
|
+
pending_mutations: "max_mutation_id",
|
|
170777
|
+
renderer_upgrade: "upgrade_state",
|
|
170778
|
+
cache_invalid: "cached_m1_missing",
|
|
170779
|
+
drift: "pressure_refold"
|
|
170780
|
+
};
|
|
170781
|
+
var sharedReasonAliases = {
|
|
170782
|
+
model_key: "model_change",
|
|
170783
|
+
pressure: "pressure_refold"
|
|
170784
|
+
};
|
|
170785
|
+
var pendingDecisionBySession = new Map;
|
|
170786
|
+
var pendingPiDecisionBySession = new Map;
|
|
170787
|
+
var lastBoundMessageIdBySession = new Map;
|
|
170788
|
+
var scheduledWriteTokensBySession = new Map;
|
|
170789
|
+
var writerOverrideForTests = null;
|
|
170790
|
+
function normalizeMaterializeReason(harness, reason, rematerialized) {
|
|
170791
|
+
const raw = typeof reason === "string" ? reason.trim() : "";
|
|
170792
|
+
if (raw.length > 0) {
|
|
170793
|
+
const alias = sharedReasonAliases[raw] ?? (harness === "pi" ? piReasonAliases[raw] : undefined) ?? undefined;
|
|
170794
|
+
if (alias)
|
|
170795
|
+
return alias;
|
|
170796
|
+
if (canonicalReasons.has(raw))
|
|
170797
|
+
return raw;
|
|
170798
|
+
return null;
|
|
170799
|
+
}
|
|
170800
|
+
return rematerialized ? "pressure_refold" : null;
|
|
170801
|
+
}
|
|
170802
|
+
function recordPendingPiTransformDecision(sessionId, decision, snapshotNewestAssistantEntryId) {
|
|
170803
|
+
if (!decision.bustedThisPass)
|
|
170804
|
+
return;
|
|
170805
|
+
pendingPiDecisionBySession.set(sessionId, {
|
|
170806
|
+
...decision,
|
|
170807
|
+
snapshotNewestAssistantEntryId
|
|
170808
|
+
});
|
|
170809
|
+
}
|
|
170810
|
+
function findNewestPiAssistantEntryId(entries) {
|
|
170811
|
+
if (!Array.isArray(entries))
|
|
170812
|
+
return null;
|
|
170813
|
+
for (let i = entries.length - 1;i >= 0; i--) {
|
|
170814
|
+
const entry = entries[i];
|
|
170815
|
+
if (!entry || typeof entry !== "object")
|
|
170816
|
+
continue;
|
|
170817
|
+
const row = entry;
|
|
170818
|
+
if (row.type !== "message" || typeof row.id !== "string" || row.id.length === 0) {
|
|
170819
|
+
continue;
|
|
170820
|
+
}
|
|
170821
|
+
const message = row.message;
|
|
170822
|
+
if (message && typeof message === "object" && message.role === "assistant") {
|
|
170823
|
+
return row.id;
|
|
170824
|
+
}
|
|
170825
|
+
}
|
|
170826
|
+
return null;
|
|
170827
|
+
}
|
|
170828
|
+
function schedulePiTransformDecisionResolve(args) {
|
|
170829
|
+
const pending = pendingPiDecisionBySession.get(args.sessionId);
|
|
170830
|
+
if (!pending)
|
|
170831
|
+
return false;
|
|
170832
|
+
const targetMessageId = findNewestPiAssistantEntryIdAfter(args.branchEntries, pending.snapshotNewestAssistantEntryId);
|
|
170833
|
+
if (!targetMessageId)
|
|
170834
|
+
return false;
|
|
170835
|
+
const dbPath = getDatabasePath(args.db);
|
|
170836
|
+
if (!dbPath)
|
|
170837
|
+
return false;
|
|
170838
|
+
pendingPiDecisionBySession.delete(args.sessionId);
|
|
170839
|
+
const token = addScheduledWriteToken(args.sessionId);
|
|
170840
|
+
setTimeout(() => {
|
|
170841
|
+
try {
|
|
170842
|
+
if (!hasScheduledWriteToken(args.sessionId, token))
|
|
170843
|
+
return;
|
|
170844
|
+
writeTransformDecisionBestEffort(dbPath, {
|
|
170845
|
+
...pending,
|
|
170846
|
+
sessionId: args.sessionId,
|
|
170847
|
+
harness: "pi",
|
|
170848
|
+
messageId: targetMessageId
|
|
170849
|
+
});
|
|
170850
|
+
} finally {
|
|
170851
|
+
deleteScheduledWriteToken(args.sessionId, token);
|
|
170852
|
+
}
|
|
170853
|
+
}, 0);
|
|
170854
|
+
return true;
|
|
170855
|
+
}
|
|
170856
|
+
function addScheduledWriteToken(sessionId) {
|
|
170857
|
+
const token = Symbol(sessionId);
|
|
170858
|
+
let tokens = scheduledWriteTokensBySession.get(sessionId);
|
|
170859
|
+
if (!tokens) {
|
|
170860
|
+
tokens = new Set;
|
|
170861
|
+
scheduledWriteTokensBySession.set(sessionId, tokens);
|
|
170862
|
+
}
|
|
170863
|
+
tokens.add(token);
|
|
170864
|
+
return token;
|
|
170865
|
+
}
|
|
170866
|
+
function hasScheduledWriteToken(sessionId, token) {
|
|
170867
|
+
return scheduledWriteTokensBySession.get(sessionId)?.has(token) === true;
|
|
170868
|
+
}
|
|
170869
|
+
function deleteScheduledWriteToken(sessionId, token) {
|
|
170870
|
+
const tokens = scheduledWriteTokensBySession.get(sessionId);
|
|
170871
|
+
if (!tokens)
|
|
170872
|
+
return;
|
|
170873
|
+
tokens.delete(token);
|
|
170874
|
+
if (tokens.size === 0)
|
|
170875
|
+
scheduledWriteTokensBySession.delete(sessionId);
|
|
170876
|
+
}
|
|
170877
|
+
function findNewestPiAssistantEntryIdAfter(entries, snapshotNewestAssistantEntryId) {
|
|
170878
|
+
if (!Array.isArray(entries))
|
|
170879
|
+
return null;
|
|
170880
|
+
for (let i = entries.length - 1;i >= 0; i--) {
|
|
170881
|
+
const entry = entries[i];
|
|
170882
|
+
if (!entry || typeof entry !== "object")
|
|
170883
|
+
continue;
|
|
170884
|
+
const row = entry;
|
|
170885
|
+
if (row.type !== "message" || typeof row.id !== "string" || row.id.length === 0) {
|
|
170886
|
+
continue;
|
|
170887
|
+
}
|
|
170888
|
+
if (snapshotNewestAssistantEntryId !== null && row.id === snapshotNewestAssistantEntryId) {
|
|
170889
|
+
continue;
|
|
170890
|
+
}
|
|
170891
|
+
const message = row.message;
|
|
170892
|
+
if (message && typeof message === "object" && message.role === "assistant") {
|
|
170893
|
+
return row.id;
|
|
170894
|
+
}
|
|
170895
|
+
}
|
|
170896
|
+
return null;
|
|
170897
|
+
}
|
|
170898
|
+
function writeTransformDecisionBestEffort(dbPath, row) {
|
|
170899
|
+
try {
|
|
170900
|
+
const writer = writerOverrideForTests ?? writeTransformDecisionRow;
|
|
170901
|
+
writer(dbPath, row);
|
|
170902
|
+
} catch {}
|
|
170903
|
+
}
|
|
170904
|
+
function writeTransformDecisionRow(dbPath, row) {
|
|
170905
|
+
const db = new Database(dbPath);
|
|
170906
|
+
try {
|
|
170907
|
+
db.exec("PRAGMA busy_timeout=0");
|
|
170908
|
+
db.prepare(`INSERT OR REPLACE INTO transform_decisions (
|
|
170909
|
+
session_id, harness, message_id, ts_ms, decision, materialized,
|
|
170910
|
+
materialize_reason, emergency, dropped_tokens, dropped_count, input_tokens
|
|
170911
|
+
) 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)));
|
|
170912
|
+
} finally {
|
|
170913
|
+
closeQuietly(db);
|
|
170914
|
+
}
|
|
170915
|
+
}
|
|
170916
|
+
|
|
170283
170917
|
// ../plugin/src/features/magic-context/work-metrics.ts
|
|
170284
170918
|
function asNumber2(value) {
|
|
170285
170919
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
@@ -170331,76 +170965,12 @@ function computePiWorkMetrics(sessionEntries) {
|
|
|
170331
170965
|
return { newWorkTokens, totalInputTokens };
|
|
170332
170966
|
}
|
|
170333
170967
|
|
|
170334
|
-
// ../plugin/src/hooks/magic-context/system-injection-stripper.ts
|
|
170335
|
-
var SYSTEM_INJECTION_MARKERS = [
|
|
170336
|
-
"<!-- OMO_INTERNAL_INITIATOR -->",
|
|
170337
|
-
"[SYSTEM DIRECTIVE: MAGIC-CONTEXT",
|
|
170338
|
-
"[SYSTEM DIRECTIVE: OH-MY-OPENCODE",
|
|
170339
|
-
"[Category+Skill Reminder]",
|
|
170340
|
-
"[EDIT ERROR - IMMEDIATE ACTION REQUIRED]",
|
|
170341
|
-
"[task CALL FAILED - IMMEDIATE RETRY REQUIRED]",
|
|
170342
|
-
"[EMERGENCY CONTEXT WINDOW WARNING]",
|
|
170343
|
-
"Unstable background agent appears idle",
|
|
170344
|
-
"**THE SUBAGENT JUST CLAIMED THIS TASK IS DONE."
|
|
170345
|
-
];
|
|
170346
|
-
var SYSTEM_REMINDER_REGEX = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
|
|
170347
|
-
var OMO_MARKER_REGEX = /<!-- OMO_INTERNAL_INITIATOR -->/g;
|
|
170348
|
-
function stripSystemInjection(text) {
|
|
170349
|
-
let hasInjection = false;
|
|
170350
|
-
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
170351
|
-
if (text.includes(marker)) {
|
|
170352
|
-
hasInjection = true;
|
|
170353
|
-
break;
|
|
170354
|
-
}
|
|
170355
|
-
}
|
|
170356
|
-
if (SYSTEM_REMINDER_REGEX.test(text))
|
|
170357
|
-
hasInjection = true;
|
|
170358
|
-
SYSTEM_REMINDER_REGEX.lastIndex = 0;
|
|
170359
|
-
if (!hasInjection)
|
|
170360
|
-
return null;
|
|
170361
|
-
let cleaned = text;
|
|
170362
|
-
cleaned = cleaned.replace(SYSTEM_REMINDER_REGEX, "");
|
|
170363
|
-
cleaned = cleaned.replace(OMO_MARKER_REGEX, "");
|
|
170364
|
-
cleaned = cleaned.replace(/\[SYSTEM DIRECTIVE: OH-MY-(?:OPENCODE|CLAUDE)[^\]]*\][\s\S]*?(?=\n\n(?!\s*[-*])|$)/g, "");
|
|
170365
|
-
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
170366
|
-
if (marker.startsWith("<!-- ") || marker.startsWith("[SYSTEM DIRECTIVE"))
|
|
170367
|
-
continue;
|
|
170368
|
-
const idx = cleaned.indexOf(marker);
|
|
170369
|
-
if (idx === -1)
|
|
170370
|
-
continue;
|
|
170371
|
-
const blockEnd = cleaned.indexOf(`
|
|
170372
|
-
|
|
170373
|
-
`, idx + marker.length);
|
|
170374
|
-
cleaned = blockEnd !== -1 ? cleaned.slice(0, idx) + cleaned.slice(blockEnd) : cleaned.slice(0, idx);
|
|
170375
|
-
}
|
|
170376
|
-
return cleaned.trim();
|
|
170377
|
-
}
|
|
170378
|
-
|
|
170379
170968
|
// ../plugin/src/hooks/magic-context/apply-operations.ts
|
|
170380
|
-
var USER_DROP_PREVIEW_CHARS = 250;
|
|
170381
170969
|
var RECENT_TOOL_SKELETON_WINDOW = 20;
|
|
170382
|
-
function buildReplacementContent(tagId
|
|
170383
|
-
|
|
170384
|
-
|
|
170385
|
-
|
|
170386
|
-
}
|
|
170387
|
-
const currentContent = target.getContent?.() ?? "";
|
|
170388
|
-
const strippedInjection = stripSystemInjection(currentContent);
|
|
170389
|
-
if (strippedInjection !== null && stripTagPrefix(strippedInjection).trim().length === 0) {
|
|
170390
|
-
return `[dropped §${tagId}§]`;
|
|
170391
|
-
}
|
|
170392
|
-
const originalText = stripTagPrefix(currentContent);
|
|
170393
|
-
if (originalText.length <= USER_DROP_PREVIEW_CHARS) {
|
|
170394
|
-
return `[truncated §${tagId}§]
|
|
170395
|
-
${originalText}`;
|
|
170396
|
-
}
|
|
170397
|
-
const hardCut = originalText.slice(0, USER_DROP_PREVIEW_CHARS);
|
|
170398
|
-
const softCutIndex = hardCut.search(/\s\S*$/);
|
|
170399
|
-
const preview = softCutIndex > USER_DROP_PREVIEW_CHARS - 30 ? hardCut.slice(0, softCutIndex) : hardCut;
|
|
170400
|
-
return `[truncated §${tagId}§]
|
|
170401
|
-
${preview}…`;
|
|
170402
|
-
}
|
|
170403
|
-
function applyPendingOperations(sessionId, db, targets, protectedTags = 0, preloadedTags, preloadedPendingOps) {
|
|
170970
|
+
function buildReplacementContent(tagId) {
|
|
170971
|
+
return `[dropped §${tagId}§]`;
|
|
170972
|
+
}
|
|
170973
|
+
function applyPendingOperations(sessionId, db, targets, protectedTags = 0, preloadedTags, preloadedPendingOps, syntheticPendingOps = []) {
|
|
170404
170974
|
let didMutateMessage = false;
|
|
170405
170975
|
db.transaction(() => {
|
|
170406
170976
|
const tags = preloadedTags ?? getTagsBySession(db, sessionId);
|
|
@@ -170408,11 +170978,16 @@ function applyPendingOperations(sessionId, db, targets, protectedTags = 0, prelo
|
|
|
170408
170978
|
const tagTypeById = new Map(tags.map((tag) => [tag.tagNumber, tag.type]));
|
|
170409
170979
|
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;
|
|
170410
170980
|
const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
|
|
170981
|
+
const opsToApply = [
|
|
170982
|
+
...pendingOps.map((op) => ({ op, synthetic: false })),
|
|
170983
|
+
...syntheticPendingOps.map((op) => ({ op, synthetic: true }))
|
|
170984
|
+
];
|
|
170411
170985
|
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));
|
|
170412
|
-
for (const pendingOp of
|
|
170986
|
+
for (const { op: pendingOp, synthetic } of opsToApply) {
|
|
170413
170987
|
const tagStatus = tagStatusById.get(pendingOp.tagId);
|
|
170414
170988
|
if (tagStatus === "compacted" || tagStatus === "dropped") {
|
|
170415
|
-
|
|
170989
|
+
if (!synthetic)
|
|
170990
|
+
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
170416
170991
|
continue;
|
|
170417
170992
|
}
|
|
170418
170993
|
if (protectedTagIds.has(pendingOp.tagId)) {
|
|
@@ -170420,33 +170995,46 @@ function applyPendingOperations(sessionId, db, targets, protectedTags = 0, prelo
|
|
|
170420
170995
|
}
|
|
170421
170996
|
const target = targets.get(pendingOp.tagId);
|
|
170422
170997
|
const isToolTag = tagTypeById.get(pendingOp.tagId) === "tool";
|
|
170998
|
+
if (synthetic) {
|
|
170999
|
+
if (!isToolTag || target?.canDrop?.() !== true)
|
|
171000
|
+
continue;
|
|
171001
|
+
}
|
|
171002
|
+
let shouldPersistDrop = false;
|
|
170423
171003
|
if (isToolTag) {
|
|
170424
171004
|
if (skeletonWindow.has(pendingOp.tagId)) {
|
|
170425
171005
|
const truncResult = target?.truncate?.() ?? "absent";
|
|
170426
|
-
if (truncResult === "incomplete") {
|
|
171006
|
+
if (truncResult === "incomplete" || synthetic && truncResult !== "truncated") {
|
|
170427
171007
|
continue;
|
|
170428
171008
|
}
|
|
170429
171009
|
if (truncResult === "truncated") {
|
|
170430
171010
|
didMutateMessage = true;
|
|
170431
171011
|
}
|
|
170432
171012
|
updateTagDropMode(db, sessionId, pendingOp.tagId, "truncated");
|
|
171013
|
+
shouldPersistDrop = true;
|
|
170433
171014
|
} else {
|
|
170434
171015
|
const dropResult = target?.drop?.() ?? "absent";
|
|
170435
|
-
if (dropResult === "incomplete") {
|
|
171016
|
+
if (dropResult === "incomplete" || synthetic && dropResult !== "removed") {
|
|
170436
171017
|
continue;
|
|
170437
171018
|
}
|
|
170438
171019
|
if (dropResult === "removed") {
|
|
170439
171020
|
didMutateMessage = true;
|
|
170440
171021
|
}
|
|
170441
171022
|
updateTagDropMode(db, sessionId, pendingOp.tagId, "full");
|
|
171023
|
+
shouldPersistDrop = true;
|
|
170442
171024
|
}
|
|
170443
171025
|
} else if (target) {
|
|
170444
|
-
const changed = target.setContent(buildReplacementContent(pendingOp.tagId
|
|
171026
|
+
const changed = target.setContent(buildReplacementContent(pendingOp.tagId));
|
|
170445
171027
|
if (changed)
|
|
170446
171028
|
didMutateMessage = true;
|
|
171029
|
+
shouldPersistDrop = true;
|
|
171030
|
+
} else if (!synthetic) {
|
|
171031
|
+
shouldPersistDrop = true;
|
|
170447
171032
|
}
|
|
171033
|
+
if (!shouldPersistDrop)
|
|
171034
|
+
continue;
|
|
170448
171035
|
updateTagStatus(db, sessionId, pendingOp.tagId, "dropped");
|
|
170449
|
-
|
|
171036
|
+
if (!synthetic)
|
|
171037
|
+
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
170450
171038
|
}
|
|
170451
171039
|
})();
|
|
170452
171040
|
return didMutateMessage;
|
|
@@ -170470,7 +171058,7 @@ function applyFlushedStatuses(sessionId, db, targets, preloadedTags) {
|
|
|
170470
171058
|
}
|
|
170471
171059
|
}
|
|
170472
171060
|
} else if (target) {
|
|
170473
|
-
const changed = target.setContent(buildReplacementContent(tag.tagNumber
|
|
171061
|
+
const changed = target.setContent(buildReplacementContent(tag.tagNumber));
|
|
170474
171062
|
if (changed)
|
|
170475
171063
|
didMutateMessage = true;
|
|
170476
171064
|
}
|
|
@@ -170758,7 +171346,8 @@ function applyCavemanCleanup(sessionId, db, targets, tags, config2) {
|
|
|
170758
171346
|
const result = {
|
|
170759
171347
|
compressedToLite: 0,
|
|
170760
171348
|
compressedToFull: 0,
|
|
170761
|
-
compressedToUltra: 0
|
|
171349
|
+
compressedToUltra: 0,
|
|
171350
|
+
mutatedTextTags: 0
|
|
170762
171351
|
};
|
|
170763
171352
|
if (!config2.enabled)
|
|
170764
171353
|
return result;
|
|
@@ -170799,7 +171388,9 @@ function applyCavemanCleanup(sessionId, db, targets, tags, config2) {
|
|
|
170799
171388
|
const target = targets.get(tag.tagNumber);
|
|
170800
171389
|
if (!target)
|
|
170801
171390
|
continue;
|
|
170802
|
-
target.setContent(compressed);
|
|
171391
|
+
const didMutate = target.setContent(compressed);
|
|
171392
|
+
if (didMutate)
|
|
171393
|
+
result.mutatedTextTags += 1;
|
|
170803
171394
|
updateCavemanDepth(db, sessionId, tag.tagNumber, targetDepth);
|
|
170804
171395
|
if (targetDepth === DEPTH_LITE)
|
|
170805
171396
|
result.compressedToLite += 1;
|
|
@@ -171177,7 +171768,7 @@ function buildToolArcs(messages) {
|
|
|
171177
171768
|
}
|
|
171178
171769
|
return arcs.sort((a, b) => a.invOrdinal - b.invOrdinal || (a.resOrdinal ?? Number.MAX_SAFE_INTEGER) - (b.resOrdinal ?? Number.MAX_SAFE_INTEGER));
|
|
171179
171770
|
}
|
|
171180
|
-
function fenceBoundaryForToolArcs(candidate, arcs, lastCompartmentEndOrdinal) {
|
|
171771
|
+
function fenceBoundaryForToolArcs(candidate, arcs, lastCompartmentEndOrdinal, recentOpenArcCutoff) {
|
|
171181
171772
|
let boundary = candidate;
|
|
171182
171773
|
for (const arc of arcs) {
|
|
171183
171774
|
if (arc.resOrdinal !== null) {
|
|
@@ -171186,6 +171777,8 @@ function fenceBoundaryForToolArcs(candidate, arcs, lastCompartmentEndOrdinal) {
|
|
|
171186
171777
|
}
|
|
171187
171778
|
continue;
|
|
171188
171779
|
}
|
|
171780
|
+
if (arc.invOrdinal < recentOpenArcCutoff)
|
|
171781
|
+
continue;
|
|
171189
171782
|
if (arc.invOrdinal >= lastCompartmentEndOrdinal + 1 && arc.invOrdinal < boundary) {
|
|
171190
171783
|
return arc.invOrdinal;
|
|
171191
171784
|
}
|
|
@@ -171423,7 +172016,7 @@ function semanticSnapBoundary(args) {
|
|
|
171423
172016
|
return snapped;
|
|
171424
172017
|
}
|
|
171425
172018
|
function applyHeadCap(args) {
|
|
171426
|
-
const { index, protectedTailStart, offset, arcs, capTokens } = args;
|
|
172019
|
+
const { index, protectedTailStart, offset, arcs, capTokens, recentOpenArcCutoff } = args;
|
|
171427
172020
|
if (offset >= protectedTailStart)
|
|
171428
172021
|
return { eligibleEndOrdinal: offset, oversizeAtomicUnit: false };
|
|
171429
172022
|
let end = index.findHeadEndForCap(offset, protectedTailStart, capTokens);
|
|
@@ -171431,7 +172024,7 @@ function applyHeadCap(args) {
|
|
|
171431
172024
|
for (const arc of arcs) {
|
|
171432
172025
|
const resOrdinal = arc.resOrdinal;
|
|
171433
172026
|
if (resOrdinal === null) {
|
|
171434
|
-
if (arc.invOrdinal >= offset && arc.invOrdinal < end) {
|
|
172027
|
+
if (arc.invOrdinal >= recentOpenArcCutoff && arc.invOrdinal >= offset && arc.invOrdinal < end) {
|
|
171435
172028
|
end = Math.min(end, arc.invOrdinal);
|
|
171436
172029
|
}
|
|
171437
172030
|
continue;
|
|
@@ -171498,7 +172091,14 @@ function resolveProtectedTailBoundary(ctx) {
|
|
|
171498
172091
|
}
|
|
171499
172092
|
if (ctx.mode === "manual-full-recomp") {
|
|
171500
172093
|
const arcs2 = buildToolArcs(messages);
|
|
171501
|
-
const
|
|
172094
|
+
const recompTarget = deriveProtectedTailTokenTarget({
|
|
172095
|
+
contextLimit: ctx.contextLimit,
|
|
172096
|
+
executeThresholdPercentage: ctx.executeThresholdPercentage,
|
|
172097
|
+
usagePercentage: 0,
|
|
172098
|
+
triggerBudget: ctx.triggerBudget
|
|
172099
|
+
});
|
|
172100
|
+
const recentOpenArcCutoff2 = index.findSuffixStartForTokens(recompTarget.N);
|
|
172101
|
+
const firstOpenArc = arcs2.find((arc) => arc.resOrdinal === null && arc.invOrdinal >= offset && arc.invOrdinal >= recentOpenArcCutoff2);
|
|
171502
172102
|
const protectedTailStart2 = firstOpenArc?.invOrdinal ?? rawMessageCount + 1;
|
|
171503
172103
|
const rawRangeFingerprint2 = computeRawRangeFingerprint(messages, offset, protectedTailStart2);
|
|
171504
172104
|
return {
|
|
@@ -171540,13 +172140,14 @@ function resolveProtectedTailBoundary(ctx) {
|
|
|
171540
172140
|
const scaledN = ctx.emergencyTailScale ? Math.max(1, Math.floor(target.N * ctx.emergencyTailScale)) : target.N;
|
|
171541
172141
|
const arcs = buildToolArcs(messages);
|
|
171542
172142
|
let boundary = index.findSuffixStartForTokens(scaledN);
|
|
172143
|
+
const recentOpenArcCutoff = boundary;
|
|
171543
172144
|
let boundaryReason = boundary === 1 ? "whole-session-smaller-than-tail" : "size-walk";
|
|
171544
172145
|
const tokenAtBoundary = index.tokenForOrdinal(boundary);
|
|
171545
172146
|
if (boundary <= rawMessageCount && tokenAtBoundary > Math.max(2 * scaledN, 64000) && boundary < rawMessageCount) {
|
|
171546
172147
|
boundary += 1;
|
|
171547
172148
|
boundaryReason = "huge-message-exception";
|
|
171548
172149
|
}
|
|
171549
|
-
boundary = fenceBoundaryForToolArcs(boundary, arcs, ctx.lastCompartmentEndOrdinal);
|
|
172150
|
+
boundary = fenceBoundaryForToolArcs(boundary, arcs, ctx.lastCompartmentEndOrdinal, recentOpenArcCutoff);
|
|
171550
172151
|
const snapped = semanticSnapBoundary({
|
|
171551
172152
|
messages,
|
|
171552
172153
|
index,
|
|
@@ -171556,7 +172157,7 @@ function resolveProtectedTailBoundary(ctx) {
|
|
|
171556
172157
|
});
|
|
171557
172158
|
if (snapped !== boundary)
|
|
171558
172159
|
boundaryReason = "semantic-snap";
|
|
171559
|
-
boundary = fenceBoundaryForToolArcs(snapped, arcs, ctx.lastCompartmentEndOrdinal);
|
|
172160
|
+
boundary = fenceBoundaryForToolArcs(snapped, arcs, ctx.lastCompartmentEndOrdinal, recentOpenArcCutoff);
|
|
171560
172161
|
let runtimeFloor = offset;
|
|
171561
172162
|
if (ctx.migrationFloorActive)
|
|
171562
172163
|
runtimeFloor = Math.max(runtimeFloor, ctx.priorBoundaryOrdinal);
|
|
@@ -171592,7 +172193,8 @@ function resolveProtectedTailBoundary(ctx) {
|
|
|
171592
172193
|
offset,
|
|
171593
172194
|
arcs,
|
|
171594
172195
|
lastCompartmentEndOrdinal: ctx.lastCompartmentEndOrdinal,
|
|
171595
|
-
capTokens: perRunCap
|
|
172196
|
+
capTokens: perRunCap,
|
|
172197
|
+
recentOpenArcCutoff
|
|
171596
172198
|
});
|
|
171597
172199
|
const rawRangeFingerprint = computeRawRangeFingerprint(messages, offset, head.eligibleEndOrdinal);
|
|
171598
172200
|
return {
|
|
@@ -171643,7 +172245,7 @@ function resolveBoundaryContext(args) {
|
|
|
171643
172245
|
}
|
|
171644
172246
|
let storedTokenTotals;
|
|
171645
172247
|
try {
|
|
171646
|
-
storedTokenTotals = getAllStatusTagTokenTotalsFlat(args.db, args.sessionId).totals;
|
|
172248
|
+
storedTokenTotals = getAllStatusTagTokenTotalsFlat(args.db, args.sessionId, args.taggerFloor ?? 0).totals;
|
|
171647
172249
|
} catch (error51) {
|
|
171648
172250
|
sessionLog(args.sessionId, "protected-tail stored-token map unavailable (live fallback):", error51);
|
|
171649
172251
|
}
|
|
@@ -171760,6 +172362,38 @@ var DEFAULT_MIN_COMMIT_CLUSTERS_FOR_TRIGGER = 3;
|
|
|
171760
172362
|
var TAIL_SIZE_TRIGGER_MULTIPLIER = 3;
|
|
171761
172363
|
var FORCE_COMPARTMENT_PERCENTAGE = 80;
|
|
171762
172364
|
var BLOCK_UNTIL_DONE_PERCENTAGE = 95;
|
|
172365
|
+
var CONTENT_TAG_OWNER_SUFFIX = /:(?:p|file)\d+$/;
|
|
172366
|
+
function tagOwnerMessageId(row) {
|
|
172367
|
+
if (row.type === "tool")
|
|
172368
|
+
return row.tool_owner_message_id ?? row.message_id;
|
|
172369
|
+
return row.message_id.replace(CONTENT_TAG_OWNER_SUFFIX, "");
|
|
172370
|
+
}
|
|
172371
|
+
function getActiveOrDroppedTagOwnerMessageIds(db, sessionId, floor = 0) {
|
|
172372
|
+
const rows = floor > 0 ? db.prepare(`SELECT type, message_id, tool_owner_message_id
|
|
172373
|
+
FROM tags
|
|
172374
|
+
WHERE session_id = ? AND status IN ('active', 'dropped') AND tag_number >= ?`).all(sessionId, floor) : db.prepare(`SELECT type, message_id, tool_owner_message_id
|
|
172375
|
+
FROM tags
|
|
172376
|
+
WHERE session_id = ? AND status IN ('active', 'dropped')`).all(sessionId);
|
|
172377
|
+
const owners = new Set;
|
|
172378
|
+
for (const row of rows)
|
|
172379
|
+
owners.add(tagOwnerMessageId(row));
|
|
172380
|
+
return owners;
|
|
172381
|
+
}
|
|
172382
|
+
function estimateUntaggedInMemoryTailUpperBound(db, sessionId, inMemoryTail, taggerFloor = 0) {
|
|
172383
|
+
const lastCompartmentEnd = getLastCompartmentEndMessage(db, sessionId);
|
|
172384
|
+
const coveredOwnerMessageIds = getActiveOrDroppedTagOwnerMessageIds(db, sessionId, taggerFloor);
|
|
172385
|
+
let total = 0;
|
|
172386
|
+
for (const message of inMemoryTail.messages) {
|
|
172387
|
+
if (message.ordinal <= lastCompartmentEnd)
|
|
172388
|
+
continue;
|
|
172389
|
+
if (coveredOwnerMessageIds.has(message.id))
|
|
172390
|
+
continue;
|
|
172391
|
+
total += estimateTrueRawMessageTokens(message, {
|
|
172392
|
+
providerShapeVersion: "opencode-v1"
|
|
172393
|
+
}).total;
|
|
172394
|
+
}
|
|
172395
|
+
return total;
|
|
172396
|
+
}
|
|
171763
172397
|
function getProactiveCompartmentTriggerPercentage(executeThresholdPercentage) {
|
|
171764
172398
|
return Math.max(0, executeThresholdPercentage - PROACTIVE_TRIGGER_OFFSET_PERCENTAGE);
|
|
171765
172399
|
}
|
|
@@ -171813,7 +172447,7 @@ function resolveBoundaryContextLimit(usage, fallbackContextLimit) {
|
|
|
171813
172447
|
}
|
|
171814
172448
|
return 128000;
|
|
171815
172449
|
}
|
|
171816
|
-
function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail) {
|
|
172450
|
+
function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail, taggerFloor = 0) {
|
|
171817
172451
|
return withRawSessionMessageCache(() => {
|
|
171818
172452
|
try {
|
|
171819
172453
|
const memoryPrimed = inMemoryTail ? primeInMemoryTailRawMessageCache({
|
|
@@ -171842,7 +172476,8 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
|
|
|
171842
172476
|
contextLimit: resolveBoundaryContextLimit(usage, contextLimit),
|
|
171843
172477
|
executeThresholdPercentage,
|
|
171844
172478
|
usage,
|
|
171845
|
-
usageSource: "live"
|
|
172479
|
+
usageSource: "live",
|
|
172480
|
+
taggerFloor
|
|
171846
172481
|
});
|
|
171847
172482
|
const hasProtectedEligibleHead = boundary.offset < boundary.protectedTailStart;
|
|
171848
172483
|
if (!hasProtectedEligibleHead) {
|
|
@@ -171873,7 +172508,7 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
|
|
|
171873
172508
|
}
|
|
171874
172509
|
});
|
|
171875
172510
|
}
|
|
171876
|
-
function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, clearReasoningAge, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail) {
|
|
172511
|
+
function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, clearReasoningAge, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail, taggerFloorOverride) {
|
|
171877
172512
|
if (sessionMeta.compartmentInProgress) {
|
|
171878
172513
|
sessionLog(sessionId, `compartment trigger: skipped — historian already in progress (usage=${usage.percentage.toFixed(1)}%)`);
|
|
171879
172514
|
return { shouldFire: false };
|
|
@@ -171887,14 +172522,17 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
171887
172522
|
inMemoryTail = undefined;
|
|
171888
172523
|
}
|
|
171889
172524
|
}
|
|
172525
|
+
const taggerFloor = taggerFloorOverride !== undefined && taggerFloorOverride > 0 ? taggerFloorOverride : inMemoryTail ? deriveTagLoadFloor(db, sessionId, inMemoryTail.messages.map((m) => m.id)) : 0;
|
|
171890
172526
|
const proactiveFloorForGate = getProactiveCompartmentTriggerPercentage(executeThresholdPercentage);
|
|
171891
|
-
if (
|
|
172527
|
+
if (usage.percentage < proactiveFloorForGate) {
|
|
171892
172528
|
try {
|
|
171893
|
-
const { bound, nullCount } = getTriggerTagTokenUpperBound(db, sessionId);
|
|
172529
|
+
const { bound: persistedBound, nullCount } = getTriggerTagTokenUpperBound(db, sessionId, taggerFloor);
|
|
171894
172530
|
if (nullCount === 0) {
|
|
171895
|
-
const
|
|
172531
|
+
const untaggedUpperBound = inMemoryTail ? estimateUntaggedInMemoryTailUpperBound(db, sessionId, inMemoryTail, taggerFloor) : 0;
|
|
172532
|
+
const eligibleUpperBound = persistedBound + untaggedUpperBound;
|
|
171896
172533
|
if (eligibleUpperBound < triggerBudget) {
|
|
171897
|
-
|
|
172534
|
+
const memorySuffix = inMemoryTail ? ` (persisted=${persistedBound}, untagged-memory≤${untaggedUpperBound})` : "";
|
|
172535
|
+
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`);
|
|
171898
172536
|
return { shouldFire: false };
|
|
171899
172537
|
}
|
|
171900
172538
|
}
|
|
@@ -171902,7 +172540,7 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
171902
172540
|
sessionLog(sessionId, `compartment trigger: cheap-gate skipped (falling through to full read): ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
171903
172541
|
}
|
|
171904
172542
|
}
|
|
171905
|
-
const tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail);
|
|
172543
|
+
const tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail, taggerFloor);
|
|
171906
172544
|
if (!tailInfo.hasNewRawHistory) {
|
|
171907
172545
|
try {
|
|
171908
172546
|
const lastCompartmentEnd = getLastCompartmentEndMessage(db, sessionId);
|
|
@@ -172066,6 +172704,13 @@ function computePressure(input) {
|
|
|
172066
172704
|
function approxThousands(tokens) {
|
|
172067
172705
|
return `${Math.round(tokens / 1000)}k`;
|
|
172068
172706
|
}
|
|
172707
|
+
function formatOldestReclaimableHint(hint) {
|
|
172708
|
+
if (!hint || hint.length === 0)
|
|
172709
|
+
return "";
|
|
172710
|
+
const rendered = hint.slice(0, 4).map((tag) => `§${tag.tagNumber}§ ${tag.toolName ?? "tool"}`).join(" · ");
|
|
172711
|
+
return rendered.length > 0 ? `
|
|
172712
|
+
oldest reclaimable: ${rendered}.` : "";
|
|
172713
|
+
}
|
|
172069
172714
|
var CHANNEL2_USABLE_FRACTION = 1 / 3;
|
|
172070
172715
|
var CHANNEL2_MIN_RECLAIMABLE = 1e4;
|
|
172071
172716
|
function shouldTriggerChannel2(input) {
|
|
@@ -172075,14 +172720,16 @@ function shouldTriggerChannel2(input) {
|
|
|
172075
172720
|
return true;
|
|
172076
172721
|
return input.reclaimableTokens >= input.usableTokens * CHANNEL2_USABLE_FRACTION;
|
|
172077
172722
|
}
|
|
172078
|
-
function buildChannel2Reminder(undroppedTokens) {
|
|
172723
|
+
function buildChannel2Reminder(undroppedTokens, hint) {
|
|
172079
172724
|
const amount = approxThousands(undroppedTokens);
|
|
172725
|
+
const hintText = formatOldestReclaimableHint(hint);
|
|
172080
172726
|
return `<system-reminder>
|
|
172081
|
-
` + `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
|
|
172727
|
+
` + `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}
|
|
172082
172728
|
` + `</system-reminder>`;
|
|
172083
172729
|
}
|
|
172084
|
-
function buildChannel1Reminder(level, undroppedTokens) {
|
|
172730
|
+
function buildChannel1Reminder(level, undroppedTokens, hint) {
|
|
172085
172731
|
const amount = approxThousands(undroppedTokens);
|
|
172732
|
+
const hintText = formatOldestReclaimableHint(hint);
|
|
172086
172733
|
let body;
|
|
172087
172734
|
switch (level) {
|
|
172088
172735
|
case "gentle":
|
|
@@ -172098,7 +172745,7 @@ function buildChannel1Reminder(level, undroppedTokens) {
|
|
|
172098
172745
|
return `
|
|
172099
172746
|
|
|
172100
172747
|
<system-reminder>
|
|
172101
|
-
${body}
|
|
172748
|
+
${body}${hintText}
|
|
172102
172749
|
</system-reminder>`;
|
|
172103
172750
|
}
|
|
172104
172751
|
|
|
@@ -172646,6 +173293,41 @@ function renderMemoryBlockV2(memories, wrapper = "project-memory", renderOptions
|
|
|
172646
173293
|
`);
|
|
172647
173294
|
}
|
|
172648
173295
|
|
|
173296
|
+
// ../plugin/src/hooks/magic-context/tool-reclaim.ts
|
|
173297
|
+
function buildSyntheticToolReclaimOps(input) {
|
|
173298
|
+
const watermark = Math.max(0, input.watermark);
|
|
173299
|
+
if (watermark <= 0)
|
|
173300
|
+
return [];
|
|
173301
|
+
const realPendingTagIds = new Set((input.pendingOps ?? []).map((op) => op.tagId));
|
|
173302
|
+
const tags = getActiveTagsBySession(input.db, input.sessionId);
|
|
173303
|
+
const synthetic = [];
|
|
173304
|
+
for (const tag of tags) {
|
|
173305
|
+
if (tag.type !== "tool")
|
|
173306
|
+
continue;
|
|
173307
|
+
if (tag.status !== "active")
|
|
173308
|
+
continue;
|
|
173309
|
+
if (tag.tagNumber > watermark)
|
|
173310
|
+
continue;
|
|
173311
|
+
if (realPendingTagIds.has(tag.tagNumber))
|
|
173312
|
+
continue;
|
|
173313
|
+
if (input.targets.get(tag.tagNumber)?.canDrop?.() !== true)
|
|
173314
|
+
continue;
|
|
173315
|
+
synthetic.push({
|
|
173316
|
+
id: 0,
|
|
173317
|
+
sessionId: input.sessionId,
|
|
173318
|
+
tagId: tag.tagNumber,
|
|
173319
|
+
operation: "drop",
|
|
173320
|
+
queuedAt: 0
|
|
173321
|
+
});
|
|
173322
|
+
}
|
|
173323
|
+
return synthetic;
|
|
173324
|
+
}
|
|
173325
|
+
function advanceToolReclaimWatermarkToCurrentMax(db, sessionId) {
|
|
173326
|
+
const maxTagNumber = getMaxTagNumberBySession(db, sessionId);
|
|
173327
|
+
advanceToolReclaimWatermark(db, sessionId, maxTagNumber);
|
|
173328
|
+
return maxTagNumber;
|
|
173329
|
+
}
|
|
173330
|
+
|
|
172649
173331
|
// src/context-handler.ts
|
|
172650
173332
|
init_logger();
|
|
172651
173333
|
|
|
@@ -173056,7 +173738,7 @@ function tagToolPart(args) {
|
|
|
173056
173738
|
const tagged = prependTag(tagId, text);
|
|
173057
173739
|
args.part.setText(tagged);
|
|
173058
173740
|
}
|
|
173059
|
-
args.targets.set(tagId, buildToolTarget(args.part, args.message));
|
|
173741
|
+
args.targets.set(tagId, buildToolTarget(args.part, args.message, tagId));
|
|
173060
173742
|
}
|
|
173061
173743
|
function setToolContentOrText(part, content) {
|
|
173062
173744
|
try {
|
|
@@ -173096,7 +173778,7 @@ function buildAggregateTarget(tagId, occurrences) {
|
|
|
173096
173778
|
return any2 ? "removed" : "absent";
|
|
173097
173779
|
},
|
|
173098
173780
|
truncate() {
|
|
173099
|
-
const sentinel =
|
|
173781
|
+
const sentinel = `[dropped §${tagId}§]`;
|
|
173100
173782
|
let any2 = false;
|
|
173101
173783
|
for (const occ of occurrences) {
|
|
173102
173784
|
if (setToolContentOrText(occ.part, sentinel)) {
|
|
@@ -173128,7 +173810,7 @@ function buildTextTarget(part, message) {
|
|
|
173128
173810
|
}
|
|
173129
173811
|
};
|
|
173130
173812
|
}
|
|
173131
|
-
function buildToolTarget(part, message) {
|
|
173813
|
+
function buildToolTarget(part, message, tagId) {
|
|
173132
173814
|
return {
|
|
173133
173815
|
setContent(content) {
|
|
173134
173816
|
return setToolContentOrText(part, content);
|
|
@@ -173137,11 +173819,11 @@ function buildToolTarget(part, message) {
|
|
|
173137
173819
|
return part.getText() ?? null;
|
|
173138
173820
|
},
|
|
173139
173821
|
drop() {
|
|
173140
|
-
const replaced = part.replaceWithSentinel(`[dropped §${
|
|
173822
|
+
const replaced = part.replaceWithSentinel(`[dropped §${tagId}§]`);
|
|
173141
173823
|
return replaced ? "removed" : "absent";
|
|
173142
173824
|
},
|
|
173143
173825
|
truncate() {
|
|
173144
|
-
const ok = setToolContentOrText(part,
|
|
173826
|
+
const ok = setToolContentOrText(part, `[dropped §${tagId}§]`);
|
|
173145
173827
|
return ok ? "truncated" : "absent";
|
|
173146
173828
|
},
|
|
173147
173829
|
message: {
|
|
@@ -174172,7 +174854,7 @@ async function runAutoSearchHintForPi(args) {
|
|
|
174172
174854
|
embeddingEnabled,
|
|
174173
174855
|
gitCommitsEnabled,
|
|
174174
174856
|
embedQuery: async (text, signal) => {
|
|
174175
|
-
const result = await embedTextForProject(options.projectPath, text, signal);
|
|
174857
|
+
const result = await embedTextForProject(options.projectPath, text, signal, "query");
|
|
174176
174858
|
return result?.vector ?? null;
|
|
174177
174859
|
},
|
|
174178
174860
|
isEmbeddingRuntimeEnabled: () => embeddingEnabled === true,
|
|
@@ -174426,9 +175108,10 @@ function maybeChannel1ReminderForToolResult(args) {
|
|
|
174426
175108
|
return null;
|
|
174427
175109
|
return {
|
|
174428
175110
|
type: "text",
|
|
174429
|
-
text: buildChannel1Reminder(decision.level, decision.undroppedTokens)
|
|
175111
|
+
text: buildChannel1Reminder(decision.level, decision.undroppedTokens, state.oldestReclaimableToolTags)
|
|
174430
175112
|
};
|
|
174431
175113
|
}
|
|
175114
|
+
var CHANNEL2_NUDGE_CUSTOM_TYPE = "magic-context:ceiling-nudge";
|
|
174432
175115
|
function maybeDeliverChannel2Pi(pi, db, sessionId, deliverAs = "followUp") {
|
|
174433
175116
|
let state;
|
|
174434
175117
|
try {
|
|
@@ -174456,9 +175139,12 @@ function maybeDeliverChannel2Pi(pi, db, sessionId, deliverAs = "followUp") {
|
|
|
174456
175139
|
if (!casChannel2NudgeState(db, sessionId, "pending", "claimed"))
|
|
174457
175140
|
return false;
|
|
174458
175141
|
try {
|
|
174459
|
-
pi.
|
|
174460
|
-
|
|
174461
|
-
|
|
175142
|
+
pi.sendMessage({
|
|
175143
|
+
customType: CHANNEL2_NUDGE_CUSTOM_TYPE,
|
|
175144
|
+
content: buildChannel2Reminder(undropped, baseline.oldestReclaimableToolTags),
|
|
175145
|
+
display: false,
|
|
175146
|
+
details: { kind: "channel-2-ceiling-nudge" }
|
|
175147
|
+
}, { deliverAs });
|
|
174462
175148
|
} catch (error51) {
|
|
174463
175149
|
try {
|
|
174464
175150
|
casChannel2NudgeState(db, sessionId, "claimed", "pending");
|
|
@@ -174650,6 +175336,51 @@ function planEmergencyDrop(input) {
|
|
|
174650
175336
|
};
|
|
174651
175337
|
}
|
|
174652
175338
|
|
|
175339
|
+
// ../plugin/src/hooks/magic-context/system-injection-stripper.ts
|
|
175340
|
+
var SYSTEM_INJECTION_MARKERS = [
|
|
175341
|
+
"<!-- OMO_INTERNAL_INITIATOR -->",
|
|
175342
|
+
"[SYSTEM DIRECTIVE: MAGIC-CONTEXT",
|
|
175343
|
+
"[SYSTEM DIRECTIVE: OH-MY-OPENCODE",
|
|
175344
|
+
"[Category+Skill Reminder]",
|
|
175345
|
+
"[EDIT ERROR - IMMEDIATE ACTION REQUIRED]",
|
|
175346
|
+
"[task CALL FAILED - IMMEDIATE RETRY REQUIRED]",
|
|
175347
|
+
"[EMERGENCY CONTEXT WINDOW WARNING]",
|
|
175348
|
+
"Unstable background agent appears idle",
|
|
175349
|
+
"**THE SUBAGENT JUST CLAIMED THIS TASK IS DONE."
|
|
175350
|
+
];
|
|
175351
|
+
var SYSTEM_REMINDER_REGEX = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
|
|
175352
|
+
var OMO_MARKER_REGEX = /<!-- OMO_INTERNAL_INITIATOR -->/g;
|
|
175353
|
+
function stripSystemInjection(text) {
|
|
175354
|
+
let hasInjection = false;
|
|
175355
|
+
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
175356
|
+
if (text.includes(marker)) {
|
|
175357
|
+
hasInjection = true;
|
|
175358
|
+
break;
|
|
175359
|
+
}
|
|
175360
|
+
}
|
|
175361
|
+
if (SYSTEM_REMINDER_REGEX.test(text))
|
|
175362
|
+
hasInjection = true;
|
|
175363
|
+
SYSTEM_REMINDER_REGEX.lastIndex = 0;
|
|
175364
|
+
if (!hasInjection)
|
|
175365
|
+
return null;
|
|
175366
|
+
let cleaned = text;
|
|
175367
|
+
cleaned = cleaned.replace(SYSTEM_REMINDER_REGEX, "");
|
|
175368
|
+
cleaned = cleaned.replace(OMO_MARKER_REGEX, "");
|
|
175369
|
+
cleaned = cleaned.replace(/\[SYSTEM DIRECTIVE: OH-MY-(?:OPENCODE|CLAUDE)[^\]]*\][\s\S]*?(?=\n\n(?!\s*[-*])|$)/g, "");
|
|
175370
|
+
for (const marker of SYSTEM_INJECTION_MARKERS) {
|
|
175371
|
+
if (marker.startsWith("<!-- ") || marker.startsWith("[SYSTEM DIRECTIVE"))
|
|
175372
|
+
continue;
|
|
175373
|
+
const idx = cleaned.indexOf(marker);
|
|
175374
|
+
if (idx === -1)
|
|
175375
|
+
continue;
|
|
175376
|
+
const blockEnd = cleaned.indexOf(`
|
|
175377
|
+
|
|
175378
|
+
`, idx + marker.length);
|
|
175379
|
+
cleaned = blockEnd !== -1 ? cleaned.slice(0, idx) + cleaned.slice(blockEnd) : cleaned.slice(0, idx);
|
|
175380
|
+
}
|
|
175381
|
+
return cleaned.trim();
|
|
175382
|
+
}
|
|
175383
|
+
|
|
174653
175384
|
// src/heuristic-cleanup-pi.ts
|
|
174654
175385
|
init_logger();
|
|
174655
175386
|
var DEDUP_SAFE_TOOLS = new Set([
|
|
@@ -174753,6 +175484,7 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config2, pr
|
|
|
174753
175484
|
const protectedCutoff = maxTag - config2.protectedTags;
|
|
174754
175485
|
const toolAgeCutoff = protectedCutoff;
|
|
174755
175486
|
let droppedTools = 0;
|
|
175487
|
+
let emergencyDroppedTools = 0;
|
|
174756
175488
|
let deduplicatedTools = 0;
|
|
174757
175489
|
let droppedInjections = 0;
|
|
174758
175490
|
let droppedStaleReduceCalls = 0;
|
|
@@ -174785,6 +175517,7 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config2, pr
|
|
|
174785
175517
|
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
174786
175518
|
updateTagDropMode(db, sessionId, tag.tagNumber, "full");
|
|
174787
175519
|
droppedTools++;
|
|
175520
|
+
emergencyDroppedTools++;
|
|
174788
175521
|
}
|
|
174789
175522
|
}
|
|
174790
175523
|
setEmergencyDropSample(db, sessionId, emergency.currentTotalInputTokens);
|
|
@@ -174808,10 +175541,14 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config2, pr
|
|
|
174808
175541
|
if (!matched)
|
|
174809
175542
|
continue;
|
|
174810
175543
|
const target = targets.get(tag.tagNumber);
|
|
174811
|
-
target?.drop?.();
|
|
175544
|
+
const result = target?.drop?.() ?? "absent";
|
|
175545
|
+
if (result === "incomplete")
|
|
175546
|
+
continue;
|
|
174812
175547
|
updateTagDropMode(db, sessionId, tag.tagNumber, "full");
|
|
174813
175548
|
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
174814
|
-
|
|
175549
|
+
if (result === "removed" || result === "truncated") {
|
|
175550
|
+
droppedStaleReduceCalls++;
|
|
175551
|
+
}
|
|
174815
175552
|
}
|
|
174816
175553
|
})();
|
|
174817
175554
|
}
|
|
@@ -174883,7 +175620,9 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config2, pr
|
|
|
174883
175620
|
continue;
|
|
174884
175621
|
updateTagDropMode(db, sessionId, tag.tagNumber, "full");
|
|
174885
175622
|
updateTagStatus(db, sessionId, tag.tagNumber, "dropped");
|
|
174886
|
-
|
|
175623
|
+
if (result === "removed" || result === "truncated") {
|
|
175624
|
+
deduplicatedTools++;
|
|
175625
|
+
}
|
|
174887
175626
|
}
|
|
174888
175627
|
}
|
|
174889
175628
|
})();
|
|
@@ -174892,6 +175631,7 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config2, pr
|
|
|
174892
175631
|
sessionLog(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, stale ctx_reduce=${droppedStaleReduceCalls}, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
|
|
174893
175632
|
}
|
|
174894
175633
|
let compressedTextTags = 0;
|
|
175634
|
+
let mutatedTextTags = 0;
|
|
174895
175635
|
if (config2.caveman?.enabled) {
|
|
174896
175636
|
const cavemanResult = applyCavemanCleanup(sessionId, db, targets, tags, {
|
|
174897
175637
|
enabled: true,
|
|
@@ -174899,13 +175639,16 @@ function applyPiHeuristicCleanup(sessionId, db, targets, piMessages, config2, pr
|
|
|
174899
175639
|
protectedTags: config2.protectedTags
|
|
174900
175640
|
});
|
|
174901
175641
|
compressedTextTags = cavemanResult.compressedToLite + cavemanResult.compressedToFull + cavemanResult.compressedToUltra;
|
|
175642
|
+
mutatedTextTags = cavemanResult.mutatedTextTags;
|
|
174902
175643
|
}
|
|
174903
175644
|
return {
|
|
174904
175645
|
droppedTools,
|
|
174905
175646
|
deduplicatedTools,
|
|
174906
175647
|
droppedInjections,
|
|
174907
175648
|
droppedStaleReduceCalls,
|
|
174908
|
-
|
|
175649
|
+
emergencyDroppedTools,
|
|
175650
|
+
compressedTextTags,
|
|
175651
|
+
mutatedTextTags
|
|
174909
175652
|
};
|
|
174910
175653
|
}
|
|
174911
175654
|
function buildMessageIdToMaxTagFromTargets(targets) {
|
|
@@ -176201,7 +176944,7 @@ async function embedAndStoreCompartmentChunks(db, sessionId, projectPath, compar
|
|
|
176201
176944
|
for (const compartment of compartments) {
|
|
176202
176945
|
try {
|
|
176203
176946
|
const fromMemory = compartment.sourceChunkText ? canonicalizeInMemoryChunkTextForEmbedding(compartment.sourceChunkText, compartment.startMessage, compartment.endMessage) : "";
|
|
176204
|
-
const canonicalText = fromMemory || buildCanonicalChunkTextFromFts(db, sessionId, compartment.startMessage, compartment.endMessage);
|
|
176947
|
+
const canonicalText = fromMemory || buildCanonicalChunkTextFromFts(db, sessionId, compartment.startMessage, compartment.endMessage) || buildCompartmentSummaryFallbackText(db, compartment.id);
|
|
176205
176948
|
if (canonicalText.length === 0)
|
|
176206
176949
|
continue;
|
|
176207
176950
|
const windows = chunkCanonicalText(canonicalText, compartment.startMessage, compartment.endMessage, maxInputTokens);
|
|
@@ -179394,6 +180137,7 @@ async function runPiHistorian(deps) {
|
|
|
179394
180137
|
} else {
|
|
179395
180138
|
recordHighPressureNoEligibleHead(db, boundarySnapshot);
|
|
179396
180139
|
}
|
|
180140
|
+
clearEmergencyDrainLatch(db, sessionId);
|
|
179397
180141
|
return;
|
|
179398
180142
|
}
|
|
179399
180143
|
const perRunCap = selectPerRunCap(boundarySnapshot);
|
|
@@ -179405,7 +180149,8 @@ async function runPiHistorian(deps) {
|
|
|
179405
180149
|
trueRawTokens: boundarySnapshot.trueRawEligibleTokens,
|
|
179406
180150
|
usagePercentage: boundarySnapshot.usagePercentage,
|
|
179407
180151
|
usable,
|
|
179408
|
-
perRunCap
|
|
180152
|
+
perRunCap,
|
|
180153
|
+
executeThresholdPercentage: boundarySnapshot.executeThresholdPercentage
|
|
179409
180154
|
});
|
|
179410
180155
|
if (!reserve.ok) {
|
|
179411
180156
|
sessionLog(sessionId, `historian rate-limit skip: ${reserve.skippedReason ?? "quota exhausted"}`);
|
|
@@ -179422,6 +180167,7 @@ async function runPiHistorian(deps) {
|
|
|
179422
180167
|
} else {
|
|
179423
180168
|
recordHighPressureNoEligibleHead(db, boundarySnapshot);
|
|
179424
180169
|
}
|
|
180170
|
+
clearEmergencyDrainLatch(db, sessionId);
|
|
179425
180171
|
telemetry.status = "noop";
|
|
179426
180172
|
telemetry.failureReason = "chunk empty after filtering";
|
|
179427
180173
|
rollbackDrainReservation();
|
|
@@ -179653,6 +180399,7 @@ ${chunkText}`,
|
|
|
179653
180399
|
}
|
|
179654
180400
|
appendCompartments(db, sessionId, newCompartments);
|
|
179655
180401
|
clearHistorianFailureState(db, sessionId);
|
|
180402
|
+
clearHistorianDrainFailure(db, sessionId);
|
|
179656
180403
|
recordProtectedTailPublicationFloor(db, sessionId, lastNewEnd + 1);
|
|
179657
180404
|
clearEmergencyRecovery(db, sessionId);
|
|
179658
180405
|
if (firstKeptEntryId && lastNewEndMessageId) {
|
|
@@ -179749,8 +180496,12 @@ ${chunkText}`,
|
|
|
179749
180496
|
await notify(buildHistorianFailureNotice(failCount, desc.brief));
|
|
179750
180497
|
}
|
|
179751
180498
|
} finally {
|
|
179752
|
-
if (!completedSuccessfully
|
|
179753
|
-
|
|
180499
|
+
if (!completedSuccessfully) {
|
|
180500
|
+
if (!retainDrainReservationForRetryThrottle) {
|
|
180501
|
+
rollbackDrainReservation();
|
|
180502
|
+
} else {
|
|
180503
|
+
recordHistorianDrainFailure(db, sessionId);
|
|
180504
|
+
}
|
|
179754
180505
|
}
|
|
179755
180506
|
updateSessionMeta(db, sessionId, { compartmentInProgress: false });
|
|
179756
180507
|
try {
|
|
@@ -179989,7 +180740,7 @@ var INLINE_THINKING_PATTERNS = [
|
|
|
179989
180740
|
/<thinking>[\s\S]*?<\/thinking>\s*/gi,
|
|
179990
180741
|
/<think>[\s\S]*?<\/think>\s*/gi
|
|
179991
180742
|
];
|
|
179992
|
-
var CLEARED = "
|
|
180743
|
+
var CLEARED = "";
|
|
179993
180744
|
function stripInlineThinkingMarkup(text) {
|
|
179994
180745
|
let cleaned = text;
|
|
179995
180746
|
for (const pattern of INLINE_THINKING_PATTERNS) {
|
|
@@ -180038,8 +180789,11 @@ function clearOldReasoningPi(args) {
|
|
|
180038
180789
|
for (const part of msg.content) {
|
|
180039
180790
|
if (part && typeof part === "object" && part.type === "thinking") {
|
|
180040
180791
|
const tp = part;
|
|
180041
|
-
if (tp.
|
|
180792
|
+
if (tp.redacted)
|
|
180793
|
+
continue;
|
|
180794
|
+
if (tp.thinking !== CLEARED || tp.thinkingSignature !== undefined) {
|
|
180042
180795
|
tp.thinking = CLEARED;
|
|
180796
|
+
tp.thinkingSignature = undefined;
|
|
180043
180797
|
cleared++;
|
|
180044
180798
|
}
|
|
180045
180799
|
}
|
|
@@ -180117,8 +180871,11 @@ function replayClearedReasoningPi(args) {
|
|
|
180117
180871
|
for (const part of msg.content) {
|
|
180118
180872
|
if (part && typeof part === "object" && part.type === "thinking") {
|
|
180119
180873
|
const tp = part;
|
|
180120
|
-
if (tp.
|
|
180874
|
+
if (tp.redacted)
|
|
180875
|
+
continue;
|
|
180876
|
+
if (tp.thinking !== CLEARED || tp.thinkingSignature !== undefined) {
|
|
180121
180877
|
tp.thinking = CLEARED;
|
|
180878
|
+
tp.thinkingSignature = undefined;
|
|
180122
180879
|
cleared++;
|
|
180123
180880
|
}
|
|
180124
180881
|
}
|
|
@@ -180282,9 +181039,7 @@ Context is managed for you entirely automatically — there's nothing to prune a
|
|
|
180282
181039
|
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).`;
|
|
180283
181040
|
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.`;
|
|
180284
181041
|
var BASE_INTRO = (protectedTags) => `Messages and tool outputs are tagged with §N§ identifiers (e.g., §1§, §42§).
|
|
180285
|
-
Use \`ctx_reduce\` to
|
|
180286
|
-
- \`drop\`: Remove entirely (best for tool outputs you already acted on).
|
|
180287
|
-
Syntax: "3-5", "1,2,9", or "1-5,8,12-15". Last ${protectedTags} tags are protected.
|
|
181042
|
+
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".
|
|
180288
181043
|
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.
|
|
180289
181044
|
${CTX_NOTE_GUIDANCE}
|
|
180290
181045
|
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.
|
|
@@ -180303,7 +181058,7 @@ Use \`ctx_expand\` to recover the raw conversation behind a \`<compartment>\` su
|
|
|
180303
181058
|
\`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.
|
|
180304
181059
|
${TOOL_HISTORY_GUIDANCE}
|
|
180305
181060
|
NEVER drop large ranges blindly (e.g., "1-50"). Review each tag before deciding.
|
|
180306
|
-
|
|
181061
|
+
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\`.
|
|
180307
181062
|
NEVER drop assistant text messages unless they are exceptionally large. Your conversation messages are lightweight; only large tool outputs are worth dropping.
|
|
180308
181063
|
Before your turn finishes, consider using \`ctx_reduce\` to drop large tool outputs you no longer need.`;
|
|
180309
181064
|
var BASE_INTRO_NO_REDUCE = () => `${CTX_NOTE_GUIDANCE}
|
|
@@ -181435,6 +182190,11 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
181435
182190
|
updateSessionProjectTracking(sessionId, projectIdentity, options.db);
|
|
181436
182191
|
logTransformTiming(sessionId, "findSessionId", tFindSession, `messages=${event.messages.length}`);
|
|
181437
182192
|
const branchEntries = readPiBranchEntriesForContext(ctx, sessionId);
|
|
182193
|
+
schedulePiTransformDecisionResolve({
|
|
182194
|
+
db: options.db,
|
|
182195
|
+
sessionId,
|
|
182196
|
+
branchEntries
|
|
182197
|
+
});
|
|
181438
182198
|
const rawMessageProvider = {
|
|
181439
182199
|
readMessages: () => branchEntries !== null ? convertEntriesToRawMessages([...branchEntries]) : readPiSessionMessages(ctx),
|
|
181440
182200
|
readMessageById: (messageId) => readPiSessionMessageById(ctx, messageId)
|
|
@@ -181671,6 +182431,20 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
181671
182431
|
appendCompaction: resolvePiAppendCompaction(ctx),
|
|
181672
182432
|
readBranchEntries: resolvePiReadBranchEntries(ctx)
|
|
181673
182433
|
});
|
|
182434
|
+
const piDecisionSnapshotNewestAssistant = branchEntries === null ? undefined : findNewestPiAssistantEntryId(branchEntries);
|
|
182435
|
+
if (result.bustedThisPass && piDecisionSnapshotNewestAssistant !== undefined) {
|
|
182436
|
+
recordPendingPiTransformDecision(sessionId, {
|
|
182437
|
+
tsMs: Date.now(),
|
|
182438
|
+
decision: schedulerDecision,
|
|
182439
|
+
materialized: result.materialized,
|
|
182440
|
+
materializeReason: normalizeMaterializeReason("pi", result.materializeReason, result.materialized),
|
|
182441
|
+
emergency: result.emergency,
|
|
182442
|
+
droppedTokens: result.droppedTokens,
|
|
182443
|
+
droppedCount: result.droppedCount,
|
|
182444
|
+
inputTokens: usageInputTokens,
|
|
182445
|
+
bustedThisPass: true
|
|
182446
|
+
}, piDecisionSnapshotNewestAssistant);
|
|
182447
|
+
}
|
|
181674
182448
|
if (options.historian) {
|
|
181675
182449
|
maybeFireHistorian({
|
|
181676
182450
|
ctx,
|
|
@@ -181780,6 +182554,7 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
181780
182554
|
const executeThresholdTokensPi = Math.round((usageContextLimit ?? 0) * resolvedExecuteThresholdPct / 100);
|
|
181781
182555
|
const usableTokensPi = Math.max(0, executeThresholdTokensPi - usageInputTokens + liveTailTokens);
|
|
181782
182556
|
resetLastNudgeCycleIfTailShrank(options.db, sessionId, tailToolTokens);
|
|
182557
|
+
const oldestReclaimableToolTags = getOldestActiveUnprotectedToolTags(options.db, sessionId, options.protectedTags ?? 20);
|
|
181783
182558
|
setPiChannel1Baseline(sessionId, {
|
|
181784
182559
|
tailToolTokens,
|
|
181785
182560
|
historyBudgetTokens: historyBudgetTokens ?? 0,
|
|
@@ -181788,7 +182563,8 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
181788
182563
|
lastInputTokens: usageInputTokens,
|
|
181789
182564
|
turnToolTokens: 0,
|
|
181790
182565
|
usableTokens: usableTokensPi,
|
|
181791
|
-
reducedSinceRefresh: false
|
|
182566
|
+
reducedSinceRefresh: false,
|
|
182567
|
+
oldestReclaimableToolTags
|
|
181792
182568
|
});
|
|
181793
182569
|
if (usageContextLimit && usageContextLimit > 0 && resolvedExecuteThresholdPct > 0) {
|
|
181794
182570
|
const channel2ShouldTrigger = shouldTriggerChannel2({
|
|
@@ -181816,6 +182592,7 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
181816
182592
|
logTransformTiming(sessionId, "postTransformPhase", tPostTransform);
|
|
181817
182593
|
sessionLog(sessionId, `transform completed in ${(performance.now() - transformStartTime).toFixed(1)}ms (${outputMessages.length} messages, ${result.targetCount} targets, watermark: ${result.reasoningWatermark})`);
|
|
181818
182594
|
clearLastTransformErrorIfSet(options.db, sessionId);
|
|
182595
|
+
options.maybeAutoEmbedSession?.(sessionId, projectDirectory, projectIdentity);
|
|
181819
182596
|
return { messages: outputMessages };
|
|
181820
182597
|
} catch (err) {
|
|
181821
182598
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -182162,6 +182939,13 @@ async function runPipeline(args) {
|
|
|
182162
182939
|
let historyWasConsumedThisPass = false;
|
|
182163
182940
|
let materializationSatisfiedThisPass = false;
|
|
182164
182941
|
let pendingOpsAppliedThisPass = false;
|
|
182942
|
+
let pendingOpsDidMutate = false;
|
|
182943
|
+
let heuristicOrReasoningDidMutate = false;
|
|
182944
|
+
let didMutateFromFlushedStatuses = false;
|
|
182945
|
+
let droppedCount = 0;
|
|
182946
|
+
const droppedTokens = 0;
|
|
182947
|
+
let emergency = false;
|
|
182948
|
+
let autoReclaimDidMutateThisPass = false;
|
|
182165
182949
|
let suppressDeferredHistoryDrain = false;
|
|
182166
182950
|
let casLost = false;
|
|
182167
182951
|
const deferredHistoryWasPendingAtPassStart = deferredHistoryRefreshSessions.has(args.sessionId);
|
|
@@ -182247,7 +183031,10 @@ async function runPipeline(args) {
|
|
|
182247
183031
|
sessionLog(args.sessionId, `pending ops WILL APPLY — reason=${applyReason}, pendingOps=${pendingOps.length}, context=${args.contextUsage.percentage.toFixed(1)}%`);
|
|
182248
183032
|
try {
|
|
182249
183033
|
const tApplyPending = performance.now();
|
|
182250
|
-
applyPendingOperations(args.sessionId, args.db, targets, args.protectedTags, undefined, pendingOps);
|
|
183034
|
+
pendingOpsDidMutate = applyPendingOperations(args.sessionId, args.db, targets, args.protectedTags, undefined, pendingOps);
|
|
183035
|
+
if (pendingOpsDidMutate) {
|
|
183036
|
+
droppedCount += pendingOps.length;
|
|
183037
|
+
}
|
|
182251
183038
|
logTransformTiming(args.sessionId, "applyPendingOperations", tApplyPending);
|
|
182252
183039
|
executedWorkThisPass = true;
|
|
182253
183040
|
materializationSatisfiedThisPass = true;
|
|
@@ -182269,7 +183056,7 @@ async function runPipeline(args) {
|
|
|
182269
183056
|
const flushedSliceTags = getTagsByNumbers(args.db, args.sessionId, targetTagNumbers);
|
|
182270
183057
|
logTransformTiming(args.sessionId, "getTagsByNumbers", tGetTags, `targets=${targetTagNumbers.length} fetched=${flushedSliceTags.length}`);
|
|
182271
183058
|
const tFlushed = performance.now();
|
|
182272
|
-
applyFlushedStatuses(args.sessionId, args.db, targets, flushedSliceTags);
|
|
183059
|
+
didMutateFromFlushedStatuses = applyFlushedStatuses(args.sessionId, args.db, targets, flushedSliceTags);
|
|
182273
183060
|
logTransformTiming(args.sessionId, "applyFlushedStatuses", tFlushed);
|
|
182274
183061
|
logTransformTiming(args.sessionId, "batchFinalize:flushed", tFlushed);
|
|
182275
183062
|
const messageIdToMaxTag = buildMessageIdToMaxTag(targets);
|
|
@@ -182331,6 +183118,11 @@ async function runPipeline(args) {
|
|
|
182331
183118
|
} : undefined,
|
|
182332
183119
|
caveman: args.heuristics.caveman
|
|
182333
183120
|
}, activeTags, stableIdResolver);
|
|
183121
|
+
const heuristicMutationCount = heuristicsResult.droppedTools + heuristicsResult.deduplicatedTools + heuristicsResult.droppedInjections + heuristicsResult.droppedStaleReduceCalls + heuristicsResult.mutatedTextTags;
|
|
183122
|
+
droppedCount += heuristicsResult.droppedTools + heuristicsResult.deduplicatedTools + heuristicsResult.droppedInjections + heuristicsResult.droppedStaleReduceCalls + heuristicsResult.mutatedTextTags;
|
|
183123
|
+
emergency ||= heuristicsResult.emergencyDroppedTools > 0;
|
|
183124
|
+
if (heuristicMutationCount > 0)
|
|
183125
|
+
heuristicOrReasoningDidMutate = true;
|
|
182334
183126
|
heuristicsExecuted = true;
|
|
182335
183127
|
executedWorkThisPass = true;
|
|
182336
183128
|
if (hasPendingMaterializeSignal) {
|
|
@@ -182339,7 +183131,7 @@ async function runPipeline(args) {
|
|
|
182339
183131
|
if (currentTurnId !== null) {
|
|
182340
183132
|
lastHeuristicsTurnIdBySession.set(args.sessionId, currentTurnId);
|
|
182341
183133
|
}
|
|
182342
|
-
logTransformTiming(args.sessionId, "applyHeuristicCleanup", tHeuristic, `droppedTools=${heuristicsResult.droppedTools} deduplicatedTools=${heuristicsResult.deduplicatedTools} droppedInjections=${heuristicsResult.droppedInjections} compressedTextTags=${heuristicsResult.compressedTextTags}`);
|
|
183134
|
+
logTransformTiming(args.sessionId, "applyHeuristicCleanup", tHeuristic, `droppedTools=${heuristicsResult.droppedTools} deduplicatedTools=${heuristicsResult.deduplicatedTools} droppedInjections=${heuristicsResult.droppedInjections} staleReduce=${heuristicsResult.droppedStaleReduceCalls} compressedTextTags=${heuristicsResult.compressedTextTags} mutatedTextTags=${heuristicsResult.mutatedTextTags}`);
|
|
182343
183135
|
} catch (err) {
|
|
182344
183136
|
sessionLog(args.sessionId, `heuristic cleanup failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
182345
183137
|
}
|
|
@@ -182376,6 +183168,10 @@ async function runPipeline(args) {
|
|
|
182376
183168
|
}
|
|
182377
183169
|
logTransformTiming(args.sessionId, "clearOldReasoning", tClearReasoning);
|
|
182378
183170
|
logTransformTiming(args.sessionId, "watermarkCleanup", tClearReasoning);
|
|
183171
|
+
if (clearOutcome.cleared > 0 || stripOutcome.stripped > 0) {
|
|
183172
|
+
heuristicOrReasoningDidMutate = true;
|
|
183173
|
+
droppedCount += clearOutcome.cleared + stripOutcome.stripped;
|
|
183174
|
+
}
|
|
182379
183175
|
if (combinedWatermark > prevWatermark || clearOutcome.cleared > 0 || stripOutcome.stripped > 0) {
|
|
182380
183176
|
executedWorkThisPass = true;
|
|
182381
183177
|
}
|
|
@@ -182383,7 +183179,36 @@ async function runPipeline(args) {
|
|
|
182383
183179
|
sessionLog(args.sessionId, `reasoning clearing failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
182384
183180
|
}
|
|
182385
183181
|
}
|
|
183182
|
+
const toolReclaimExecutePass = args.schedulerDecision === "execute";
|
|
183183
|
+
const alreadyMutatingThisPass = pendingOpsDidMutate || heuristicOrReasoningDidMutate;
|
|
183184
|
+
const emergencyDropEligible = args.forceMaterialization === true || args.contextUsage.percentage >= FORCE_MATERIALIZATION_PERCENTAGE;
|
|
183185
|
+
let autoReclaimTargetCount = 0;
|
|
183186
|
+
let autoReclaimDidMutate = false;
|
|
183187
|
+
if (toolReclaimExecutePass && alreadyMutatingThisPass && !emergencyDropEligible) {
|
|
183188
|
+
const reclaimMeta = getOrCreateSessionMeta(args.db, args.sessionId);
|
|
183189
|
+
const syntheticPendingOps = buildSyntheticToolReclaimOps({
|
|
183190
|
+
db: args.db,
|
|
183191
|
+
sessionId: args.sessionId,
|
|
183192
|
+
targets,
|
|
183193
|
+
watermark: reclaimMeta.toolReclaimWatermark ?? 0,
|
|
183194
|
+
pendingOps
|
|
183195
|
+
});
|
|
183196
|
+
autoReclaimTargetCount = syntheticPendingOps.length;
|
|
183197
|
+
if (syntheticPendingOps.length > 0) {
|
|
183198
|
+
autoReclaimDidMutate = applyPendingOperations(args.sessionId, args.db, targets, args.protectedTags, undefined, [], syntheticPendingOps);
|
|
183199
|
+
if (autoReclaimDidMutate) {
|
|
183200
|
+
droppedCount += syntheticPendingOps.length;
|
|
183201
|
+
autoReclaimDidMutateThisPass = true;
|
|
183202
|
+
}
|
|
183203
|
+
}
|
|
183204
|
+
}
|
|
182386
183205
|
transcript.commit();
|
|
183206
|
+
if (toolReclaimExecutePass) {
|
|
183207
|
+
advanceToolReclaimWatermarkToCurrentMax(args.db, args.sessionId);
|
|
183208
|
+
}
|
|
183209
|
+
if (autoReclaimTargetCount > 0) {
|
|
183210
|
+
sessionLog(args.sessionId, `tool reclaim auto-drop: targets=${autoReclaimTargetCount} mutated=${autoReclaimDidMutate}`);
|
|
183211
|
+
}
|
|
182387
183212
|
const postCommitStableIdByRef = new Map;
|
|
182388
183213
|
const postCommitEntryIdByRef = new Map;
|
|
182389
183214
|
for (let i = 0;i < args.messages.length; i++) {
|
|
@@ -182483,6 +183308,9 @@ async function runPipeline(args) {
|
|
|
182483
183308
|
} catch (err) {
|
|
182484
183309
|
sessionLog(args.sessionId, `token accounting failed (continuing): ${err instanceof Error ? err.message : String(err)}`);
|
|
182485
183310
|
}
|
|
183311
|
+
const materialized = injectionResult?.m0Materialized === true;
|
|
183312
|
+
const materializeReason = injectionResult?.m0Reason ?? null;
|
|
183313
|
+
const bustedThisPass = didMutateFromFlushedStatuses || pendingOpsDidMutate || heuristicOrReasoningDidMutate || autoReclaimDidMutateThisPass || materialized || historyWasConsumedThisPass;
|
|
182486
183314
|
return {
|
|
182487
183315
|
messages: outputMessages,
|
|
182488
183316
|
heuristicsExecuted,
|
|
@@ -182491,6 +183319,12 @@ async function runPipeline(args) {
|
|
|
182491
183319
|
syntheticLeadingCount: injectionResult?.syntheticLeadingCount ?? 0,
|
|
182492
183320
|
heuristicsResult,
|
|
182493
183321
|
injectionResult,
|
|
183322
|
+
materialized,
|
|
183323
|
+
materializeReason,
|
|
183324
|
+
droppedTokens,
|
|
183325
|
+
droppedCount,
|
|
183326
|
+
emergency,
|
|
183327
|
+
bustedThisPass,
|
|
182494
183328
|
targetCount: targets.size,
|
|
182495
183329
|
reasoningWatermark: getOrCreateSessionMeta(args.db, args.sessionId).clearedReasoningThroughTag ?? 0,
|
|
182496
183330
|
activeTags,
|
|
@@ -182667,6 +183501,7 @@ function clearContextHandlerSession(sessionId) {
|
|
|
182667
183501
|
rawMessageProviderUnregistersBySession.delete(sessionId);
|
|
182668
183502
|
}
|
|
182669
183503
|
clearSessionTracking(sessionId);
|
|
183504
|
+
clearPiEmbedSessionState(sessionId);
|
|
182670
183505
|
}
|
|
182671
183506
|
|
|
182672
183507
|
// src/commands/ctx-flush.ts
|
|
@@ -182916,6 +183751,12 @@ function updateCompactionMarkerAfterPublication(db, sessionId, lastCompartmentEn
|
|
|
182916
183751
|
// ../plugin/src/hooks/magic-context/compartment-runner-historian.ts
|
|
182917
183752
|
import { mkdirSync as mkdirSync7, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
182918
183753
|
import { join as join16 } from "node:path";
|
|
183754
|
+
|
|
183755
|
+
// ../plugin/src/agents/historian.ts
|
|
183756
|
+
var HISTORIAN_AGENT = "historian";
|
|
183757
|
+
var HISTORIAN_EDITOR_AGENT = "historian-editor";
|
|
183758
|
+
|
|
183759
|
+
// ../plugin/src/hooks/magic-context/compartment-runner-historian.ts
|
|
182919
183760
|
init_data_path();
|
|
182920
183761
|
function historianResponseDumpDir(directory) {
|
|
182921
183762
|
return getProjectMagicContextHistorianDir(directory);
|
|
@@ -185169,7 +186010,7 @@ function formatThresholdPercent(value) {
|
|
|
185169
186010
|
// package.json
|
|
185170
186011
|
var package_default = {
|
|
185171
186012
|
name: "@cortexkit/pi-magic-context",
|
|
185172
|
-
version: "0.
|
|
186013
|
+
version: "0.26.0",
|
|
185173
186014
|
type: "module",
|
|
185174
186015
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
185175
186016
|
main: "dist/index.js",
|
|
@@ -185782,9 +186623,184 @@ Older parts of this session are summarized into <compartment> blocks inside <ses
|
|
|
185782
186623
|
|
|
185783
186624
|
ctx_expand(start=120, end=245) ← the compartment's own start/end attributes
|
|
185784
186625
|
|
|
185785
|
-
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
|
|
186626
|
+
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.
|
|
186627
|
+
|
|
186628
|
+
Two recovery modes for finer detail:
|
|
186629
|
+
- 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.
|
|
186630
|
+
- 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.`;
|
|
185786
186631
|
var CTX_EXPAND_TOKEN_BUDGET = 15000;
|
|
185787
186632
|
|
|
186633
|
+
// ../plugin/src/tools/ctx-expand/render.ts
|
|
186634
|
+
function isRecord3(value) {
|
|
186635
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
186636
|
+
}
|
|
186637
|
+
function roleLabel(role) {
|
|
186638
|
+
if (role === "assistant")
|
|
186639
|
+
return "A (assistant)";
|
|
186640
|
+
if (role === "user")
|
|
186641
|
+
return "U (user)";
|
|
186642
|
+
return role;
|
|
186643
|
+
}
|
|
186644
|
+
function truncate2(value, max) {
|
|
186645
|
+
const t = value.trim();
|
|
186646
|
+
return t.length <= max ? t : `${t.slice(0, max)}…`;
|
|
186647
|
+
}
|
|
186648
|
+
function keyArg(input) {
|
|
186649
|
+
if (!input)
|
|
186650
|
+
return "";
|
|
186651
|
+
for (const k of ["filePath", "path", "pattern", "query", "symbol", "module", "action"]) {
|
|
186652
|
+
const v = input[k];
|
|
186653
|
+
if (typeof v === "string" && v.length > 0)
|
|
186654
|
+
return truncate2(v, 60);
|
|
186655
|
+
}
|
|
186656
|
+
if (typeof input.description === "string")
|
|
186657
|
+
return truncate2(input.description, 60);
|
|
186658
|
+
return "";
|
|
186659
|
+
}
|
|
186660
|
+
function asToolPart(part) {
|
|
186661
|
+
const type = typeof part.type === "string" ? part.type : "";
|
|
186662
|
+
if (type === "tool") {
|
|
186663
|
+
const state = isRecord3(part.state) ? part.state : null;
|
|
186664
|
+
const output = state && typeof state.output === "string" ? state.output : state && state.output != null ? JSON.stringify(state.output) : null;
|
|
186665
|
+
const metadata = state && isRecord3(state.metadata) ? state.metadata : null;
|
|
186666
|
+
const title = state && typeof state.title === "string" && state.title || metadata && typeof metadata.title === "string" && metadata.title || null;
|
|
186667
|
+
return {
|
|
186668
|
+
name: typeof part.tool === "string" ? part.tool : "tool",
|
|
186669
|
+
callId: typeof part.callID === "string" ? part.callID : "",
|
|
186670
|
+
title,
|
|
186671
|
+
input: state && isRecord3(state.input) ? state.input : null,
|
|
186672
|
+
output
|
|
186673
|
+
};
|
|
186674
|
+
}
|
|
186675
|
+
if (type === "tool_use") {
|
|
186676
|
+
return {
|
|
186677
|
+
name: typeof part.name === "string" ? part.name : "tool",
|
|
186678
|
+
callId: typeof part.id === "string" ? part.id : "",
|
|
186679
|
+
title: null,
|
|
186680
|
+
input: isRecord3(part.input) ? part.input : null,
|
|
186681
|
+
output: null
|
|
186682
|
+
};
|
|
186683
|
+
}
|
|
186684
|
+
if (type === "tool_result") {
|
|
186685
|
+
const content = part.content;
|
|
186686
|
+
const output = typeof content === "string" ? content : content != null ? JSON.stringify(content) : null;
|
|
186687
|
+
return {
|
|
186688
|
+
name: "tool_result",
|
|
186689
|
+
callId: typeof part.tool_use_id === "string" ? part.tool_use_id : "",
|
|
186690
|
+
title: null,
|
|
186691
|
+
input: null,
|
|
186692
|
+
output
|
|
186693
|
+
};
|
|
186694
|
+
}
|
|
186695
|
+
return null;
|
|
186696
|
+
}
|
|
186697
|
+
function textOf(part) {
|
|
186698
|
+
if (part.type === "text" && typeof part.text === "string")
|
|
186699
|
+
return part.text;
|
|
186700
|
+
return null;
|
|
186701
|
+
}
|
|
186702
|
+
function reasoningOf(part) {
|
|
186703
|
+
if ((part.type === "reasoning" || part.type === "thinking") && typeof part.text === "string") {
|
|
186704
|
+
return part.text;
|
|
186705
|
+
}
|
|
186706
|
+
return null;
|
|
186707
|
+
}
|
|
186708
|
+
function renderPartPreview(part) {
|
|
186709
|
+
if (!isRecord3(part))
|
|
186710
|
+
return null;
|
|
186711
|
+
const text = textOf(part);
|
|
186712
|
+
if (text !== null) {
|
|
186713
|
+
const t = truncate2(text, 200);
|
|
186714
|
+
return t.length > 0 ? ` • ${t}` : null;
|
|
186715
|
+
}
|
|
186716
|
+
const tool = asToolPart(part);
|
|
186717
|
+
if (tool) {
|
|
186718
|
+
const arg = keyArg(tool.input);
|
|
186719
|
+
const head = arg ? `${tool.name}(${arg})` : tool.name;
|
|
186720
|
+
return tool.output !== null ? ` • tool ${head} → output ~${estimateTokens(tool.output)} tok` : ` • tool ${head}`;
|
|
186721
|
+
}
|
|
186722
|
+
const reasoning = reasoningOf(part);
|
|
186723
|
+
if (reasoning !== null)
|
|
186724
|
+
return ` • [reasoning] ${truncate2(reasoning, 120)}`;
|
|
186725
|
+
const type = typeof part.type === "string" ? part.type : "part";
|
|
186726
|
+
if (type === "file")
|
|
186727
|
+
return " • [file]";
|
|
186728
|
+
if (type === "step-start" || type === "step-finish")
|
|
186729
|
+
return null;
|
|
186730
|
+
return ` • [${type}]`;
|
|
186731
|
+
}
|
|
186732
|
+
function renderPartFull(part) {
|
|
186733
|
+
if (!isRecord3(part))
|
|
186734
|
+
return null;
|
|
186735
|
+
const text = textOf(part);
|
|
186736
|
+
if (text !== null) {
|
|
186737
|
+
return text.trim().length > 0 ? ` [text]
|
|
186738
|
+
${text}` : null;
|
|
186739
|
+
}
|
|
186740
|
+
const tool = asToolPart(part);
|
|
186741
|
+
if (tool) {
|
|
186742
|
+
const lines = [];
|
|
186743
|
+
const idSuffix = tool.callId ? ` #${tool.callId}` : "";
|
|
186744
|
+
lines.push(` [tool: ${tool.name}${idSuffix}]`);
|
|
186745
|
+
if (tool.title && tool.title.trim().length > 0) {
|
|
186746
|
+
lines.push(` description: ${tool.title.trim()}`);
|
|
186747
|
+
}
|
|
186748
|
+
if (tool.input)
|
|
186749
|
+
lines.push(` input: ${JSON.stringify(tool.input)}`);
|
|
186750
|
+
if (tool.output !== null)
|
|
186751
|
+
lines.push(` output:
|
|
186752
|
+
${tool.output}`);
|
|
186753
|
+
return lines.join(`
|
|
186754
|
+
`);
|
|
186755
|
+
}
|
|
186756
|
+
const type = typeof part.type === "string" ? part.type : "part";
|
|
186757
|
+
if (type === "file") {
|
|
186758
|
+
const name2 = typeof part.filename === "string" && part.filename || typeof part.url === "string" && part.url || "";
|
|
186759
|
+
return ` [file]${name2 ? ` ${name2}` : ""}`;
|
|
186760
|
+
}
|
|
186761
|
+
return null;
|
|
186762
|
+
}
|
|
186763
|
+
function renderMessageByOrdinal(sessionId, ordinal) {
|
|
186764
|
+
const msg = readRawSessionMessages(sessionId).find((m) => m.ordinal === ordinal);
|
|
186765
|
+
if (!msg) {
|
|
186766
|
+
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.`;
|
|
186767
|
+
}
|
|
186768
|
+
const rendered = msg.parts.map(renderPartFull).filter((l) => l !== null);
|
|
186769
|
+
const lines = [`[${msg.ordinal}] ${roleLabel(msg.role)} — full recovery:`, ""];
|
|
186770
|
+
if (rendered.length === 0) {
|
|
186771
|
+
lines.push(" (no recoverable content — message had only structural/reasoning parts)");
|
|
186772
|
+
} else {
|
|
186773
|
+
lines.push(...rendered);
|
|
186774
|
+
}
|
|
186775
|
+
return lines.join(`
|
|
186776
|
+
`);
|
|
186777
|
+
}
|
|
186778
|
+
function renderVerboseRange(sessionId, start, end, tokenBudget) {
|
|
186779
|
+
const messages = readRawSessionMessages(sessionId).filter((m) => m.ordinal >= start && m.ordinal <= end);
|
|
186780
|
+
const out = [];
|
|
186781
|
+
let usedTokens = 0;
|
|
186782
|
+
let lastOrdinal = start - 1;
|
|
186783
|
+
let truncated = false;
|
|
186784
|
+
for (const msg of messages) {
|
|
186785
|
+
const header = `[${msg.ordinal}] ${roleLabel(msg.role)}`;
|
|
186786
|
+
const partLines = msg.parts.map(renderPartPreview).filter((l) => l !== null);
|
|
186787
|
+
const block = partLines.length > 0 ? `${header}
|
|
186788
|
+
${partLines.join(`
|
|
186789
|
+
`)}` : header;
|
|
186790
|
+
const blockTokens = estimateTokens(block);
|
|
186791
|
+
if (usedTokens + blockTokens > tokenBudget && out.length > 0) {
|
|
186792
|
+
truncated = true;
|
|
186793
|
+
break;
|
|
186794
|
+
}
|
|
186795
|
+
out.push(block);
|
|
186796
|
+
usedTokens += blockTokens;
|
|
186797
|
+
lastOrdinal = msg.ordinal;
|
|
186798
|
+
}
|
|
186799
|
+
return { text: out.join(`
|
|
186800
|
+
|
|
186801
|
+
`), lastOrdinal, truncated };
|
|
186802
|
+
}
|
|
186803
|
+
|
|
185788
186804
|
// ../../node_modules/.bun/typebox@1.1.38/node_modules/typebox/build/system/memory/memory.mjs
|
|
185789
186805
|
var exports_memory = {};
|
|
185790
186806
|
__export(exports_memory, {
|
|
@@ -189850,12 +190866,18 @@ __export(exports_typebox, {
|
|
|
189850
190866
|
});
|
|
189851
190867
|
// src/tools/ctx-expand.ts
|
|
189852
190868
|
var ParamsSchema = exports_typebox.Object({
|
|
189853
|
-
start: exports_typebox.Number({
|
|
190869
|
+
start: exports_typebox.Optional(exports_typebox.Number({
|
|
189854
190870
|
description: "Start message ordinal (from compartment start attribute)"
|
|
189855
|
-
}),
|
|
189856
|
-
end: exports_typebox.Number({
|
|
190871
|
+
})),
|
|
190872
|
+
end: exports_typebox.Optional(exports_typebox.Number({
|
|
189857
190873
|
description: "End message ordinal (from compartment end attribute)"
|
|
189858
|
-
})
|
|
190874
|
+
})),
|
|
190875
|
+
verbose: exports_typebox.Optional(exports_typebox.Boolean({
|
|
190876
|
+
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."
|
|
190877
|
+
})),
|
|
190878
|
+
message: exports_typebox.Optional(exports_typebox.Number({
|
|
190879
|
+
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."
|
|
190880
|
+
}))
|
|
189859
190881
|
});
|
|
189860
190882
|
function ok(text) {
|
|
189861
190883
|
return { content: [{ type: "text", text }], details: undefined };
|
|
@@ -189874,22 +190896,41 @@ function createCtxExpandTool(deps) {
|
|
|
189874
190896
|
description: CTX_EXPAND_DESCRIPTION,
|
|
189875
190897
|
parameters: ParamsSchema,
|
|
189876
190898
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
189877
|
-
if (typeof params.start !== "number" || typeof params.end !== "number" || params.start < 1 || params.end < params.start) {
|
|
189878
|
-
return err("Error: start and end must be positive integers with start <= end.");
|
|
189879
|
-
}
|
|
189880
190899
|
const sessionId = ctx.sessionManager.getSessionId();
|
|
189881
190900
|
if (!sessionId) {
|
|
189882
190901
|
return err("Error: no active Pi session.");
|
|
189883
190902
|
}
|
|
189884
|
-
const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
|
|
189885
|
-
if (lastCompartmentEnd >= 0 && params.start > lastCompartmentEnd) {
|
|
189886
|
-
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.`);
|
|
189887
|
-
}
|
|
189888
|
-
const effectiveEnd = lastCompartmentEnd >= 0 ? Math.min(params.end, lastCompartmentEnd) : params.end;
|
|
189889
190903
|
const unregister = setRawMessageProvider(sessionId, {
|
|
189890
190904
|
readMessages: () => readPiSessionMessages(ctx)
|
|
189891
190905
|
});
|
|
189892
190906
|
try {
|
|
190907
|
+
if (typeof params.message === "number" && params.message >= 1) {
|
|
190908
|
+
return ok(renderMessageByOrdinal(sessionId, params.message));
|
|
190909
|
+
}
|
|
190910
|
+
if (typeof params.start !== "number" || typeof params.end !== "number" || params.start < 1 || params.end < params.start) {
|
|
190911
|
+
return err("Error: provide either message=<ordinal>, or start and end (positive integers, start <= end).");
|
|
190912
|
+
}
|
|
190913
|
+
const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
|
|
190914
|
+
if (lastCompartmentEnd >= 0 && params.start > lastCompartmentEnd) {
|
|
190915
|
+
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.`);
|
|
190916
|
+
}
|
|
190917
|
+
const effectiveEnd = lastCompartmentEnd >= 0 ? Math.min(params.end, lastCompartmentEnd) : params.end;
|
|
190918
|
+
if (params.verbose === true) {
|
|
190919
|
+
const v = renderVerboseRange(sessionId, params.start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET);
|
|
190920
|
+
if (!v.text) {
|
|
190921
|
+
return ok(`No messages found in range ${params.start}-${effectiveEnd}. The range may be outside this session's history.`);
|
|
190922
|
+
}
|
|
190923
|
+
const out = [
|
|
190924
|
+
`Messages ${params.start}-${v.lastOrdinal} (verbose). Recover any one in full with ctx_expand(message=<ordinal>):`,
|
|
190925
|
+
"",
|
|
190926
|
+
v.text
|
|
190927
|
+
];
|
|
190928
|
+
if (v.truncated) {
|
|
190929
|
+
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.`);
|
|
190930
|
+
}
|
|
190931
|
+
return ok(out.join(`
|
|
190932
|
+
`));
|
|
190933
|
+
}
|
|
189893
190934
|
const chunk = readSessionChunk(sessionId, CTX_EXPAND_TOKEN_BUDGET, params.start, effectiveEnd + 1);
|
|
189894
190935
|
if (!chunk.text || chunk.messageCount === 0) {
|
|
189895
190936
|
return ok(`No messages found in range ${params.start}-${params.end}. The range may be outside this session's history.`);
|
|
@@ -190608,15 +191649,16 @@ function parseInteger(str) {
|
|
|
190608
191649
|
}
|
|
190609
191650
|
|
|
190610
191651
|
// ../plugin/src/tools/ctx-reduce/constants.ts
|
|
190611
|
-
var CTX_REDUCE_DESCRIPTION = `
|
|
190612
|
-
|
|
191652
|
+
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".
|
|
191653
|
+
|
|
191654
|
+
How it works:
|
|
191655
|
+
- 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.
|
|
191656
|
+
- The newest tags are protected: marking one just queues it until it ages out of the recent window, so marking recent output is harmless.
|
|
191657
|
+
- 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?".
|
|
190613
191658
|
|
|
190614
|
-
|
|
190615
|
-
|
|
190616
|
-
-
|
|
190617
|
-
- Protected tags are accepted but deferred until they leave the last protected range.
|
|
190618
|
-
- Keep recent context — only reduce OLD content that is no longer relevant to current work.
|
|
190619
|
-
- Dropped content is gone forever.`;
|
|
191659
|
+
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.
|
|
191660
|
+
Keep: user messages, unresolved errors, raw evidence you haven't extracted yet, and outputs whose exact wording may matter later.
|
|
191661
|
+
Never blanket-mark large ranges (e.g. "1-50") — review what each tag holds first.`;
|
|
190620
191662
|
|
|
190621
191663
|
// src/tools/ctx-reduce.ts
|
|
190622
191664
|
var ParamsSchema4 = exports_typebox.Object({
|
|
@@ -190843,7 +191885,7 @@ function createCtxSearchTool(deps) {
|
|
|
190843
191885
|
memoryEnabled,
|
|
190844
191886
|
embeddingEnabled,
|
|
190845
191887
|
embedQuery: async (text, signal) => {
|
|
190846
|
-
const result = await embedTextForProject(projectIdentity, text, signal);
|
|
191888
|
+
const result = await embedTextForProject(projectIdentity, text, signal, "query");
|
|
190847
191889
|
return result?.vector ?? null;
|
|
190848
191890
|
},
|
|
190849
191891
|
isEmbeddingRuntimeEnabled: () => embeddingEnabled === true,
|
|
@@ -191071,7 +192113,7 @@ function resolveSidekickFromConfig(config2) {
|
|
|
191071
192113
|
systemPrompt: sidekick.system_prompt,
|
|
191072
192114
|
timeoutMs: sidekick.timeout_ms,
|
|
191073
192115
|
thinking_level: sidekick.thinking_level,
|
|
191074
|
-
fallbackModels: resolveFallbackChain(
|
|
192116
|
+
fallbackModels: resolveFallbackChain(sidekick.fallback_models)
|
|
191075
192117
|
};
|
|
191076
192118
|
}
|
|
191077
192119
|
function resolveHistorianFromConfig(config2) {
|
|
@@ -191083,7 +192125,7 @@ function resolveHistorianFromConfig(config2) {
|
|
|
191083
192125
|
return;
|
|
191084
192126
|
const historianContextLimit = resolveHistorianContextLimit(model);
|
|
191085
192127
|
const historianChunkTokens = deriveHistorianChunkTokens(historianContextLimit);
|
|
191086
|
-
const fallbackModels = resolveFallbackChain(
|
|
192128
|
+
const fallbackModels = resolveFallbackChain(historian?.fallback_models);
|
|
191087
192129
|
return {
|
|
191088
192130
|
runner: new PiSubagentRunner,
|
|
191089
192131
|
model,
|
|
@@ -191217,7 +192259,21 @@ async function src_default2(pi) {
|
|
|
191217
192259
|
},
|
|
191218
192260
|
historian: hist,
|
|
191219
192261
|
autoSearch: auto,
|
|
191220
|
-
resolveForProject: resolveContextOptionsForProject
|
|
192262
|
+
resolveForProject: resolveContextOptionsForProject,
|
|
192263
|
+
maybeAutoEmbedSession: (sessionId, dir, identity) => {
|
|
192264
|
+
maybeAutoEmbedPiSession({
|
|
192265
|
+
db: database,
|
|
192266
|
+
projectDir: dir,
|
|
192267
|
+
projectIdentity: identity,
|
|
192268
|
+
memoryEnabled: cfg.memory.enabled
|
|
192269
|
+
}, sessionId, dir, identity, (text) => {
|
|
192270
|
+
pi.sendMessage({
|
|
192271
|
+
customType: "ctx-status",
|
|
192272
|
+
content: text,
|
|
192273
|
+
display: true
|
|
192274
|
+
}, { triggerTurn: false });
|
|
192275
|
+
});
|
|
192276
|
+
}
|
|
191221
192277
|
});
|
|
191222
192278
|
function resolveContextOptionsForProject(dir) {
|
|
191223
192279
|
const cached2 = contextOptionsByDir.get(dir);
|
|
@@ -191299,14 +192355,14 @@ async function src_default2(pi) {
|
|
|
191299
192355
|
onProjectSeen: (identity) => seenDreamerProjectIdentities.add(identity)
|
|
191300
192356
|
});
|
|
191301
192357
|
info("registered /ctx-dream");
|
|
191302
|
-
|
|
192358
|
+
registerCtxEmbedCommand(pi, {
|
|
191303
192359
|
db,
|
|
191304
192360
|
projectDir,
|
|
191305
192361
|
projectIdentity,
|
|
191306
192362
|
memoryEnabled: config2.memory.enabled,
|
|
191307
192363
|
resolveProject: resolveCurrentProject
|
|
191308
192364
|
});
|
|
191309
|
-
info("registered /ctx-embed
|
|
192365
|
+
info("registered /ctx-embed");
|
|
191310
192366
|
const dreamerConfig = resolveDreamerFromConfig(config2);
|
|
191311
192367
|
if (dreamerConfig) {
|
|
191312
192368
|
registerPiDreamerProject({
|