@wolfx/opencode-magic-context 0.22.1-patch.1 → 0.22.4
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/config/agent-disable.d.ts +0 -9
- package/dist/config/agent-disable.d.ts.map +1 -1
- package/dist/config/schema/agent-overrides.d.ts +0 -3
- package/dist/config/schema/agent-overrides.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +7 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/features/builtin-commands/types.d.ts +0 -2
- package/dist/features/builtin-commands/types.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/runner.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/scheduler.d.ts +0 -4
- package/dist/features/magic-context/dreamer/scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/git-log-reader.d.ts +8 -0
- package/dist/features/magic-context/git-commits/git-log-reader.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/index.d.ts +1 -0
- package/dist/features/magic-context/git-commits/index.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/indexer.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/storage-git-commits.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/sweep-coordinator.d.ts +48 -0
- package/dist/features/magic-context/git-commits/sweep-coordinator.d.ts.map +1 -0
- package/dist/features/magic-context/key-files/aft-availability.d.ts.map +1 -1
- package/dist/features/magic-context/key-files/identify-key-files.d.ts.map +1 -1
- package/dist/features/magic-context/key-files/storage-key-files.d.ts +0 -5
- package/dist/features/magic-context/key-files/storage-key-files.d.ts.map +1 -1
- package/dist/features/magic-context/literal-probes.d.ts +24 -0
- package/dist/features/magic-context/literal-probes.d.ts.map +1 -0
- package/dist/features/magic-context/memory/memory-migration.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/search.d.ts +7 -0
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/sidekick/agent.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts +7 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
- package/dist/features/magic-context/storage-notes.d.ts +8 -0
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -1
- package/dist/features/magic-context/tool-definition-tokens.d.ts +21 -0
- package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
- package/dist/features/magic-context/types.d.ts +4 -0
- package/dist/features/magic-context/types.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +14 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/derive-budgets.d.ts +3 -3
- package/dist/hooks/magic-context/event-handler.d.ts +7 -0
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-payloads.d.ts +7 -0
- package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts +1 -0
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +41 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/live-session-state.d.ts +12 -0
- package/dist/hooks/magic-context/live-session-state.d.ts.map +1 -1
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts +7 -2
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +9 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-content-primitives.d.ts +23 -0
- package/dist/hooks/magic-context/tag-content-primitives.d.ts.map +1 -1
- package/dist/hooks/magic-context/temporal-awareness.d.ts.map +1 -1
- package/dist/hooks/magic-context/text-complete.d.ts +11 -26
- package/dist/hooks/magic-context/text-complete.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +2 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +17 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +830 -263
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/shared/keep-subagents.d.ts +7 -0
- package/dist/shared/keep-subagents.d.ts.map +1 -0
- package/dist/shared/models-dev-cache.d.ts +54 -27
- package/dist/shared/models-dev-cache.d.ts.map +1 -1
- package/dist/shared/rpc-types.d.ts +3 -1
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/shared/keep-subagents.test.ts +39 -0
- package/src/shared/keep-subagents.ts +33 -0
- package/src/shared/models-dev-cache.test.ts +192 -360
- package/src/shared/models-dev-cache.ts +162 -193
- package/src/shared/rpc-types.ts +3 -1
- package/src/tui/index.tsx +17 -8
- package/src/tui/slots/sidebar-content.tsx +20 -10
package/dist/index.js
CHANGED
|
@@ -14967,6 +14967,7 @@ var init_magic_context = __esm(() => {
|
|
|
14967
14967
|
model: DEFAULT_LOCAL_EMBEDDING_MODEL
|
|
14968
14968
|
}).describe("Embedding provider configuration"),
|
|
14969
14969
|
temporal_awareness: exports_external.boolean().default(true).describe('Inject wall-clock gap markers (<!-- +Xm -->) between user messages where > 5 min elapsed since the previous message, and add start/end date attributes on compartments. Gives the agent a sense of session pacing and "how long ago" across multi-day sessions. Graduated from experimental.temporal_awareness; default: true (set false to opt out).'),
|
|
14970
|
+
keep_subagents: exports_external.boolean().default(false).describe("Debug: keep the child sessions Magic Context spawns for its own subagents (historian, dreamer, sidekick, memory-migration) instead of deleting them on success. Useful for short-term inspection/data collection — their full transcript (prompt, tool calls, token usage, output) stays in the host session store. Kept sessions accumulate until manually cleared; leave false for normal use. Requires a restart to take effect."),
|
|
14970
14971
|
caveman_text_compression: exports_external.object({
|
|
14971
14972
|
enabled: exports_external.boolean().default(false).describe("Apply deterministic caveman-style text compression to old conversation text. Only active when ctx_reduce_enabled=false. Compresses user/assistant text in oldest-first tiers: ultra (oldest 20%), full, lite, untouched (newest 40%)."),
|
|
14972
14973
|
min_chars: exports_external.number().min(100).max(1e4).default(500).describe("Text parts shorter than this (characters) stay untouched. Min 100, max 10000. Default: 500.")
|
|
@@ -15216,9 +15217,6 @@ function getMagicContextStorageDir() {
|
|
|
15216
15217
|
function getLegacyOpenCodeMagicContextStorageDir() {
|
|
15217
15218
|
return path2.join(getOpenCodeStorageDir(), "plugin", "magic-context");
|
|
15218
15219
|
}
|
|
15219
|
-
function getCacheDir() {
|
|
15220
|
-
return process.env.XDG_CACHE_HOME ?? path2.join(os.homedir(), ".cache");
|
|
15221
|
-
}
|
|
15222
15220
|
var init_data_path = () => {};
|
|
15223
15221
|
|
|
15224
15222
|
// src/shared/logger.ts
|
|
@@ -15752,6 +15750,15 @@ function extractLatestAssistantText(messages) {
|
|
|
15752
15750
|
}
|
|
15753
15751
|
var init_assistant_message_extractor = () => {};
|
|
15754
15752
|
|
|
15753
|
+
// src/shared/keep-subagents.ts
|
|
15754
|
+
function setKeepSubagents(value) {
|
|
15755
|
+
keepSubagents = value === true;
|
|
15756
|
+
}
|
|
15757
|
+
function shouldKeepSubagents() {
|
|
15758
|
+
return keepSubagents;
|
|
15759
|
+
}
|
|
15760
|
+
var keepSubagents = false;
|
|
15761
|
+
|
|
15755
15762
|
// src/features/magic-context/compartment-lease.ts
|
|
15756
15763
|
function acquireCompartmentLease(db, sessionId, holderId) {
|
|
15757
15764
|
const acquiredAt = Date.now();
|
|
@@ -15838,7 +15845,7 @@ function isSessionMetaRow(row) {
|
|
|
15838
15845
|
if (row === null || typeof row !== "object")
|
|
15839
15846
|
return false;
|
|
15840
15847
|
const r = row;
|
|
15841
|
-
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) && 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.last_observed_model_key) && isNumberOrNull(r.upgrade_reminded_at) && isNumberOrNull(r.pi_stable_id_scheme);
|
|
15848
|
+
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) && 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.upgrade_reminded_at) && isNumberOrNull(r.pi_stable_id_scheme);
|
|
15842
15849
|
}
|
|
15843
15850
|
function getDefaultSessionMeta(sessionId) {
|
|
15844
15851
|
return {
|
|
@@ -15874,6 +15881,9 @@ function getDefaultSessionMeta(sessionId) {
|
|
|
15874
15881
|
cachedM0MaterializedAt: null,
|
|
15875
15882
|
cachedM0SessionFactsVersion: null,
|
|
15876
15883
|
cachedM0UpgradeState: null,
|
|
15884
|
+
cachedM0SystemHash: null,
|
|
15885
|
+
cachedM0ToolSetHash: null,
|
|
15886
|
+
cachedM0ModelKey: null,
|
|
15877
15887
|
lastObservedModelKey: null,
|
|
15878
15888
|
upgradeRemindedAt: null,
|
|
15879
15889
|
piStableIdScheme: null
|
|
@@ -15925,6 +15935,9 @@ function toSessionMeta(row) {
|
|
|
15925
15935
|
cachedM0MaterializedAt: numOrNull(row.cached_m0_materialized_at),
|
|
15926
15936
|
cachedM0SessionFactsVersion: numOrNull(row.cached_m0_session_facts_version),
|
|
15927
15937
|
cachedM0UpgradeState: stringOrNull(row.cached_m0_upgrade_state),
|
|
15938
|
+
cachedM0SystemHash: stringOrNull(row.cached_m0_system_hash),
|
|
15939
|
+
cachedM0ToolSetHash: stringOrNull(row.cached_m0_tool_set_hash),
|
|
15940
|
+
cachedM0ModelKey: stringOrNull(row.cached_m0_model_key),
|
|
15928
15941
|
lastObservedModelKey: stringOrNull(row.last_observed_model_key),
|
|
15929
15942
|
upgradeRemindedAt: numOrNull(row.upgrade_reminded_at),
|
|
15930
15943
|
piStableIdScheme: numOrNull(row.pi_stable_id_scheme)
|
|
@@ -15944,8 +15957,11 @@ function persistCachedM0(db, sessionId, payload) {
|
|
|
15944
15957
|
cached_m0_project_docs_hash = ?,
|
|
15945
15958
|
cached_m0_materialized_at = ?,
|
|
15946
15959
|
cached_m0_session_facts_version = ?,
|
|
15947
|
-
cached_m0_upgrade_state =
|
|
15948
|
-
|
|
15960
|
+
cached_m0_upgrade_state = ?,
|
|
15961
|
+
cached_m0_system_hash = ?,
|
|
15962
|
+
cached_m0_tool_set_hash = ?,
|
|
15963
|
+
cached_m0_model_key = ?
|
|
15964
|
+
WHERE session_id = ?`).run(Buffer2.from(payload.m0Bytes), payload.projectMemoryEpoch, payload.projectUserProfileVersion, payload.maxCompartmentSeq, payload.maxMemoryId, payload.maxMutationId, payload.maxMemoryMutationId ?? null, payload.m1Bytes ? Buffer2.from(payload.m1Bytes) : null, payload.projectDocsHash, payload.materializedAt, payload.sessionFactsVersion, payload.upgradeState, payload.systemHash ?? "", payload.toolSetHash ?? "", payload.modelKey ?? "", sessionId);
|
|
15949
15965
|
}
|
|
15950
15966
|
function clearCachedM0M1(db, sessionId) {
|
|
15951
15967
|
ensureSessionMetaRow(db, sessionId);
|
|
@@ -15963,6 +15979,9 @@ function clearCachedM0M1(db, sessionId) {
|
|
|
15963
15979
|
["cached_m0_materialized_at", null],
|
|
15964
15980
|
["cached_m0_session_facts_version", null],
|
|
15965
15981
|
["cached_m0_upgrade_state", null],
|
|
15982
|
+
["cached_m0_system_hash", null],
|
|
15983
|
+
["cached_m0_tool_set_hash", null],
|
|
15984
|
+
["cached_m0_model_key", null],
|
|
15966
15985
|
["cached_m0_last_baseline_end_message_id", null],
|
|
15967
15986
|
["memory_block_cache", ""],
|
|
15968
15987
|
["memory_block_count", 0],
|
|
@@ -16015,6 +16034,9 @@ var init_storage_meta_shared = __esm(() => {
|
|
|
16015
16034
|
"cached_m0_materialized_at",
|
|
16016
16035
|
"cached_m0_session_facts_version",
|
|
16017
16036
|
"cached_m0_upgrade_state",
|
|
16037
|
+
"cached_m0_system_hash",
|
|
16038
|
+
"cached_m0_tool_set_hash",
|
|
16039
|
+
"cached_m0_model_key",
|
|
16018
16040
|
"last_observed_model_key",
|
|
16019
16041
|
"upgrade_reminded_at",
|
|
16020
16042
|
"pi_stable_id_scheme"
|
|
@@ -16051,6 +16073,9 @@ var init_storage_meta_shared = __esm(() => {
|
|
|
16051
16073
|
cachedM0MaterializedAt: "cached_m0_materialized_at",
|
|
16052
16074
|
cachedM0SessionFactsVersion: "cached_m0_session_facts_version",
|
|
16053
16075
|
cachedM0UpgradeState: "cached_m0_upgrade_state",
|
|
16076
|
+
cachedM0SystemHash: "cached_m0_system_hash",
|
|
16077
|
+
cachedM0ToolSetHash: "cached_m0_tool_set_hash",
|
|
16078
|
+
cachedM0ModelKey: "cached_m0_model_key",
|
|
16054
16079
|
lastObservedModelKey: "last_observed_model_key",
|
|
16055
16080
|
upgradeRemindedAt: "upgrade_reminded_at",
|
|
16056
16081
|
piStableIdScheme: "pi_stable_id_scheme"
|
|
@@ -149164,14 +149189,45 @@ function readRawSessionMessageByIdFromDb(db, sessionId, messageId) {
|
|
|
149164
149189
|
}
|
|
149165
149190
|
|
|
149166
149191
|
// src/hooks/magic-context/tag-content-primitives.ts
|
|
149192
|
+
function stripWellFormedLeadingTagPrefix(value) {
|
|
149193
|
+
return value.replace(/^(\u00a7\d+\u00a7\s*)+/, "");
|
|
149194
|
+
}
|
|
149195
|
+
function stripCompleteTagPairsGlobally(value) {
|
|
149196
|
+
return value.replace(COMPLETE_TAG_PAIR_GLOBAL_REGEX, "");
|
|
149197
|
+
}
|
|
149198
|
+
function stripMalformedTagNotationGlobally(value) {
|
|
149199
|
+
return value.replace(MALFORMED_TAG_GLOBAL_REGEX, "");
|
|
149200
|
+
}
|
|
149201
|
+
function stripTagSectionCharacters(value) {
|
|
149202
|
+
return value.replace(STRAY_SECTION_CHAR_REGEX, "");
|
|
149203
|
+
}
|
|
149204
|
+
function stripPersistedAssistantText(value) {
|
|
149205
|
+
let text = stripWellFormedLeadingTagPrefix(value);
|
|
149206
|
+
text = stripCompleteTagPairsGlobally(text);
|
|
149207
|
+
text = stripMalformedTagNotationGlobally(text);
|
|
149208
|
+
text = stripTagSectionCharacters(text);
|
|
149209
|
+
return text.trim();
|
|
149210
|
+
}
|
|
149167
149211
|
function byteSize(value) {
|
|
149168
149212
|
return encoder.encode(value).length;
|
|
149169
149213
|
}
|
|
149170
149214
|
function stripTagPrefix(value) {
|
|
149171
|
-
let stripped = value
|
|
149172
|
-
|
|
149215
|
+
let stripped = value;
|
|
149216
|
+
for (let pass = 0;pass < 8; pass++) {
|
|
149217
|
+
const prev = stripped;
|
|
149218
|
+
stripped = stripped.replace(MALFORMED_TAG_PREFIX_REGEX, "");
|
|
149219
|
+
stripped = stripped.replace(TAG_PREFIX_REGEX, "");
|
|
149220
|
+
if (stripped === prev)
|
|
149221
|
+
break;
|
|
149222
|
+
}
|
|
149173
149223
|
return stripped;
|
|
149174
149224
|
}
|
|
149225
|
+
function peelLeadingMcTagNotation(value) {
|
|
149226
|
+
const body = stripTagPrefix(value);
|
|
149227
|
+
if (body === value)
|
|
149228
|
+
return { tagPrefix: "", body };
|
|
149229
|
+
return { tagPrefix: value.slice(0, value.length - body.length), body };
|
|
149230
|
+
}
|
|
149175
149231
|
function prependTag(tagId, value) {
|
|
149176
149232
|
const stripped = stripTagPrefix(value);
|
|
149177
149233
|
return `§${tagId}§ ${stripped}`;
|
|
@@ -149182,11 +149238,14 @@ function isThinkingPart(part) {
|
|
|
149182
149238
|
const candidate = part;
|
|
149183
149239
|
return candidate.type === "thinking" || candidate.type === "reasoning";
|
|
149184
149240
|
}
|
|
149185
|
-
var encoder, TAG_PREFIX_REGEX, MALFORMED_TAG_PREFIX_REGEX;
|
|
149241
|
+
var encoder, TAG_PREFIX_REGEX, MALFORMED_TAG_PREFIX_REGEX, COMPLETE_TAG_PAIR_GLOBAL_REGEX, MALFORMED_TAG_GLOBAL_REGEX, STRAY_SECTION_CHAR_REGEX;
|
|
149186
149242
|
var init_tag_content_primitives = __esm(() => {
|
|
149187
149243
|
encoder = new TextEncoder;
|
|
149188
149244
|
TAG_PREFIX_REGEX = /^(?:§\d+§\s*)+/;
|
|
149189
149245
|
MALFORMED_TAG_PREFIX_REGEX = /^(?:§\d+">§(?:\d+§)?\s*)+/;
|
|
149246
|
+
COMPLETE_TAG_PAIR_GLOBAL_REGEX = /\u00a7\d+\u00a7/g;
|
|
149247
|
+
MALFORMED_TAG_GLOBAL_REGEX = /\u00a7\d+">(?:\u00a7(?:\d+\u00a7)?)?/g;
|
|
149248
|
+
STRAY_SECTION_CHAR_REGEX = /\u00a7/g;
|
|
149190
149249
|
});
|
|
149191
149250
|
|
|
149192
149251
|
// src/hooks/magic-context/tag-part-guards.ts
|
|
@@ -149314,7 +149373,9 @@ function hasMeaningfulPart(part) {
|
|
|
149314
149373
|
return false;
|
|
149315
149374
|
const type = part.type;
|
|
149316
149375
|
if (type === "text") {
|
|
149317
|
-
|
|
149376
|
+
if (typeof part.text !== "string")
|
|
149377
|
+
return false;
|
|
149378
|
+
return stripTagPrefix(part.text).trim().length > 0;
|
|
149318
149379
|
}
|
|
149319
149380
|
if (typeof type !== "string")
|
|
149320
149381
|
return false;
|
|
@@ -149430,6 +149491,7 @@ function createToolDropTarget(compositeKey, thinkingParts, index, batch) {
|
|
|
149430
149491
|
}
|
|
149431
149492
|
var DROP_PREFIX = "[dropped", IGNORE_PART_TYPES, TRUNCATION_SENTINEL = "...[truncated]";
|
|
149432
149493
|
var init_tool_drop_target = __esm(() => {
|
|
149494
|
+
init_tag_content_primitives();
|
|
149433
149495
|
IGNORE_PART_TYPES = new Set([
|
|
149434
149496
|
"thinking",
|
|
149435
149497
|
"reasoning",
|
|
@@ -150082,6 +150144,18 @@ function keyFor(providerID, modelID, agentName) {
|
|
|
150082
150144
|
function fingerprintFor(description, parameters) {
|
|
150083
150145
|
return createHash3("sha256").update(description).update("\x00").update(stableStringify(parameters)).digest("hex");
|
|
150084
150146
|
}
|
|
150147
|
+
function getCurrentToolSetHash(providerID, modelID, agentName) {
|
|
150148
|
+
const key = keyFor(providerID, modelID, agentName);
|
|
150149
|
+
const inner = fingerprints.get(key);
|
|
150150
|
+
if (!inner || inner.size === 0)
|
|
150151
|
+
return "";
|
|
150152
|
+
const parts = [];
|
|
150153
|
+
for (const [toolID, fp] of inner)
|
|
150154
|
+
parts.push(`${toolID}\x00${fp}`);
|
|
150155
|
+
parts.sort();
|
|
150156
|
+
return createHash3("sha256").update(parts.join(`
|
|
150157
|
+
`)).digest("hex");
|
|
150158
|
+
}
|
|
150085
150159
|
function setDatabase(db) {
|
|
150086
150160
|
persistenceDb = db;
|
|
150087
150161
|
cachedInsertStmt = null;
|
|
@@ -150730,6 +150804,17 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
150730
150804
|
updated_at INTEGER NOT NULL DEFAULT 0
|
|
150731
150805
|
);
|
|
150732
150806
|
|
|
150807
|
+
CREATE TABLE IF NOT EXISTS git_sweep_coordinator (
|
|
150808
|
+
project_path TEXT PRIMARY KEY,
|
|
150809
|
+
lease_holder TEXT,
|
|
150810
|
+
lease_expires_at INTEGER,
|
|
150811
|
+
last_swept_at INTEGER
|
|
150812
|
+
);
|
|
150813
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_lease_expires
|
|
150814
|
+
ON git_sweep_coordinator(lease_expires_at);
|
|
150815
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_last_swept
|
|
150816
|
+
ON git_sweep_coordinator(last_swept_at);
|
|
150817
|
+
|
|
150733
150818
|
CREATE TABLE IF NOT EXISTS m0_mutation_log (
|
|
150734
150819
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
150735
150820
|
session_id TEXT NOT NULL,
|
|
@@ -150864,6 +150949,9 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
150864
150949
|
cached_m0_materialized_at INTEGER,
|
|
150865
150950
|
cached_m0_session_facts_version INTEGER,
|
|
150866
150951
|
cached_m0_upgrade_state TEXT,
|
|
150952
|
+
cached_m0_system_hash TEXT,
|
|
150953
|
+
cached_m0_tool_set_hash TEXT,
|
|
150954
|
+
cached_m0_model_key TEXT,
|
|
150867
150955
|
cached_m0_last_baseline_end_message_id TEXT,
|
|
150868
150956
|
upgrade_reminded_at INTEGER,
|
|
150869
150957
|
pi_stable_id_scheme INTEGER
|
|
@@ -151055,6 +151143,9 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
151055
151143
|
ensureColumn(db, "session_meta", "cached_m0_materialized_at", "INTEGER");
|
|
151056
151144
|
ensureColumn(db, "session_meta", "cached_m0_session_facts_version", "INTEGER");
|
|
151057
151145
|
ensureColumn(db, "session_meta", "cached_m0_upgrade_state", "TEXT");
|
|
151146
|
+
ensureColumn(db, "session_meta", "cached_m0_system_hash", "TEXT");
|
|
151147
|
+
ensureColumn(db, "session_meta", "cached_m0_tool_set_hash", "TEXT");
|
|
151148
|
+
ensureColumn(db, "session_meta", "cached_m0_model_key", "TEXT");
|
|
151058
151149
|
ensureColumn(db, "session_meta", "cached_m0_last_baseline_end_message_id", "TEXT");
|
|
151059
151150
|
ensureColumn(db, "session_meta", "upgrade_reminded_at", "INTEGER");
|
|
151060
151151
|
db.exec(`
|
|
@@ -151259,7 +151350,7 @@ function getDatabasePersistenceError(db) {
|
|
|
151259
151350
|
return null;
|
|
151260
151351
|
return persistenceErrorByDatabase.get(db) ?? null;
|
|
151261
151352
|
}
|
|
151262
|
-
var databases, persistenceByDatabase, persistenceErrorByDatabase, lastSchemaFenceRejection = null, LATEST_SUPPORTED_VERSION =
|
|
151353
|
+
var databases, persistenceByDatabase, persistenceErrorByDatabase, lastSchemaFenceRejection = null, LATEST_SUPPORTED_VERSION = 30, sqlitePragmaConfig;
|
|
151263
151354
|
var init_storage_db = __esm(async () => {
|
|
151264
151355
|
init_data_path();
|
|
151265
151356
|
init_logger();
|
|
@@ -152050,6 +152141,60 @@ var init_migrations = __esm(async () => {
|
|
|
152050
152141
|
ON tags(session_id, entry_fingerprint)
|
|
152051
152142
|
WHERE type='message' AND entry_fingerprint IS NOT NULL`);
|
|
152052
152143
|
}
|
|
152144
|
+
},
|
|
152145
|
+
{
|
|
152146
|
+
version: 28,
|
|
152147
|
+
description: "Add git commit sweep coordinator lease/cooldown table",
|
|
152148
|
+
up: (db) => {
|
|
152149
|
+
db.exec(`
|
|
152150
|
+
CREATE TABLE IF NOT EXISTS git_sweep_coordinator (
|
|
152151
|
+
project_path TEXT PRIMARY KEY,
|
|
152152
|
+
lease_holder TEXT,
|
|
152153
|
+
lease_expires_at INTEGER,
|
|
152154
|
+
last_swept_at INTEGER
|
|
152155
|
+
);
|
|
152156
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_lease_expires
|
|
152157
|
+
ON git_sweep_coordinator(lease_expires_at);
|
|
152158
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_last_swept
|
|
152159
|
+
ON git_sweep_coordinator(last_swept_at);
|
|
152160
|
+
`);
|
|
152161
|
+
}
|
|
152162
|
+
},
|
|
152163
|
+
{
|
|
152164
|
+
version: 29,
|
|
152165
|
+
description: "Add anchor_ordinal to notes (traceback to the conversation tail)",
|
|
152166
|
+
up: (db) => {
|
|
152167
|
+
const notesExists = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='notes'").get();
|
|
152168
|
+
if (!notesExists) {
|
|
152169
|
+
return;
|
|
152170
|
+
}
|
|
152171
|
+
const columns = db.prepare("PRAGMA table_info(notes)").all();
|
|
152172
|
+
if (!columns.some((column) => column.name === "anchor_ordinal")) {
|
|
152173
|
+
db.exec("ALTER TABLE notes ADD COLUMN anchor_ordinal INTEGER");
|
|
152174
|
+
}
|
|
152175
|
+
}
|
|
152176
|
+
},
|
|
152177
|
+
{
|
|
152178
|
+
version: 30,
|
|
152179
|
+
description: "HARD-bust m[0] markers: cached system/tool-set/model identity",
|
|
152180
|
+
up: (db) => {
|
|
152181
|
+
const hasSessionMeta = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='session_meta' LIMIT 1").get();
|
|
152182
|
+
if (!hasSessionMeta)
|
|
152183
|
+
return;
|
|
152184
|
+
ensureColumn(db, "session_meta", "cached_m0_system_hash", "TEXT");
|
|
152185
|
+
ensureColumn(db, "session_meta", "cached_m0_tool_set_hash", "TEXT");
|
|
152186
|
+
ensureColumn(db, "session_meta", "cached_m0_model_key", "TEXT");
|
|
152187
|
+
const columns = new Set(db.prepare("PRAGMA table_info(session_meta)").all().map((column) => column.name));
|
|
152188
|
+
if (columns.has("cached_m0_bytes")) {
|
|
152189
|
+
db.prepare(`UPDATE session_meta SET
|
|
152190
|
+
cached_m0_bytes = NULL,
|
|
152191
|
+
cached_m1_bytes = NULL,
|
|
152192
|
+
cached_m0_materialized_at = NULL,
|
|
152193
|
+
cached_m0_system_hash = NULL,
|
|
152194
|
+
cached_m0_tool_set_hash = NULL,
|
|
152195
|
+
cached_m0_model_key = NULL`).run();
|
|
152196
|
+
}
|
|
152197
|
+
}
|
|
152053
152198
|
}
|
|
152054
152199
|
];
|
|
152055
152200
|
LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -152968,6 +153113,9 @@ var init_storage_meta_session = __esm(async () => {
|
|
|
152968
153113
|
cached_m0_materialized_at: "NULL AS cached_m0_materialized_at",
|
|
152969
153114
|
cached_m0_session_facts_version: "NULL AS cached_m0_session_facts_version",
|
|
152970
153115
|
cached_m0_upgrade_state: "NULL AS cached_m0_upgrade_state",
|
|
153116
|
+
cached_m0_system_hash: "NULL AS cached_m0_system_hash",
|
|
153117
|
+
cached_m0_tool_set_hash: "NULL AS cached_m0_tool_set_hash",
|
|
153118
|
+
cached_m0_model_key: "NULL AS cached_m0_model_key",
|
|
152971
153119
|
last_observed_model_key: "NULL AS last_observed_model_key",
|
|
152972
153120
|
upgrade_reminded_at: "NULL AS upgrade_reminded_at"
|
|
152973
153121
|
};
|
|
@@ -153007,7 +153155,8 @@ function toNote(row) {
|
|
|
153007
153155
|
updatedAt: row.updated_at,
|
|
153008
153156
|
lastCheckedAt: toNullableNumber(row.last_checked_at),
|
|
153009
153157
|
readyAt: toNullableNumber(row.ready_at),
|
|
153010
|
-
readyReason: toNullableString(row.ready_reason)
|
|
153158
|
+
readyReason: toNullableString(row.ready_reason),
|
|
153159
|
+
anchorOrdinal: toNullableNumber(row.anchor_ordinal)
|
|
153011
153160
|
};
|
|
153012
153161
|
}
|
|
153013
153162
|
function getNoteById(db, noteId) {
|
|
@@ -153059,7 +153208,7 @@ function getNotes(db, options = {}) {
|
|
|
153059
153208
|
}
|
|
153060
153209
|
function addNote(db, type, options) {
|
|
153061
153210
|
const now = Date.now();
|
|
153062
|
-
const result = type === "session" ? db.prepare("INSERT INTO notes (type, status, content, session_id, created_at, updated_at, harness) VALUES ('session', 'active', ?, ?, ?, ?, ?) RETURNING *").get(options.content, options.sessionId, now, now, getHarness()) : db.prepare("INSERT INTO notes (type, status, content, session_id, project_path, surface_condition, created_at, updated_at, harness) VALUES ('smart', 'pending', ?, ?, ?, ?, ?, ?, ?) RETURNING *").get(options.content, options.sessionId ?? null, options.projectPath, options.surfaceCondition, now, now, getHarness());
|
|
153211
|
+
const result = type === "session" ? db.prepare("INSERT INTO notes (type, status, content, session_id, created_at, updated_at, harness, anchor_ordinal) VALUES ('session', 'active', ?, ?, ?, ?, ?, ?) RETURNING *").get(options.content, options.sessionId, now, now, getHarness(), options.anchorOrdinal ?? null) : db.prepare("INSERT INTO notes (type, status, content, session_id, project_path, surface_condition, created_at, updated_at, harness, anchor_ordinal) VALUES ('smart', 'pending', ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *").get(options.content, options.sessionId ?? null, options.projectPath, options.surfaceCondition, now, now, getHarness(), options.anchorOrdinal ?? null);
|
|
153063
153212
|
if (!isNoteRow(result)) {
|
|
153064
153213
|
throw new Error("[notes] failed to insert note");
|
|
153065
153214
|
}
|
|
@@ -162943,25 +163092,56 @@ var require_src2 = __commonJS((exports, module) => {
|
|
|
162943
163092
|
// src/features/magic-context/key-files/aft-availability.ts
|
|
162944
163093
|
import { existsSync as existsSync9, readFileSync as readFileSync7 } from "node:fs";
|
|
162945
163094
|
import { homedir as homedir6 } from "node:os";
|
|
162946
|
-
import { join as join10 } from "node:path";
|
|
163095
|
+
import { isAbsolute as isAbsolute2, join as join10, resolve as resolve4 } from "node:path";
|
|
163096
|
+
import { fileURLToPath } from "node:url";
|
|
162947
163097
|
function parseConfig(path6) {
|
|
162948
163098
|
if (!existsSync9(path6))
|
|
162949
163099
|
return null;
|
|
162950
163100
|
return import_comment_json.parse(readFileSync7(path6, "utf-8"));
|
|
162951
163101
|
}
|
|
162952
|
-
function
|
|
163102
|
+
function stringMentionsAft(value) {
|
|
163103
|
+
return AFT_NAME_NEEDLES.some((needle) => value.includes(needle));
|
|
163104
|
+
}
|
|
163105
|
+
function resolveLocalEntryPackageName(value, configDir) {
|
|
163106
|
+
let dir = null;
|
|
163107
|
+
if (value.startsWith("file://")) {
|
|
163108
|
+
try {
|
|
163109
|
+
dir = fileURLToPath(value);
|
|
163110
|
+
} catch {
|
|
163111
|
+
return null;
|
|
163112
|
+
}
|
|
163113
|
+
} else if (value.startsWith("~/")) {
|
|
163114
|
+
dir = join10(homedir6(), value.slice(2));
|
|
163115
|
+
} else if (value.startsWith("/") || value.startsWith("./") || value.startsWith("../")) {
|
|
163116
|
+
dir = isAbsolute2(value) ? value : resolve4(configDir, value);
|
|
163117
|
+
} else {
|
|
163118
|
+
return null;
|
|
163119
|
+
}
|
|
163120
|
+
try {
|
|
163121
|
+
const pkg = JSON.parse(readFileSync7(join10(dir, "package.json"), "utf-8"));
|
|
163122
|
+
return typeof pkg.name === "string" ? pkg.name : null;
|
|
163123
|
+
} catch {
|
|
163124
|
+
return null;
|
|
163125
|
+
}
|
|
163126
|
+
}
|
|
163127
|
+
function entryMatchesAft(entry, configDir) {
|
|
162953
163128
|
const value = Array.isArray(entry) ? entry[0] : entry;
|
|
162954
|
-
|
|
163129
|
+
if (typeof value !== "string")
|
|
163130
|
+
return false;
|
|
163131
|
+
if (stringMentionsAft(value))
|
|
163132
|
+
return true;
|
|
163133
|
+
const name2 = resolveLocalEntryPackageName(value, configDir);
|
|
163134
|
+
return name2 != null && stringMentionsAft(name2);
|
|
162955
163135
|
}
|
|
162956
|
-
function hasAftInArray(value) {
|
|
162957
|
-
return Array.isArray(value) && value.some(entryMatchesAft);
|
|
163136
|
+
function hasAftInArray(value, configDir) {
|
|
163137
|
+
return Array.isArray(value) && value.some((entry) => entryMatchesAft(entry, configDir));
|
|
162958
163138
|
}
|
|
162959
|
-
function hasAftAtKeys(value, keys) {
|
|
163139
|
+
function hasAftAtKeys(value, keys, configDir) {
|
|
162960
163140
|
if (!value || typeof value !== "object")
|
|
162961
163141
|
return false;
|
|
162962
163142
|
const record2 = value;
|
|
162963
163143
|
for (const key of keys) {
|
|
162964
|
-
if (hasAftInArray(record2[key]))
|
|
163144
|
+
if (hasAftInArray(record2[key], configDir))
|
|
162965
163145
|
return true;
|
|
162966
163146
|
}
|
|
162967
163147
|
return false;
|
|
@@ -162978,7 +163158,8 @@ function getAftAvailability() {
|
|
|
162978
163158
|
for (const path6 of opencodePaths) {
|
|
162979
163159
|
try {
|
|
162980
163160
|
const config2 = parseConfig(path6);
|
|
162981
|
-
|
|
163161
|
+
const configDir = join10(path6, "..");
|
|
163162
|
+
if (hasAftAtKeys(config2, ["plugin", "plugins", "mcp", "mcp_servers"], configDir)) {
|
|
162982
163163
|
opencode = true;
|
|
162983
163164
|
break;
|
|
162984
163165
|
}
|
|
@@ -162988,12 +163169,13 @@ function getAftAvailability() {
|
|
|
162988
163169
|
for (const path6 of piPaths) {
|
|
162989
163170
|
try {
|
|
162990
163171
|
const config2 = parseConfig(path6);
|
|
162991
|
-
|
|
163172
|
+
const configDir = join10(path6, "..");
|
|
163173
|
+
if (hasAftAtKeys(config2, ["packages", "extensions"], configDir)) {
|
|
162992
163174
|
pi = true;
|
|
162993
163175
|
break;
|
|
162994
163176
|
}
|
|
162995
163177
|
const agent = config2?.agent;
|
|
162996
|
-
if (hasAftAtKeys(agent, ["packages", "extensions"])) {
|
|
163178
|
+
if (hasAftAtKeys(agent, ["packages", "extensions"], configDir)) {
|
|
162997
163179
|
pi = true;
|
|
162998
163180
|
break;
|
|
162999
163181
|
}
|
|
@@ -163010,9 +163192,10 @@ function getAftAvailability() {
|
|
|
163010
163192
|
function isAftAvailable() {
|
|
163011
163193
|
return getAftAvailability().available;
|
|
163012
163194
|
}
|
|
163013
|
-
var import_comment_json, overrideAvailability = null;
|
|
163195
|
+
var import_comment_json, overrideAvailability = null, AFT_NAME_NEEDLES;
|
|
163014
163196
|
var init_aft_availability = __esm(() => {
|
|
163015
163197
|
import_comment_json = __toESM(require_src2(), 1);
|
|
163198
|
+
AFT_NAME_NEEDLES = ["@cortexkit/aft", "aft-opencode", "aft-pi"];
|
|
163016
163199
|
});
|
|
163017
163200
|
|
|
163018
163201
|
// src/features/magic-context/memory/storage-memory-embeddings.ts
|
|
@@ -163697,7 +163880,7 @@ async function acquireModelLoadLock(lockPath) {
|
|
|
163697
163880
|
if (Date.now() - waitStart > MAX_LOCK_WAIT_MS) {
|
|
163698
163881
|
throw new Error(`[magic-context] embedding-load lock wait exceeded ${MAX_LOCK_WAIT_MS}ms; another process is still loading the model. Skipping this init attempt to avoid an unsynchronized native load.`);
|
|
163699
163882
|
}
|
|
163700
|
-
await new Promise((
|
|
163883
|
+
await new Promise((resolve6) => setTimeout(resolve6, LOCK_POLL_MS));
|
|
163701
163884
|
}
|
|
163702
163885
|
}
|
|
163703
163886
|
}
|
|
@@ -163866,7 +164049,7 @@ class LocalEmbeddingProvider {
|
|
|
163866
164049
|
}
|
|
163867
164050
|
const delayMs = 300 * attempt + Math.floor(Math.random() * 200);
|
|
163868
164051
|
log(`[magic-context] embedding model load attempt ${attempt}/${MAX_ATTEMPTS} failed transiently, retrying in ${delayMs}ms`);
|
|
163869
|
-
await new Promise((
|
|
164052
|
+
await new Promise((resolve6) => setTimeout(resolve6, delayMs));
|
|
163870
164053
|
}
|
|
163871
164054
|
}
|
|
163872
164055
|
if (this.pipeline) {
|
|
@@ -163894,8 +164077,8 @@ class LocalEmbeddingProvider {
|
|
|
163894
164077
|
if (this.inFlight === 0) {
|
|
163895
164078
|
return Promise.resolve();
|
|
163896
164079
|
}
|
|
163897
|
-
return new Promise((
|
|
163898
|
-
this.inFlightWaiters.push(
|
|
164080
|
+
return new Promise((resolve6) => {
|
|
164081
|
+
this.inFlightWaiters.push(resolve6);
|
|
163899
164082
|
});
|
|
163900
164083
|
}
|
|
163901
164084
|
finishInFlight() {
|
|
@@ -164322,8 +164505,130 @@ var init_storage_git_commit_embeddings = __esm(() => {
|
|
|
164322
164505
|
distinctModelIdStatements = new WeakMap;
|
|
164323
164506
|
});
|
|
164324
164507
|
|
|
164508
|
+
// src/features/magic-context/git-commits/sweep-coordinator.ts
|
|
164509
|
+
function runImmediate2(db, body) {
|
|
164510
|
+
db.exec("BEGIN IMMEDIATE");
|
|
164511
|
+
let committed = false;
|
|
164512
|
+
try {
|
|
164513
|
+
const result = body();
|
|
164514
|
+
db.exec("COMMIT");
|
|
164515
|
+
committed = true;
|
|
164516
|
+
return result;
|
|
164517
|
+
} finally {
|
|
164518
|
+
if (!committed) {
|
|
164519
|
+
try {
|
|
164520
|
+
db.exec("ROLLBACK");
|
|
164521
|
+
} catch {}
|
|
164522
|
+
}
|
|
164523
|
+
}
|
|
164524
|
+
}
|
|
164525
|
+
function rowToState(row) {
|
|
164526
|
+
return {
|
|
164527
|
+
projectPath: row.project_path,
|
|
164528
|
+
leaseHolder: row.lease_holder,
|
|
164529
|
+
leaseExpiresAt: row.lease_expires_at,
|
|
164530
|
+
lastSweptAt: row.last_swept_at
|
|
164531
|
+
};
|
|
164532
|
+
}
|
|
164533
|
+
function getGitSweepCoordinatorState(db, projectPath) {
|
|
164534
|
+
const row = db.prepare(`SELECT project_path, lease_holder, lease_expires_at, last_swept_at
|
|
164535
|
+
FROM git_sweep_coordinator
|
|
164536
|
+
WHERE project_path = ?`).get(projectPath);
|
|
164537
|
+
return row ? rowToState(row) : null;
|
|
164538
|
+
}
|
|
164539
|
+
function acquireGitSweepLease(db, projectPath, holderId, options = {}) {
|
|
164540
|
+
const cooldownMs = options.cooldownMs ?? GIT_SWEEP_COOLDOWN_MS;
|
|
164541
|
+
const leaseTtlMs = options.leaseTtlMs ?? GIT_SWEEP_LEASE_TTL_MS;
|
|
164542
|
+
return runImmediate2(db, () => {
|
|
164543
|
+
const now = Date.now();
|
|
164544
|
+
const row = getGitSweepCoordinatorState(db, projectPath);
|
|
164545
|
+
if (row?.leaseHolder && row.leaseExpiresAt !== null && row.leaseExpiresAt > now) {
|
|
164546
|
+
return {
|
|
164547
|
+
acquired: false,
|
|
164548
|
+
projectPath,
|
|
164549
|
+
reason: "lease_active",
|
|
164550
|
+
leaseHolder: row.leaseHolder,
|
|
164551
|
+
leaseExpiresAt: row.leaseExpiresAt,
|
|
164552
|
+
lastSweptAt: row.lastSweptAt,
|
|
164553
|
+
nextAllowedAt: null
|
|
164554
|
+
};
|
|
164555
|
+
}
|
|
164556
|
+
if (!options.ignoreCooldown && row?.lastSweptAt !== null && row?.lastSweptAt !== undefined) {
|
|
164557
|
+
const nextAllowedAt = row.lastSweptAt + cooldownMs;
|
|
164558
|
+
if (nextAllowedAt > now) {
|
|
164559
|
+
return {
|
|
164560
|
+
acquired: false,
|
|
164561
|
+
projectPath,
|
|
164562
|
+
reason: "cooldown_active",
|
|
164563
|
+
leaseHolder: row.leaseHolder,
|
|
164564
|
+
leaseExpiresAt: row.leaseExpiresAt,
|
|
164565
|
+
lastSweptAt: row.lastSweptAt,
|
|
164566
|
+
nextAllowedAt
|
|
164567
|
+
};
|
|
164568
|
+
}
|
|
164569
|
+
}
|
|
164570
|
+
const leaseExpiresAt = now + leaseTtlMs;
|
|
164571
|
+
db.prepare(`INSERT INTO git_sweep_coordinator (
|
|
164572
|
+
project_path,
|
|
164573
|
+
lease_holder,
|
|
164574
|
+
lease_expires_at,
|
|
164575
|
+
last_swept_at
|
|
164576
|
+
) VALUES (?, ?, ?, NULL)
|
|
164577
|
+
ON CONFLICT(project_path) DO UPDATE SET
|
|
164578
|
+
lease_holder = excluded.lease_holder,
|
|
164579
|
+
lease_expires_at = excluded.lease_expires_at`).run(projectPath, holderId, leaseExpiresAt);
|
|
164580
|
+
return {
|
|
164581
|
+
acquired: true,
|
|
164582
|
+
projectPath,
|
|
164583
|
+
holderId,
|
|
164584
|
+
acquiredAt: now,
|
|
164585
|
+
leaseExpiresAt
|
|
164586
|
+
};
|
|
164587
|
+
});
|
|
164588
|
+
}
|
|
164589
|
+
function renewGitSweepLease(db, projectPath, holderId, leaseTtlMs = GIT_SWEEP_LEASE_TTL_MS) {
|
|
164590
|
+
return runImmediate2(db, () => {
|
|
164591
|
+
const now = Date.now();
|
|
164592
|
+
const leaseExpiresAt = now + leaseTtlMs;
|
|
164593
|
+
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
164594
|
+
SET lease_expires_at = ?
|
|
164595
|
+
WHERE project_path = ?
|
|
164596
|
+
AND lease_holder = ?
|
|
164597
|
+
AND lease_expires_at > ?`).run(leaseExpiresAt, projectPath, holderId, now);
|
|
164598
|
+
return result.changes === 1;
|
|
164599
|
+
});
|
|
164600
|
+
}
|
|
164601
|
+
function markGitSweepSuccessAndRelease(db, projectPath, holderId) {
|
|
164602
|
+
return runImmediate2(db, () => {
|
|
164603
|
+
const now = Date.now();
|
|
164604
|
+
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
164605
|
+
SET lease_holder = NULL,
|
|
164606
|
+
lease_expires_at = NULL,
|
|
164607
|
+
last_swept_at = ?
|
|
164608
|
+
WHERE project_path = ?
|
|
164609
|
+
AND lease_holder = ?
|
|
164610
|
+
AND lease_expires_at > ?`).run(now, projectPath, holderId, now);
|
|
164611
|
+
return result.changes === 1;
|
|
164612
|
+
});
|
|
164613
|
+
}
|
|
164614
|
+
function releaseGitSweepLease(db, projectPath, holderId) {
|
|
164615
|
+
runImmediate2(db, () => {
|
|
164616
|
+
db.prepare(`UPDATE git_sweep_coordinator
|
|
164617
|
+
SET lease_holder = NULL,
|
|
164618
|
+
lease_expires_at = NULL
|
|
164619
|
+
WHERE project_path = ?
|
|
164620
|
+
AND lease_holder = ?`).run(projectPath, holderId);
|
|
164621
|
+
});
|
|
164622
|
+
}
|
|
164623
|
+
var GIT_SWEEP_COOLDOWN_MS, GIT_SWEEP_LEASE_TTL_MS, GIT_SWEEP_LEASE_RENEWAL_MS;
|
|
164624
|
+
var init_sweep_coordinator = __esm(() => {
|
|
164625
|
+
GIT_SWEEP_COOLDOWN_MS = 10 * 60 * 1000;
|
|
164626
|
+
GIT_SWEEP_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
164627
|
+
GIT_SWEEP_LEASE_RENEWAL_MS = 60 * 1000;
|
|
164628
|
+
});
|
|
164629
|
+
|
|
164325
164630
|
// src/features/magic-context/project-embedding-registry.ts
|
|
164326
|
-
import { createHash as createHash7 } from "node:crypto";
|
|
164631
|
+
import { createHash as createHash7, randomUUID } from "node:crypto";
|
|
164327
164632
|
function resolveEmbeddingConfig(config2) {
|
|
164328
164633
|
if (!config2 || config2.provider === "local") {
|
|
164329
164634
|
return {
|
|
@@ -164587,6 +164892,7 @@ var init_project_embedding_registry = __esm(() => {
|
|
|
164587
164892
|
init_magic_context();
|
|
164588
164893
|
init_logger();
|
|
164589
164894
|
init_storage_git_commit_embeddings();
|
|
164895
|
+
init_sweep_coordinator();
|
|
164590
164896
|
init_embedding_cache();
|
|
164591
164897
|
init_embedding_identity();
|
|
164592
164898
|
init_embedding_local();
|
|
@@ -164685,32 +164991,48 @@ var init_storage_memory_fts = __esm(() => {
|
|
|
164685
164991
|
});
|
|
164686
164992
|
|
|
164687
164993
|
// src/shared/models-dev-cache.ts
|
|
164688
|
-
import {
|
|
164689
|
-
import { existsSync as existsSync11, readFileSync as readFileSync9 } from "node:fs";
|
|
164690
|
-
import { homedir as homedir7, platform as platform2 } from "node:os";
|
|
164994
|
+
import { mkdirSync as mkdirSync4, readFileSync as readFileSync9, renameSync, writeFileSync } from "node:fs";
|
|
164691
164995
|
import { join as join14 } from "node:path";
|
|
164692
|
-
function
|
|
164693
|
-
return
|
|
164694
|
-
}
|
|
164695
|
-
function
|
|
164696
|
-
|
|
164697
|
-
|
|
164698
|
-
|
|
164699
|
-
|
|
164700
|
-
|
|
164701
|
-
|
|
164702
|
-
|
|
164703
|
-
|
|
164704
|
-
|
|
164705
|
-
|
|
164706
|
-
|
|
164707
|
-
|
|
164708
|
-
|
|
164709
|
-
|
|
164710
|
-
|
|
164711
|
-
|
|
164712
|
-
|
|
164713
|
-
|
|
164996
|
+
function isSaneLimit(limit) {
|
|
164997
|
+
return typeof limit === "number" && limit >= MIN_SANE_LIMIT && limit <= MAX_SANE_LIMIT;
|
|
164998
|
+
}
|
|
164999
|
+
function persistFilePath() {
|
|
165000
|
+
return join14(getMagicContextStorageDir(), `model-context-limits-${getHarness()}.json`);
|
|
165001
|
+
}
|
|
165002
|
+
function loadPersistedApiCacheOnce() {
|
|
165003
|
+
if (persistSeedLoaded || apiCache !== null)
|
|
165004
|
+
return;
|
|
165005
|
+
persistSeedLoaded = true;
|
|
165006
|
+
try {
|
|
165007
|
+
const raw = readFileSync9(persistFilePath(), "utf-8");
|
|
165008
|
+
const obj = JSON.parse(raw);
|
|
165009
|
+
const map2 = new Map;
|
|
165010
|
+
for (const [key, limit] of Object.entries(obj)) {
|
|
165011
|
+
if (isSaneLimit(limit))
|
|
165012
|
+
map2.set(key, { limit });
|
|
165013
|
+
}
|
|
165014
|
+
if (map2.size > 0) {
|
|
165015
|
+
apiCache = map2;
|
|
165016
|
+
sessionLog("global", `models-dev-cache: seeded ${map2.size} entries from persisted cache (cold start)`);
|
|
165017
|
+
}
|
|
165018
|
+
} catch {}
|
|
165019
|
+
}
|
|
165020
|
+
function persistApiCache() {
|
|
165021
|
+
if (!apiCache)
|
|
165022
|
+
return;
|
|
165023
|
+
const obj = {};
|
|
165024
|
+
for (const [key, value] of apiCache) {
|
|
165025
|
+
if (isSaneLimit(value.limit))
|
|
165026
|
+
obj[key] = value.limit;
|
|
165027
|
+
}
|
|
165028
|
+
try {
|
|
165029
|
+
const dir = getMagicContextStorageDir();
|
|
165030
|
+
mkdirSync4(dir, { recursive: true });
|
|
165031
|
+
const target = persistFilePath();
|
|
165032
|
+
const tmp = `${target}.${process.pid}.tmp`;
|
|
165033
|
+
writeFileSync(tmp, JSON.stringify(obj), { encoding: "utf-8", mode: 384 });
|
|
165034
|
+
renameSync(tmp, target);
|
|
165035
|
+
} catch {}
|
|
164714
165036
|
}
|
|
164715
165037
|
function resolveLimit(limit) {
|
|
164716
165038
|
if (!limit)
|
|
@@ -164723,7 +165045,7 @@ function resolveLimit(limit) {
|
|
|
164723
165045
|
}
|
|
164724
165046
|
function setCachedModelMetadata(cache, key, model) {
|
|
164725
165047
|
const limit = resolveLimit(model?.limit);
|
|
164726
|
-
if (limit
|
|
165048
|
+
if (!isSaneLimit(limit)) {
|
|
164727
165049
|
return;
|
|
164728
165050
|
}
|
|
164729
165051
|
const value = { limit };
|
|
@@ -164735,54 +165057,26 @@ function setCachedModelMetadata(cache, key, model) {
|
|
|
164735
165057
|
}
|
|
164736
165058
|
}
|
|
164737
165059
|
}
|
|
164738
|
-
function
|
|
164739
|
-
const
|
|
164740
|
-
const
|
|
164741
|
-
let
|
|
164742
|
-
|
|
164743
|
-
if (
|
|
164744
|
-
|
|
164745
|
-
|
|
164746
|
-
|
|
164747
|
-
for (const [providerId, provider2] of Object.entries(data)) {
|
|
164748
|
-
if (!provider2?.models || typeof provider2.models !== "object")
|
|
164749
|
-
continue;
|
|
164750
|
-
for (const [modelId, model] of Object.entries(provider2.models)) {
|
|
164751
|
-
setCachedModelMetadata(metadata, `${providerId}/${modelId}`, model);
|
|
164752
|
-
}
|
|
164753
|
-
}
|
|
164754
|
-
}
|
|
164755
|
-
} catch (error51) {
|
|
164756
|
-
sessionLog("global", `models-dev-cache: failed to read models.json at ${modelsJsonPath}:`, error51 instanceof Error ? error51.message : String(error51));
|
|
164757
|
-
}
|
|
164758
|
-
try {
|
|
164759
|
-
const configPath = getOpencodeConfigPath();
|
|
164760
|
-
if (configPath && existsSync11(configPath)) {
|
|
164761
|
-
const config2 = parseJsonc(readFileSync9(configPath, "utf-8"));
|
|
164762
|
-
if (config2.provider && typeof config2.provider === "object") {
|
|
164763
|
-
for (const [providerId, provider2] of Object.entries(config2.provider)) {
|
|
164764
|
-
if (!provider2?.models || typeof provider2.models !== "object")
|
|
164765
|
-
continue;
|
|
164766
|
-
for (const [modelId, model] of Object.entries(provider2.models)) {
|
|
164767
|
-
setCachedModelMetadata(metadata, `${providerId}/${modelId}`, model);
|
|
164768
|
-
}
|
|
164769
|
-
}
|
|
164770
|
-
}
|
|
165060
|
+
async function refreshModelLimitsFromApi(client, options) {
|
|
165061
|
+
const attempts = Math.max(1, (options?.retries ?? 0) + 1);
|
|
165062
|
+
const delayMs = options?.retryDelayMs ?? 1000;
|
|
165063
|
+
for (let attempt = 1;attempt <= attempts; attempt++) {
|
|
165064
|
+
const ok = await refreshModelLimitsOnce(client);
|
|
165065
|
+
if (ok)
|
|
165066
|
+
return;
|
|
165067
|
+
if (attempt < attempts) {
|
|
165068
|
+
await new Promise((resolve6) => setTimeout(resolve6, delayMs));
|
|
164771
165069
|
}
|
|
164772
|
-
} catch (error51) {
|
|
164773
|
-
sessionLog("global", "models-dev-cache: failed to read opencode config for custom models:", error51 instanceof Error ? error51.message : String(error51));
|
|
164774
165070
|
}
|
|
164775
|
-
sessionLog("global", `models-dev-cache: file-layer loaded ${metadata.size} model metadata entries (modelsJsonPath=${modelsJsonPath}, found=${fileFound})`);
|
|
164776
|
-
return metadata;
|
|
164777
165071
|
}
|
|
164778
|
-
async function
|
|
165072
|
+
async function refreshModelLimitsOnce(client) {
|
|
164779
165073
|
try {
|
|
164780
165074
|
const result = await client.config.providers();
|
|
164781
165075
|
const data = result.data;
|
|
164782
165076
|
const providers = data?.providers;
|
|
164783
|
-
if (!Array.isArray(providers)) {
|
|
164784
|
-
sessionLog("global", "models-dev-cache: API refresh returned no providers payload");
|
|
164785
|
-
return;
|
|
165077
|
+
if (!Array.isArray(providers) || providers.length === 0) {
|
|
165078
|
+
sessionLog("global", "models-dev-cache: API refresh returned no providers payload (will retry if attempts remain)");
|
|
165079
|
+
return false;
|
|
164786
165080
|
}
|
|
164787
165081
|
const map2 = new Map;
|
|
164788
165082
|
for (const entry of providers) {
|
|
@@ -164796,27 +165090,22 @@ async function refreshModelLimitsFromApi(client) {
|
|
|
164796
165090
|
const previousSize = apiCache?.size ?? null;
|
|
164797
165091
|
apiCache = map2;
|
|
164798
165092
|
apiLoadedAt = Date.now();
|
|
165093
|
+
persistApiCache();
|
|
164799
165094
|
if (previousSize === null) {
|
|
164800
165095
|
sessionLog("global", `models-dev-cache: API layer loaded ${map2.size} model metadata entries`);
|
|
164801
165096
|
} else if (previousSize !== map2.size) {
|
|
164802
165097
|
sessionLog("global", `models-dev-cache: API layer loaded ${map2.size} model metadata entries (was ${previousSize})`);
|
|
164803
165098
|
}
|
|
165099
|
+
return true;
|
|
164804
165100
|
} catch (error51) {
|
|
164805
165101
|
sessionLog("global", "models-dev-cache: API refresh failed:", error51 instanceof Error ? error51.message : String(error51));
|
|
165102
|
+
return false;
|
|
164806
165103
|
}
|
|
164807
165104
|
}
|
|
164808
|
-
function
|
|
164809
|
-
|
|
164810
|
-
if (!fileCache || now - fileLastAttempt > RELOAD_INTERVAL_MS) {
|
|
164811
|
-
fileLastAttempt = now;
|
|
164812
|
-
fileCache = loadModelsDevMetadataFromFile();
|
|
164813
|
-
}
|
|
165105
|
+
function getSdkContextLimit(providerID, modelID) {
|
|
165106
|
+
loadPersistedApiCacheOnce();
|
|
164814
165107
|
const fromApi = lookupLimitWithTagFallback(apiCache, providerID, modelID);
|
|
164815
|
-
|
|
164816
|
-
if (typeof fromApi === "number" && typeof fromFile === "number") {
|
|
164817
|
-
return Math.max(fromApi, fromFile);
|
|
164818
|
-
}
|
|
164819
|
-
return fromApi ?? fromFile;
|
|
165108
|
+
return isSaneLimit(fromApi) ? fromApi : undefined;
|
|
164820
165109
|
}
|
|
164821
165110
|
function lookupLimitWithTagFallback(cache, providerID, modelID) {
|
|
164822
165111
|
if (!cache)
|
|
@@ -164833,12 +165122,10 @@ function lookupLimitWithTagFallback(cache, providerID, modelID) {
|
|
|
164833
165122
|
}
|
|
164834
165123
|
return;
|
|
164835
165124
|
}
|
|
164836
|
-
var
|
|
165125
|
+
var MIN_SANE_LIMIT = 20000, MAX_SANE_LIMIT = 3000000, apiCache = null, apiLoadedAt = 0, persistSeedLoaded = false;
|
|
164837
165126
|
var init_models_dev_cache = __esm(() => {
|
|
164838
165127
|
init_data_path();
|
|
164839
|
-
init_jsonc_parser();
|
|
164840
165128
|
init_logger();
|
|
164841
|
-
RELOAD_INTERVAL_MS = 5 * 60 * 1000;
|
|
164842
165129
|
});
|
|
164843
165130
|
|
|
164844
165131
|
// src/shared/rpc-notifications.ts
|
|
@@ -165564,7 +165851,7 @@ var init_compartment_runner_validation = __esm(async () => {
|
|
|
165564
165851
|
});
|
|
165565
165852
|
|
|
165566
165853
|
// src/hooks/magic-context/compartment-runner-historian.ts
|
|
165567
|
-
import { mkdirSync as
|
|
165854
|
+
import { mkdirSync as mkdirSync5, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
165568
165855
|
import { join as join17 } from "node:path";
|
|
165569
165856
|
function historianResponseDumpDir(directory) {
|
|
165570
165857
|
return getProjectMagicContextHistorianDir(directory);
|
|
@@ -165764,12 +166051,12 @@ async function runHistorianPrompt(args) {
|
|
|
165764
166051
|
error: `Historian failed while processing this session: ${desc.brief}`
|
|
165765
166052
|
};
|
|
165766
166053
|
} finally {
|
|
165767
|
-
if (agentSessionId && outcomeOk) {
|
|
166054
|
+
if (agentSessionId && outcomeOk && !shouldKeepSubagents()) {
|
|
165768
166055
|
await client.session.delete({ path: { id: agentSessionId } }).catch((e) => {
|
|
165769
166056
|
sessionLog(parentSessionId, "compartment agent: session cleanup failed", getErrorMessage(e));
|
|
165770
166057
|
});
|
|
165771
|
-
} else if (agentSessionId && !outcomeOk) {
|
|
165772
|
-
sessionLog(parentSessionId, `historian: KEEPING
|
|
166058
|
+
} else if (agentSessionId && (!outcomeOk || shouldKeepSubagents())) {
|
|
166059
|
+
sessionLog(parentSessionId, `historian: KEEPING child session ${agentSessionId} (${outcomeOk ? "keep_subagents" : "failed"}) — not deleted`);
|
|
165773
166060
|
}
|
|
165774
166061
|
}
|
|
165775
166062
|
}
|
|
@@ -165848,8 +166135,8 @@ function isTransientHistorianPromptError(message) {
|
|
|
165848
166135
|
].some((token) => normalized.includes(token));
|
|
165849
166136
|
}
|
|
165850
166137
|
function sleep(ms) {
|
|
165851
|
-
return new Promise((
|
|
165852
|
-
setTimeout(
|
|
166138
|
+
return new Promise((resolve6) => {
|
|
166139
|
+
setTimeout(resolve6, ms);
|
|
165853
166140
|
});
|
|
165854
166141
|
}
|
|
165855
166142
|
function cleanupHistorianDump(sessionId, dumpPath) {
|
|
@@ -165867,11 +166154,11 @@ function cleanupHistorianDump(sessionId, dumpPath) {
|
|
|
165867
166154
|
function dumpHistorianResponse(sessionId, directory, label, text) {
|
|
165868
166155
|
try {
|
|
165869
166156
|
const dumpDir = historianResponseDumpDir(directory);
|
|
165870
|
-
|
|
166157
|
+
mkdirSync5(dumpDir, { recursive: true });
|
|
165871
166158
|
const safeSessionId = sanitizeDumpName(sessionId);
|
|
165872
166159
|
const safeLabel = sanitizeDumpName(label);
|
|
165873
166160
|
const dumpPath = join17(dumpDir, `${safeSessionId}-${safeLabel}-${Date.now()}.xml`);
|
|
165874
|
-
|
|
166161
|
+
writeFileSync2(dumpPath, text, "utf8");
|
|
165875
166162
|
sessionLog(sessionId, "compartment agent: historian response dumped", {
|
|
165876
166163
|
label,
|
|
165877
166164
|
dumpPath
|
|
@@ -165993,7 +166280,7 @@ function insertCompartmentEvents(db, sessionId, events, compartmentIds) {
|
|
|
165993
166280
|
var init_compartment_events = () => {};
|
|
165994
166281
|
|
|
165995
166282
|
// src/hooks/magic-context/historian-state-file.ts
|
|
165996
|
-
import { mkdirSync as
|
|
166283
|
+
import { mkdirSync as mkdirSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
165997
166284
|
function cleanupHistorianStateFile(path6) {
|
|
165998
166285
|
if (!path6)
|
|
165999
166286
|
return;
|
|
@@ -166548,9 +166835,7 @@ function injectTemporalMarkers(messages) {
|
|
|
166548
166835
|
if (prefix && Array.isArray(msg.parts)) {
|
|
166549
166836
|
const target = findFirstVisibleTextPart(msg.parts);
|
|
166550
166837
|
if (target && typeof target.text === "string") {
|
|
166551
|
-
const
|
|
166552
|
-
const tagPrefix = tagMatch ? tagMatch[0] : "";
|
|
166553
|
-
const body = target.text.slice(tagPrefix.length);
|
|
166838
|
+
const { tagPrefix, body } = peelLeadingMcTagNotation(target.text);
|
|
166554
166839
|
if (!TEMPORAL_MARKER_PATTERN.test(body)) {
|
|
166555
166840
|
target.text = tagPrefix + prefix + body;
|
|
166556
166841
|
injected++;
|
|
@@ -166565,6 +166850,7 @@ function injectTemporalMarkers(messages) {
|
|
|
166565
166850
|
}
|
|
166566
166851
|
var TEMPORAL_AWARENESS_THRESHOLD_SECONDS = 300, SECONDS_PER_MINUTE = 60, SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK, TEMPORAL_MARKER_PATTERN;
|
|
166567
166852
|
var init_temporal_awareness = __esm(() => {
|
|
166853
|
+
init_tag_content_primitives();
|
|
166568
166854
|
SECONDS_PER_HOUR = 60 * 60;
|
|
166569
166855
|
SECONDS_PER_DAY = 24 * 60 * 60;
|
|
166570
166856
|
SECONDS_PER_WEEK = 7 * 24 * 60 * 60;
|
|
@@ -166859,12 +167145,6 @@ function getMaxCompartmentSeq(db, sessionId) {
|
|
|
166859
167145
|
const row = cachedStatement(maxCompartmentSeqStatements, db, "SELECT COALESCE(MAX(sequence), -1) AS s FROM compartments WHERE session_id = ?").get(sessionId);
|
|
166860
167146
|
return numberFromRow(row, "s");
|
|
166861
167147
|
}
|
|
166862
|
-
function normalizeCachedMaxCompartmentSeq(db, sessionId, stored) {
|
|
166863
|
-
if (stored === 0 && getMaxCompartmentSeq(db, sessionId) === EMPTY_MAX_COMPARTMENT_SEQ) {
|
|
166864
|
-
return EMPTY_MAX_COMPARTMENT_SEQ;
|
|
166865
|
-
}
|
|
166866
|
-
return stored;
|
|
166867
|
-
}
|
|
166868
167148
|
function getMaxMemoryId(db, projectPath) {
|
|
166869
167149
|
if (!projectPath)
|
|
166870
167150
|
return 0;
|
|
@@ -166888,6 +167168,7 @@ function getGlobalUserProfileVersion(db) {
|
|
|
166888
167168
|
}
|
|
166889
167169
|
function readCurrentM0SnapshotMarkers(args) {
|
|
166890
167170
|
const projectDirectory = args.projectDirectory ?? args.projectPath ?? "";
|
|
167171
|
+
const hard = args.hardSignals ?? EMPTY_HARD_SIGNALS;
|
|
166891
167172
|
return {
|
|
166892
167173
|
projectMemoryEpoch: getProjectMemoryEpoch(args.db, args.projectPath),
|
|
166893
167174
|
projectUserProfileVersion: getGlobalUserProfileVersion(args.db),
|
|
@@ -166898,7 +167179,10 @@ function readCurrentM0SnapshotMarkers(args) {
|
|
|
166898
167179
|
projectDocsHash: projectDirectory ? computeProjectDocsHash(projectDirectory) : "",
|
|
166899
167180
|
materializedAt: Date.now(),
|
|
166900
167181
|
sessionFactsVersion: getSessionFactsVersion(args.db, args.sessionId),
|
|
166901
|
-
upgradeState: getUpgradeState(args.db, args.sessionId)
|
|
167182
|
+
upgradeState: getUpgradeState(args.db, args.sessionId),
|
|
167183
|
+
systemHash: hard.systemHash,
|
|
167184
|
+
toolSetHash: hard.toolSetHash,
|
|
167185
|
+
modelKey: hard.modelKey
|
|
166902
167186
|
};
|
|
166903
167187
|
}
|
|
166904
167188
|
function snapshotMarkersFromCachedM0(state) {
|
|
@@ -166928,7 +167212,10 @@ function snapshotMarkersFromCachedM0(state) {
|
|
|
166928
167212
|
projectDocsHash: state.cachedM0ProjectDocsHash ?? "",
|
|
166929
167213
|
materializedAt: state.cachedM0MaterializedAt ?? 0,
|
|
166930
167214
|
sessionFactsVersion: state.cachedM0SessionFactsVersion,
|
|
166931
|
-
upgradeState: state.cachedM0UpgradeState
|
|
167215
|
+
upgradeState: state.cachedM0UpgradeState,
|
|
167216
|
+
systemHash: state.cachedM0SystemHash ?? "",
|
|
167217
|
+
toolSetHash: state.cachedM0ToolSetHash ?? "",
|
|
167218
|
+
modelKey: state.cachedM0ModelKey ?? ""
|
|
166932
167219
|
};
|
|
166933
167220
|
}
|
|
166934
167221
|
function mustMaterialize(args) {
|
|
@@ -166936,16 +167223,22 @@ function mustMaterialize(args) {
|
|
|
166936
167223
|
return { value: true, reason: "first_render" };
|
|
166937
167224
|
if (!args.state.cachedM1Bytes)
|
|
166938
167225
|
return { value: true, reason: "cached_m1_missing" };
|
|
167226
|
+
const hard = args.hardSignals ?? EMPTY_HARD_SIGNALS;
|
|
166939
167227
|
const current = readCurrentM0SnapshotMarkers(args);
|
|
166940
|
-
if (args.state.
|
|
166941
|
-
return { value: true, reason: "
|
|
167228
|
+
if (hard.modelKey !== "" && hard.modelKey !== (args.state.cachedM0ModelKey ?? "")) {
|
|
167229
|
+
return { value: true, reason: "model_change" };
|
|
167230
|
+
}
|
|
167231
|
+
if (hard.systemHash !== "" && hard.systemHash !== (args.state.cachedM0SystemHash ?? "")) {
|
|
167232
|
+
return { value: true, reason: "system_hash" };
|
|
166942
167233
|
}
|
|
166943
|
-
if (args.state.
|
|
166944
|
-
return { value: true, reason: "
|
|
167234
|
+
if (hard.toolSetHash !== "" && hard.toolSetHash !== (args.state.cachedM0ToolSetHash ?? "")) {
|
|
167235
|
+
return { value: true, reason: "tool_set_hash" };
|
|
166945
167236
|
}
|
|
166946
|
-
|
|
166947
|
-
|
|
166948
|
-
|
|
167237
|
+
if (hard.cacheExpired && hard.lastResponseTime > 0 && hard.lastResponseTime > (args.state.cachedM0MaterializedAt ?? 0)) {
|
|
167238
|
+
return { value: true, reason: "ttl_idle" };
|
|
167239
|
+
}
|
|
167240
|
+
if (args.state.cachedM0ProjectMemoryEpoch !== current.projectMemoryEpoch) {
|
|
167241
|
+
return { value: true, reason: "project_memory_epoch" };
|
|
166949
167242
|
}
|
|
166950
167243
|
if (args.state.cachedM0MaxMutationId !== current.maxMutationId) {
|
|
166951
167244
|
return { value: true, reason: "max_mutation_id" };
|
|
@@ -167134,6 +167427,9 @@ function applyMarkersToState(state, m0Bytes, markers, m1Bytes) {
|
|
|
167134
167427
|
state.cachedM0MaterializedAt = markers.materializedAt;
|
|
167135
167428
|
state.cachedM0SessionFactsVersion = markers.sessionFactsVersion;
|
|
167136
167429
|
state.cachedM0UpgradeState = markers.upgradeState;
|
|
167430
|
+
state.cachedM0SystemHash = markers.systemHash;
|
|
167431
|
+
state.cachedM0ToolSetHash = markers.toolSetHash;
|
|
167432
|
+
state.cachedM0ModelKey = markers.modelKey;
|
|
167137
167433
|
state.snapshotMarkers = markers;
|
|
167138
167434
|
}
|
|
167139
167435
|
function historySliceTokens(m0Text) {
|
|
@@ -167158,7 +167454,8 @@ function materializeM0(options) {
|
|
|
167158
167454
|
db: options.db,
|
|
167159
167455
|
sessionId: options.sessionId,
|
|
167160
167456
|
projectPath,
|
|
167161
|
-
projectDirectory
|
|
167457
|
+
projectDirectory,
|
|
167458
|
+
hardSignals: options.hardSignals
|
|
167162
167459
|
});
|
|
167163
167460
|
docs = projectDirectory ? readProjectDocsCanonical(projectDirectory) : { renderedBlock: "", canonicalHash: "" };
|
|
167164
167461
|
snapshotMarkers.projectDocsHash = docs.canonicalHash;
|
|
@@ -167224,7 +167521,10 @@ function materializeM0(options) {
|
|
|
167224
167521
|
projectDocsHash: phase3ProjectDocsHash,
|
|
167225
167522
|
materializedAt: Date.now(),
|
|
167226
167523
|
sessionFactsVersion: getSessionFactsVersion(options.db, options.sessionId),
|
|
167227
|
-
upgradeState: getUpgradeState(options.db, options.sessionId)
|
|
167524
|
+
upgradeState: getUpgradeState(options.db, options.sessionId),
|
|
167525
|
+
systemHash: snapshotMarkers.systemHash,
|
|
167526
|
+
toolSetHash: snapshotMarkers.toolSetHash,
|
|
167527
|
+
modelKey: snapshotMarkers.modelKey
|
|
167228
167528
|
};
|
|
167229
167529
|
const stale = current.projectMemoryEpoch !== snapshotMarkers.projectMemoryEpoch || current.projectUserProfileVersion !== snapshotMarkers.projectUserProfileVersion || current.maxCompartmentSeq !== snapshotMarkers.maxCompartmentSeq || current.maxMutationId !== snapshotMarkers.maxMutationId || current.maxMemoryMutationId !== snapshotMarkers.maxMemoryMutationId || current.projectDocsHash !== snapshotMarkers.projectDocsHash || current.sessionFactsVersion !== snapshotMarkers.sessionFactsVersion || current.upgradeState !== snapshotMarkers.upgradeState;
|
|
167230
167530
|
if (stale) {
|
|
@@ -167246,7 +167546,10 @@ function materializeM0(options) {
|
|
|
167246
167546
|
projectDocsHash: snapshotMarkers.projectDocsHash,
|
|
167247
167547
|
materializedAt: snapshotMarkers.materializedAt,
|
|
167248
167548
|
sessionFactsVersion: snapshotMarkers.sessionFactsVersion,
|
|
167249
|
-
upgradeState: snapshotMarkers.upgradeState
|
|
167549
|
+
upgradeState: snapshotMarkers.upgradeState,
|
|
167550
|
+
systemHash: snapshotMarkers.systemHash,
|
|
167551
|
+
toolSetHash: snapshotMarkers.toolSetHash,
|
|
167552
|
+
modelKey: snapshotMarkers.modelKey
|
|
167250
167553
|
});
|
|
167251
167554
|
options.db.prepare("UPDATE session_meta SET memory_block_count = ?, memory_block_ids = ? WHERE session_id = ?").run(renderedMemoryIds.length, JSON.stringify(renderedMemoryIds), options.sessionId);
|
|
167252
167555
|
options.db.exec("COMMIT");
|
|
@@ -167405,6 +167708,9 @@ function readCachedM0M1Row(db, sessionId) {
|
|
|
167405
167708
|
cached_m0_materialized_at,
|
|
167406
167709
|
cached_m0_session_facts_version,
|
|
167407
167710
|
cached_m0_upgrade_state,
|
|
167711
|
+
cached_m0_system_hash,
|
|
167712
|
+
cached_m0_tool_set_hash,
|
|
167713
|
+
cached_m0_model_key,
|
|
167408
167714
|
memory_block_ids
|
|
167409
167715
|
FROM session_meta
|
|
167410
167716
|
WHERE session_id = ?`).get(sessionId);
|
|
@@ -167436,11 +167742,14 @@ function markersFromCachedRow(row) {
|
|
|
167436
167742
|
projectDocsHash: row.cached_m0_project_docs_hash ?? "",
|
|
167437
167743
|
materializedAt: row.cached_m0_materialized_at ?? 0,
|
|
167438
167744
|
sessionFactsVersion: row.cached_m0_session_facts_version,
|
|
167439
|
-
upgradeState: row.cached_m0_upgrade_state
|
|
167745
|
+
upgradeState: row.cached_m0_upgrade_state,
|
|
167746
|
+
systemHash: row.cached_m0_system_hash ?? "",
|
|
167747
|
+
toolSetHash: row.cached_m0_tool_set_hash ?? "",
|
|
167748
|
+
modelKey: row.cached_m0_model_key ?? ""
|
|
167440
167749
|
};
|
|
167441
167750
|
}
|
|
167442
167751
|
function cachedRowMatchesState(row, state) {
|
|
167443
|
-
return bufferEqualsNullable(row.cached_m0_bytes, state.cachedM0Bytes) && row.cached_m0_project_memory_epoch === state.cachedM0ProjectMemoryEpoch && row.cached_m0_project_user_profile_version === state.cachedM0ProjectUserProfileVersion && row.cached_m0_max_compartment_seq === state.cachedM0MaxCompartmentSeq && row.cached_m0_max_memory_id === state.cachedM0MaxMemoryId && row.cached_m0_max_mutation_id === state.cachedM0MaxMutationId && row.cached_m0_max_memory_mutation_id === state.cachedM0MaxMemoryMutationId && (row.cached_m0_project_docs_hash ?? "") === (state.cachedM0ProjectDocsHash ?? "") && row.cached_m0_materialized_at === state.cachedM0MaterializedAt && row.cached_m0_session_facts_version === state.cachedM0SessionFactsVersion && (row.cached_m0_upgrade_state ?? null) === (state.cachedM0UpgradeState ?? null);
|
|
167752
|
+
return bufferEqualsNullable(row.cached_m0_bytes, state.cachedM0Bytes) && row.cached_m0_project_memory_epoch === state.cachedM0ProjectMemoryEpoch && row.cached_m0_project_user_profile_version === state.cachedM0ProjectUserProfileVersion && row.cached_m0_max_compartment_seq === state.cachedM0MaxCompartmentSeq && row.cached_m0_max_memory_id === state.cachedM0MaxMemoryId && row.cached_m0_max_mutation_id === state.cachedM0MaxMutationId && row.cached_m0_max_memory_mutation_id === state.cachedM0MaxMemoryMutationId && (row.cached_m0_project_docs_hash ?? "") === (state.cachedM0ProjectDocsHash ?? "") && row.cached_m0_materialized_at === state.cachedM0MaterializedAt && row.cached_m0_session_facts_version === state.cachedM0SessionFactsVersion && (row.cached_m0_upgrade_state ?? null) === (state.cachedM0UpgradeState ?? null) && (row.cached_m0_system_hash ?? "") === (state.cachedM0SystemHash ?? "") && (row.cached_m0_tool_set_hash ?? "") === (state.cachedM0ToolSetHash ?? "") && (row.cached_m0_model_key ?? "") === (state.cachedM0ModelKey ?? "");
|
|
167444
167753
|
}
|
|
167445
167754
|
function applyCachedRowToState(state, row) {
|
|
167446
167755
|
const markers = markersFromCachedRow(row);
|
|
@@ -167459,6 +167768,9 @@ function applyCachedRowToState(state, row) {
|
|
|
167459
167768
|
state.cachedM0MaterializedAt = markers.materializedAt;
|
|
167460
167769
|
state.cachedM0SessionFactsVersion = markers.sessionFactsVersion;
|
|
167461
167770
|
state.cachedM0UpgradeState = markers.upgradeState;
|
|
167771
|
+
state.cachedM0SystemHash = markers.systemHash;
|
|
167772
|
+
state.cachedM0ToolSetHash = markers.toolSetHash;
|
|
167773
|
+
state.cachedM0ModelKey = markers.modelKey;
|
|
167462
167774
|
state.snapshotMarkers = markers;
|
|
167463
167775
|
}
|
|
167464
167776
|
function replayCachedM1(state) {
|
|
@@ -167575,7 +167887,8 @@ function injectM0M1(options) {
|
|
|
167575
167887
|
sessionId: options.sessionId,
|
|
167576
167888
|
state: options.state,
|
|
167577
167889
|
projectPath: options.projectPath,
|
|
167578
|
-
projectDirectory: options.projectDirectory
|
|
167890
|
+
projectDirectory: options.projectDirectory,
|
|
167891
|
+
hardSignals: options.hardSignals
|
|
167579
167892
|
});
|
|
167580
167893
|
let rematerialized = false;
|
|
167581
167894
|
let contentionExhausted = false;
|
|
@@ -167633,7 +167946,10 @@ function injectM0M1(options) {
|
|
|
167633
167946
|
m1Text = replayCachedM1(options.state);
|
|
167634
167947
|
}
|
|
167635
167948
|
const M0_DRIFT_RATIO_FLOOR = 2000;
|
|
167636
|
-
|
|
167949
|
+
const M1_ABSOLUTE_CAP_RATIO = 0.2;
|
|
167950
|
+
const m1AbsoluteBudget = (options.historyBudgetTokens ?? DEFAULT_HISTORY_BUDGET_TOKENS) * M1_ABSOLUTE_CAP_RATIO;
|
|
167951
|
+
const m1OverAbsoluteCap = m1Text !== M1_EMPTY_PLACEHOLDER && estimateTokens(m1Text) > m1AbsoluteBudget;
|
|
167952
|
+
if (!rematerialized && !contentionExhausted && m1Recomputed && options.isCacheBustingPass && (memoryUpdateCount > 40 || m1OverAbsoluteCap || m1Text !== M1_EMPTY_PLACEHOLDER && m0Text.length >= M0_DRIFT_RATIO_FLOOR && m1Text.length > m0Text.length * 0.15)) {
|
|
167637
167953
|
try {
|
|
167638
167954
|
const refolded = materializeWithRetry(options);
|
|
167639
167955
|
applyMarkersToState(options.state, refolded.m0Bytes, refolded.snapshotMarkers, refolded.m1Bytes);
|
|
@@ -167657,7 +167973,7 @@ function injectM0M1(options) {
|
|
|
167657
167973
|
m1Text
|
|
167658
167974
|
};
|
|
167659
167975
|
}
|
|
167660
|
-
var INJECTION_CACHE_MAX = 100, injectionCache, CONSTRAINT_KEYWORDS, MaterializeContentionError, RenderM1InvalidMarkersError, DEFAULT_HISTORY_BUDGET_TOKENS = 60000, DEFAULT_MEMORY_BUDGET_TOKENS = 8000, MEMORY_BLOCK_WRAPPER_TOKENS = 6, DEFAULT_USER_PROFILE_BUDGET_TOKENS = 4000, M0_EMPTY_BODY = "<session-history></session-history>", M1_EMPTY_PLACEHOLDER = "<session-history-since>(no new content since last materialization)</session-history-since>", maxCompartmentSeqStatements, maxMemoryIdStatements, legacyCompartmentCountStatements, m0CompartmentStatements, newCompartmentStatements
|
|
167976
|
+
var INJECTION_CACHE_MAX = 100, injectionCache, CONSTRAINT_KEYWORDS, EMPTY_HARD_SIGNALS, MaterializeContentionError, RenderM1InvalidMarkersError, DEFAULT_HISTORY_BUDGET_TOKENS = 60000, DEFAULT_MEMORY_BUDGET_TOKENS = 8000, MEMORY_BLOCK_WRAPPER_TOKENS = 6, DEFAULT_USER_PROFILE_BUDGET_TOKENS = 4000, M0_EMPTY_BODY = "<session-history></session-history>", M1_EMPTY_PLACEHOLDER = "<session-history-since>(no new content since last materialization)</session-history-since>", maxCompartmentSeqStatements, maxMemoryIdStatements, legacyCompartmentCountStatements, m0CompartmentStatements, newCompartmentStatements;
|
|
167661
167977
|
var init_inject_compartments = __esm(async () => {
|
|
167662
167978
|
init_compartment_storage();
|
|
167663
167979
|
init_constants();
|
|
@@ -167673,6 +167989,13 @@ var init_inject_compartments = __esm(async () => {
|
|
|
167673
167989
|
]);
|
|
167674
167990
|
injectionCache = new BoundedSessionMap(INJECTION_CACHE_MAX);
|
|
167675
167991
|
CONSTRAINT_KEYWORDS = /\b(must|never|always|cannot|should not|must not)\b/i;
|
|
167992
|
+
EMPTY_HARD_SIGNALS = {
|
|
167993
|
+
systemHash: "",
|
|
167994
|
+
toolSetHash: "",
|
|
167995
|
+
modelKey: "",
|
|
167996
|
+
cacheExpired: false,
|
|
167997
|
+
lastResponseTime: 0
|
|
167998
|
+
};
|
|
167676
167999
|
MaterializeContentionError = class MaterializeContentionError extends Error {
|
|
167677
168000
|
retries;
|
|
167678
168001
|
reason;
|
|
@@ -170829,7 +171152,7 @@ function resolveHistorianContextLimit(historianModelOverride) {
|
|
|
170829
171152
|
const [providerID, ...rest] = historianModelOverride.split("/");
|
|
170830
171153
|
const modelID = rest.join("/");
|
|
170831
171154
|
if (providerID && modelID) {
|
|
170832
|
-
const limit =
|
|
171155
|
+
const limit = getSdkContextLimit(providerID, modelID);
|
|
170833
171156
|
if (typeof limit === "number" && limit > 0)
|
|
170834
171157
|
return limit;
|
|
170835
171158
|
}
|
|
@@ -170848,7 +171171,7 @@ function resolveHistorianContextLimit(historianModelOverride) {
|
|
|
170848
171171
|
const modelID = rest.join("/");
|
|
170849
171172
|
if (!providerID || !modelID)
|
|
170850
171173
|
continue;
|
|
170851
|
-
const limit =
|
|
171174
|
+
const limit = getSdkContextLimit(providerID, modelID);
|
|
170852
171175
|
if (typeof limit !== "number" || limit <= 0)
|
|
170853
171176
|
continue;
|
|
170854
171177
|
if (minLimit === undefined || limit < minLimit)
|
|
@@ -171078,6 +171401,10 @@ async function runMemoryMigration(deps) {
|
|
|
171078
171401
|
const cleanupChildSession = async (sid) => {
|
|
171079
171402
|
if (!sid)
|
|
171080
171403
|
return;
|
|
171404
|
+
if (shouldKeepSubagents()) {
|
|
171405
|
+
sessionLog(parentSessionId, `memory-migration: KEEPING child session ${sid} (keep_subagents)`);
|
|
171406
|
+
return;
|
|
171407
|
+
}
|
|
171081
171408
|
await client.session.delete({ path: { id: sid } }).catch((e) => {
|
|
171082
171409
|
sessionLog(parentSessionId, `memory-migration: child cleanup failed: ${String(e)}`);
|
|
171083
171410
|
});
|
|
@@ -171215,6 +171542,7 @@ __export(exports_recomp_orchestrator, {
|
|
|
171215
171542
|
setRecompNote: () => setRecompNote,
|
|
171216
171543
|
runManagedUpgrade: () => runManagedUpgrade,
|
|
171217
171544
|
runManagedRecomp: () => runManagedRecomp,
|
|
171545
|
+
isRecompSkip: () => isRecompSkip,
|
|
171218
171546
|
isRecompFailure: () => isRecompFailure,
|
|
171219
171547
|
isRecompComplete: () => isRecompComplete,
|
|
171220
171548
|
extractRecompReason: () => extractRecompReason,
|
|
@@ -171227,6 +171555,9 @@ function resolveLiveModelKey(liveSessionState, sessionId) {
|
|
|
171227
171555
|
function isRecompFailure(message) {
|
|
171228
171556
|
return /—\s*(Failed|Skipped)/.test(message);
|
|
171229
171557
|
}
|
|
171558
|
+
function isRecompSkip(message) {
|
|
171559
|
+
return /—\s*Skipped|already mutating compartment state|already running/i.test(message);
|
|
171560
|
+
}
|
|
171230
171561
|
function isRecompComplete(message) {
|
|
171231
171562
|
return /—\s*Complete/.test(message);
|
|
171232
171563
|
}
|
|
@@ -171242,9 +171573,10 @@ function contextualizeUpgradeReason(reason) {
|
|
|
171242
171573
|
}
|
|
171243
171574
|
return rewritten;
|
|
171244
171575
|
}
|
|
171245
|
-
function setRecompStarting(liveSessionState, sessionId, note) {
|
|
171576
|
+
function setRecompStarting(liveSessionState, sessionId, note, kind = "recomp") {
|
|
171246
171577
|
liveSessionState.recompProgressBySession.set(sessionId, {
|
|
171247
171578
|
sessionId,
|
|
171579
|
+
kind,
|
|
171248
171580
|
phase: "recomp",
|
|
171249
171581
|
processedMessages: 0,
|
|
171250
171582
|
totalMessages: 0,
|
|
@@ -171269,6 +171601,7 @@ function setRecompTerminal(liveSessionState, sessionId, phase, message) {
|
|
|
171269
171601
|
const existing = liveSessionState.recompProgressBySession.get(sessionId);
|
|
171270
171602
|
liveSessionState.recompProgressBySession.set(sessionId, {
|
|
171271
171603
|
sessionId,
|
|
171604
|
+
kind: existing?.kind ?? "recomp",
|
|
171272
171605
|
phase,
|
|
171273
171606
|
processedMessages: existing?.processedMessages ?? 0,
|
|
171274
171607
|
totalMessages: existing?.totalMessages ?? 0,
|
|
@@ -171278,10 +171611,10 @@ function setRecompTerminal(liveSessionState, sessionId, phase, message) {
|
|
|
171278
171611
|
updatedAt: Date.now(),
|
|
171279
171612
|
message
|
|
171280
171613
|
});
|
|
171281
|
-
if (phase === "done") {
|
|
171614
|
+
if (phase === "done" || phase === "skipped") {
|
|
171282
171615
|
const t = setTimeout(() => {
|
|
171283
171616
|
const cur = liveSessionState.recompProgressBySession.get(sessionId);
|
|
171284
|
-
if (cur?.phase ===
|
|
171617
|
+
if (cur?.phase === phase)
|
|
171285
171618
|
liveSessionState.recompProgressBySession.delete(sessionId);
|
|
171286
171619
|
}, RECOMP_DONE_GRACE_MS);
|
|
171287
171620
|
t.unref?.();
|
|
@@ -171310,7 +171643,11 @@ function buildRecompDeps(ctx, sessionId) {
|
|
|
171310
171643
|
ctx.liveSessionState.deferredHistoryRefreshSessions.add(sid);
|
|
171311
171644
|
},
|
|
171312
171645
|
onRecompProgress: (p) => {
|
|
171313
|
-
ctx.liveSessionState.recompProgressBySession.
|
|
171646
|
+
const prevKind = ctx.liveSessionState.recompProgressBySession.get(sessionId)?.kind ?? "recomp";
|
|
171647
|
+
ctx.liveSessionState.recompProgressBySession.set(sessionId, {
|
|
171648
|
+
...p,
|
|
171649
|
+
kind: p.kind ?? prevKind
|
|
171650
|
+
});
|
|
171314
171651
|
}
|
|
171315
171652
|
};
|
|
171316
171653
|
}
|
|
@@ -171329,10 +171666,11 @@ async function resolveSessionDirectory(ctx, sessionId) {
|
|
|
171329
171666
|
return ctx.directory;
|
|
171330
171667
|
}
|
|
171331
171668
|
async function runManagedRecomp(ctx, sessionId, options) {
|
|
171332
|
-
setRecompStarting(ctx.liveSessionState, sessionId, "Starting recomp…");
|
|
171669
|
+
setRecompStarting(ctx.liveSessionState, sessionId, "Starting recomp…", "recomp");
|
|
171333
171670
|
try {
|
|
171334
171671
|
const message = await executeContextRecomp(buildRecompDeps(ctx, sessionId), options);
|
|
171335
|
-
|
|
171672
|
+
const terminalPhase = isRecompSkip(message) ? "skipped" : isRecompFailure(message) ? "failed" : "done";
|
|
171673
|
+
setRecompTerminal(ctx.liveSessionState, sessionId, terminalPhase, extractRecompReason(message));
|
|
171336
171674
|
return message;
|
|
171337
171675
|
} catch (error51) {
|
|
171338
171676
|
setRecompTerminal(ctx.liveSessionState, sessionId, "failed", `Recomp crashed: ${String(error51)}`);
|
|
@@ -171342,7 +171680,7 @@ Recomp crashed: ${String(error51)}`;
|
|
|
171342
171680
|
}
|
|
171343
171681
|
}
|
|
171344
171682
|
async function runManagedUpgrade(ctx, sessionId) {
|
|
171345
|
-
setRecompStarting(ctx.liveSessionState, sessionId, "Starting upgrade…");
|
|
171683
|
+
setRecompStarting(ctx.liveSessionState, sessionId, "Starting upgrade…", "upgrade");
|
|
171346
171684
|
try {
|
|
171347
171685
|
const compartments = getCompartments(ctx.db, sessionId);
|
|
171348
171686
|
const legacyCount = compartments.filter((c) => c.legacy === 1 || !c.p1 || c.p1.trim() === "").length;
|
|
@@ -171400,6 +171738,7 @@ async function runUpgradeMemoryMigration(ctx, sessionId, migrationDirectory) {
|
|
|
171400
171738
|
const prev = ctx.liveSessionState.recompProgressBySession.get(sessionId);
|
|
171401
171739
|
ctx.liveSessionState.recompProgressBySession.set(sessionId, {
|
|
171402
171740
|
sessionId,
|
|
171741
|
+
kind: prev?.kind ?? "upgrade",
|
|
171403
171742
|
phase: "migration",
|
|
171404
171743
|
processedMessages: prev?.processedMessages ?? 0,
|
|
171405
171744
|
totalMessages: prev?.totalMessages ?? 0,
|
|
@@ -172546,7 +172885,7 @@ async function runSidekick(deps) {
|
|
|
172546
172885
|
}
|
|
172547
172886
|
return null;
|
|
172548
172887
|
} finally {
|
|
172549
|
-
if (agentSessionId) {
|
|
172888
|
+
if (agentSessionId && !shouldKeepSubagents()) {
|
|
172550
172889
|
await deps.client.session.delete({
|
|
172551
172890
|
path: { id: agentSessionId }
|
|
172552
172891
|
}).catch((error51) => {
|
|
@@ -172796,7 +173135,8 @@ function createLiveSessionState() {
|
|
|
172796
173135
|
pendingMaterializationSessions: new Set,
|
|
172797
173136
|
deferredMaterializationSessions: new Set,
|
|
172798
173137
|
sessionDirectoryBySession: new Map,
|
|
172799
|
-
recompProgressBySession: new Map
|
|
173138
|
+
recompProgressBySession: new Map,
|
|
173139
|
+
internalChildSessions: new Set
|
|
172800
173140
|
};
|
|
172801
173141
|
}
|
|
172802
173142
|
|
|
@@ -173009,13 +173349,14 @@ init_shared();
|
|
|
173009
173349
|
init_assistant_message_extractor();
|
|
173010
173350
|
init_logger();
|
|
173011
173351
|
import { readFileSync as readFileSync8 } from "node:fs";
|
|
173012
|
-
import { isAbsolute as
|
|
173352
|
+
import { isAbsolute as isAbsolute3, join as join11, relative as relative2 } from "node:path";
|
|
173353
|
+
init_subagent_token_capture();
|
|
173013
173354
|
init_aft_availability();
|
|
173014
173355
|
init_project_key_files();
|
|
173015
173356
|
|
|
173016
173357
|
// src/features/magic-context/key-files/read-history.ts
|
|
173017
173358
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
173018
|
-
import { relative, resolve as
|
|
173359
|
+
import { relative, resolve as resolve5 } from "node:path";
|
|
173019
173360
|
function toMs(value) {
|
|
173020
173361
|
if (typeof value === "number" && Number.isFinite(value))
|
|
173021
173362
|
return value;
|
|
@@ -173052,7 +173393,7 @@ function coalesceRanges(ranges) {
|
|
|
173052
173393
|
}
|
|
173053
173394
|
function normalizeProjectRelativePath(projectPath, filePath) {
|
|
173054
173395
|
const root = realpathSync3(projectPath);
|
|
173055
|
-
const abs = filePath.startsWith("/") ?
|
|
173396
|
+
const abs = filePath.startsWith("/") ? resolve5(filePath) : resolve5(root, filePath);
|
|
173056
173397
|
let real = abs;
|
|
173057
173398
|
try {
|
|
173058
173399
|
real = realpathSync3(abs);
|
|
@@ -173420,11 +173761,13 @@ async function runKeyFilesLlm(args) {
|
|
|
173420
173761
|
const text = extractLatestAssistantText(messages);
|
|
173421
173762
|
if (!text)
|
|
173422
173763
|
throw new Error("Dreamer returned no key-files output.");
|
|
173423
|
-
return text;
|
|
173764
|
+
return { text, messages };
|
|
173424
173765
|
} finally {
|
|
173425
|
-
|
|
173426
|
-
|
|
173427
|
-
|
|
173766
|
+
if (!shouldKeepSubagents()) {
|
|
173767
|
+
await args.client.session.delete({ path: { id: agentSessionId } }).catch(() => {
|
|
173768
|
+
return;
|
|
173769
|
+
});
|
|
173770
|
+
}
|
|
173428
173771
|
}
|
|
173429
173772
|
}
|
|
173430
173773
|
async function runKeyFilesTask(args) {
|
|
@@ -173470,9 +173813,27 @@ async function runKeyFilesTask(args) {
|
|
|
173470
173813
|
log(`[key-files] lease renewal threw: ${getErrorMessage(error51)}`);
|
|
173471
173814
|
}
|
|
173472
173815
|
}, 60000);
|
|
173816
|
+
let invocationRecorded = false;
|
|
173817
|
+
const llmStartedAt = Date.now();
|
|
173818
|
+
const recordKeyFilesInvocation = (params) => {
|
|
173819
|
+
if (!args.parentSessionId || invocationRecorded)
|
|
173820
|
+
return;
|
|
173821
|
+
invocationRecorded = true;
|
|
173822
|
+
recordChildInvocation({
|
|
173823
|
+
db: args.db,
|
|
173824
|
+
parentSessionId: args.parentSessionId,
|
|
173825
|
+
harness: getHarness(),
|
|
173826
|
+
subagent: "dreamer",
|
|
173827
|
+
task: "key files",
|
|
173828
|
+
startedAt: llmStartedAt,
|
|
173829
|
+
status: params.status,
|
|
173830
|
+
messages: params.messages,
|
|
173831
|
+
error: params.error
|
|
173832
|
+
});
|
|
173833
|
+
};
|
|
173473
173834
|
try {
|
|
173474
173835
|
try {
|
|
173475
|
-
const raw = await runKeyFilesLlm({
|
|
173836
|
+
const { text: raw, messages: llmMessages } = await runKeyFilesLlm({
|
|
173476
173837
|
client: args.client,
|
|
173477
173838
|
parentSessionId: args.parentSessionId,
|
|
173478
173839
|
projectPath,
|
|
@@ -173480,8 +173841,10 @@ async function runKeyFilesTask(args) {
|
|
|
173480
173841
|
deadline: args.deadline,
|
|
173481
173842
|
fallbackModels: args.fallbackModels
|
|
173482
173843
|
});
|
|
173844
|
+
recordKeyFilesInvocation({ status: "completed", messages: llmMessages });
|
|
173483
173845
|
validated = validateLlmOutput(raw, args.config, projectPath, new Set(candidates.map((candidate) => candidate.path)));
|
|
173484
173846
|
} catch (error51) {
|
|
173847
|
+
recordKeyFilesInvocation({ status: "failed", error: error51 });
|
|
173485
173848
|
log(`[key-files] LLM validation failed: ${getErrorMessage(error51)}`);
|
|
173486
173849
|
throw error51;
|
|
173487
173850
|
}
|
|
@@ -173580,7 +173943,8 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
173580
173943
|
db: args.db,
|
|
173581
173944
|
parentSessionId: args.parentSessionId,
|
|
173582
173945
|
harness: "opencode",
|
|
173583
|
-
subagent: "
|
|
173946
|
+
subagent: "dreamer",
|
|
173947
|
+
task: "user memories",
|
|
173584
173948
|
startedAt,
|
|
173585
173949
|
status: params.status,
|
|
173586
173950
|
messages: params.messages,
|
|
@@ -173704,7 +174068,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
173704
174068
|
return result;
|
|
173705
174069
|
} finally {
|
|
173706
174070
|
clearInterval(leaseInterval);
|
|
173707
|
-
if (agentSessionId) {
|
|
174071
|
+
if (agentSessionId && !shouldKeepSubagents()) {
|
|
173708
174072
|
await args.client.session.delete({
|
|
173709
174073
|
path: { id: agentSessionId },
|
|
173710
174074
|
query: { directory: args.sessionDirectory }
|
|
@@ -174027,14 +174391,14 @@ async function runDream(args) {
|
|
|
174027
174391
|
}
|
|
174028
174392
|
} finally {
|
|
174029
174393
|
clearInterval(leaseRenewalInterval);
|
|
174030
|
-
if (agentSessionId && !taskFailed) {
|
|
174394
|
+
if (agentSessionId && !taskFailed && !shouldKeepSubagents()) {
|
|
174031
174395
|
await args.client.session.delete({
|
|
174032
174396
|
path: { id: agentSessionId }
|
|
174033
174397
|
}).catch((error51) => {
|
|
174034
174398
|
log("[dreamer] failed to delete child session:", error51);
|
|
174035
174399
|
});
|
|
174036
|
-
} else if (agentSessionId && taskFailed) {
|
|
174037
|
-
log(`[dreamer] KEEPING
|
|
174400
|
+
} else if (agentSessionId && (taskFailed || shouldKeepSubagents())) {
|
|
174401
|
+
log(`[dreamer] KEEPING child session ${agentSessionId} for task ${taskName} (${taskFailed ? "failed" : "keep_subagents"})`);
|
|
174038
174402
|
}
|
|
174039
174403
|
}
|
|
174040
174404
|
if (lostLease) {
|
|
@@ -174319,7 +174683,7 @@ Only include notes whose conditions you could definitively evaluate against exte
|
|
|
174319
174683
|
parts: [{ type: "text", text: evaluationPrompt, synthetic: true }]
|
|
174320
174684
|
}
|
|
174321
174685
|
}, {
|
|
174322
|
-
timeoutMs: Math.min(remainingMs,
|
|
174686
|
+
timeoutMs: Math.min(remainingMs, 5 * 60 * 1000),
|
|
174323
174687
|
signal: abortController.signal,
|
|
174324
174688
|
fallbackModels: args.fallbackModels,
|
|
174325
174689
|
callContext: "dreamer:smart-notes"
|
|
@@ -174395,7 +174759,7 @@ Only include notes whose conditions you could definitively evaluate against exte
|
|
|
174395
174759
|
});
|
|
174396
174760
|
} finally {
|
|
174397
174761
|
clearInterval(leaseInterval);
|
|
174398
|
-
if (agentSessionId) {
|
|
174762
|
+
if (agentSessionId && !shouldKeepSubagents()) {
|
|
174399
174763
|
await args.client.session.delete({
|
|
174400
174764
|
path: { id: agentSessionId }
|
|
174401
174765
|
}).catch(() => {});
|
|
@@ -174406,14 +174770,14 @@ var MAX_LEASE_RETRIES = 3;
|
|
|
174406
174770
|
async function processDreamQueue(args) {
|
|
174407
174771
|
const maxRuntimeMs = args.maxRuntimeMinutes * 60 * 1000;
|
|
174408
174772
|
if (!hasActiveDreamLease(args.db)) {
|
|
174409
|
-
clearStaleEntries(args.db, maxRuntimeMs +
|
|
174773
|
+
clearStaleEntries(args.db, maxRuntimeMs + 30 * 60 * 1000, args.projectIdentity);
|
|
174410
174774
|
}
|
|
174411
174775
|
const entry = dequeueNext(args.db, args.projectIdentity);
|
|
174412
174776
|
if (!entry) {
|
|
174413
174777
|
return null;
|
|
174414
174778
|
}
|
|
174415
174779
|
const projectDirectory = args.sessionDirectoryOverride ?? resolveDreamSessionDirectory(entry.projectIdentity);
|
|
174416
|
-
log(`[dreamer] dequeued project ${entry.projectIdentity}
|
|
174780
|
+
log(`[dreamer] dequeued project ${entry.projectIdentity}, starting dream run`);
|
|
174417
174781
|
let result;
|
|
174418
174782
|
try {
|
|
174419
174783
|
result = await runDream({
|
|
@@ -174537,6 +174901,7 @@ async function readGitCommits(directory, options = {}) {
|
|
|
174537
174901
|
if (revision.startsWith("-")) {
|
|
174538
174902
|
throw new Error(`readGitCommits: refusing revision that looks like an option: "${revision}"`);
|
|
174539
174903
|
}
|
|
174904
|
+
const projectLabel = options.projectIdentity ?? "<project>";
|
|
174540
174905
|
const args = [
|
|
174541
174906
|
"log",
|
|
174542
174907
|
revision,
|
|
@@ -174559,11 +174924,11 @@ async function readGitCommits(directory, options = {}) {
|
|
|
174559
174924
|
stdout = result.stdout;
|
|
174560
174925
|
} catch (error51) {
|
|
174561
174926
|
const message = error51 instanceof Error ? error51.message : String(error51);
|
|
174562
|
-
log(`[git-commits] readGitCommits failed
|
|
174927
|
+
log(`[git-commits] readGitCommits failed for ${projectLabel}: ${message.slice(0, 500)}`);
|
|
174563
174928
|
return [];
|
|
174564
174929
|
}
|
|
174565
174930
|
if (stdout.trim().length === 0) {
|
|
174566
|
-
log(`[git-commits] readGitCommits returned empty stdout
|
|
174931
|
+
log(`[git-commits] readGitCommits returned empty stdout for ${projectLabel} (sinceMs=${options.sinceMs ?? "none"} args=${args.slice(0, 4).join(" ")})`);
|
|
174567
174932
|
}
|
|
174568
174933
|
return parseGitLogOutput(stdout);
|
|
174569
174934
|
}
|
|
@@ -174618,6 +174983,7 @@ var insertStatements = new WeakMap;
|
|
|
174618
174983
|
var existingShasStatements = new WeakMap;
|
|
174619
174984
|
var projectCountStatements = new WeakMap;
|
|
174620
174985
|
var evictStatements = new WeakMap;
|
|
174986
|
+
var evictOverflowStatements = new WeakMap;
|
|
174621
174987
|
var latestCommitTimeStatements = new WeakMap;
|
|
174622
174988
|
function getInsertStatement(db) {
|
|
174623
174989
|
let stmt = insertStatements.get(db);
|
|
@@ -174660,17 +175026,17 @@ function getLatestCommitTimeStatement(db) {
|
|
|
174660
175026
|
}
|
|
174661
175027
|
return stmt;
|
|
174662
175028
|
}
|
|
174663
|
-
function
|
|
174664
|
-
let stmt =
|
|
175029
|
+
function getEvictOverflowStatement(db) {
|
|
175030
|
+
let stmt = evictOverflowStatements.get(db);
|
|
174665
175031
|
if (!stmt) {
|
|
174666
175032
|
stmt = db.prepare(`DELETE FROM git_commits
|
|
174667
|
-
WHERE
|
|
174668
|
-
SELECT
|
|
175033
|
+
WHERE rowid IN (
|
|
175034
|
+
SELECT rowid FROM git_commits
|
|
174669
175035
|
WHERE project_path = ?
|
|
174670
|
-
ORDER BY committed_at
|
|
174671
|
-
LIMIT ?
|
|
175036
|
+
ORDER BY committed_at DESC, sha DESC
|
|
175037
|
+
LIMIT -1 OFFSET ?
|
|
174672
175038
|
)`);
|
|
174673
|
-
|
|
175039
|
+
evictOverflowStatements.set(db, stmt);
|
|
174674
175040
|
}
|
|
174675
175041
|
return stmt;
|
|
174676
175042
|
}
|
|
@@ -174708,22 +175074,15 @@ function getLatestIndexedCommitTimeMs(db, projectPath) {
|
|
|
174708
175074
|
const row = getLatestCommitTimeStatement(db).get(projectPath);
|
|
174709
175075
|
return row?.latest ?? null;
|
|
174710
175076
|
}
|
|
174711
|
-
function evictOldestCommits(db, projectPath, excess) {
|
|
174712
|
-
if (excess <= 0)
|
|
174713
|
-
return 0;
|
|
174714
|
-
const before = getCommitCount(db, projectPath);
|
|
174715
|
-
getEvictStatement(db).run(projectPath, excess);
|
|
174716
|
-
const after = getCommitCount(db, projectPath);
|
|
174717
|
-
return Math.max(0, before - after);
|
|
174718
|
-
}
|
|
174719
175077
|
function enforceProjectCap(db, projectPath, maxCommits) {
|
|
174720
175078
|
if (maxCommits <= 0)
|
|
174721
175079
|
return 0;
|
|
174722
175080
|
const count = getCommitCount(db, projectPath);
|
|
174723
175081
|
if (count <= maxCommits)
|
|
174724
175082
|
return 0;
|
|
174725
|
-
|
|
174726
|
-
const
|
|
175083
|
+
getEvictOverflowStatement(db).run(projectPath, maxCommits);
|
|
175084
|
+
const after = getCommitCount(db, projectPath);
|
|
175085
|
+
const evicted = Math.max(0, count - after);
|
|
174727
175086
|
if (evicted > 0) {
|
|
174728
175087
|
log(`[git-commits] evicted ${evicted} oldest commits for project ${projectPath} (cap=${maxCommits}, was=${count})`);
|
|
174729
175088
|
}
|
|
@@ -174755,7 +175114,8 @@ async function indexCommitsForProject(db, projectPath, directory, options) {
|
|
|
174755
175114
|
const sinceMs = latestIndexed !== null ? Math.max(latestIndexed - 60000, Date.now() - options.sinceDays * MS_PER_DAY) : Date.now() - options.sinceDays * MS_PER_DAY;
|
|
174756
175115
|
const commits = await readGitCommits(directory, {
|
|
174757
175116
|
sinceMs,
|
|
174758
|
-
maxCommits: options.maxCommits
|
|
175117
|
+
maxCommits: options.maxCommits,
|
|
175118
|
+
projectIdentity: projectPath
|
|
174759
175119
|
});
|
|
174760
175120
|
result.scanned = commits.length;
|
|
174761
175121
|
if (commits.length === 0) {
|
|
@@ -174967,6 +175327,7 @@ function searchGitCommitsSync(db, projectPath, query, options) {
|
|
|
174967
175327
|
|
|
174968
175328
|
// src/features/magic-context/git-commits/index.ts
|
|
174969
175329
|
init_storage_git_commit_embeddings();
|
|
175330
|
+
init_sweep_coordinator();
|
|
174970
175331
|
|
|
174971
175332
|
// src/plugin/dream-timer.ts
|
|
174972
175333
|
init_embedding();
|
|
@@ -174999,7 +175360,7 @@ async function startDreamScheduleTimer(args) {
|
|
|
174999
175360
|
const isNewRegistration = !registeredProjects.has(args.directory);
|
|
175000
175361
|
registeredProjects.set(args.directory, args);
|
|
175001
175362
|
if (isNewRegistration) {
|
|
175002
|
-
log(`[dreamer] registered project ${args.
|
|
175363
|
+
log(`[dreamer] registered project ${args.projectIdentity} (dreaming=${dreamingEnabled} embeddings=${embeddingSweepEnabled} commits=${commitIndexingEnabled}; total=${registeredProjects.size})`);
|
|
175003
175364
|
}
|
|
175004
175365
|
if (!activeTimer) {
|
|
175005
175366
|
log(`[dreamer] started independent schedule timer (every ${DREAM_TIMER_INTERVAL_MS / 60000}m)`);
|
|
@@ -175014,7 +175375,7 @@ async function startDreamScheduleTimer(args) {
|
|
|
175014
175375
|
}
|
|
175015
175376
|
return () => {
|
|
175016
175377
|
registeredProjects.delete(args.directory);
|
|
175017
|
-
log(`[dreamer] unregistered project ${args.
|
|
175378
|
+
log(`[dreamer] unregistered project ${args.projectIdentity} (remaining=${registeredProjects.size})`);
|
|
175018
175379
|
if (registeredProjects.size === 0 && activeTimer) {
|
|
175019
175380
|
clearInterval(activeTimer);
|
|
175020
175381
|
activeTimer = null;
|
|
@@ -175062,7 +175423,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled = getProjectEmbedd
|
|
|
175062
175423
|
return;
|
|
175063
175424
|
}
|
|
175064
175425
|
try {
|
|
175065
|
-
log(`[dreamer] timer tick (${origin}) ${reg.
|
|
175426
|
+
log(`[dreamer] timer tick (${origin}) ${reg.projectIdentity} — checking schedule window "${reg.dreamerConfig.schedule}"`);
|
|
175066
175427
|
checkScheduleAndEnqueue(db, reg.dreamerConfig.schedule, reg.projectIdentity);
|
|
175067
175428
|
await processDreamQueue({
|
|
175068
175429
|
db,
|
|
@@ -175077,13 +175438,34 @@ async function sweepProject(reg, origin, db, gitCommitEnabled = getProjectEmbedd
|
|
|
175077
175438
|
fallbackModels: resolveFallbackChain(DREAMER_AGENT, reg.dreamerConfig.fallback_models)
|
|
175078
175439
|
});
|
|
175079
175440
|
} catch (error51) {
|
|
175080
|
-
log(`[dreamer] timer-triggered queue processing failed for ${reg.
|
|
175441
|
+
log(`[dreamer] timer-triggered queue processing failed for ${reg.projectIdentity}:`, error51);
|
|
175081
175442
|
}
|
|
175082
175443
|
}
|
|
175444
|
+
function startGitSweepLeaseRenewal(db, projectIdentity, holderId) {
|
|
175445
|
+
const timer = setInterval(() => {
|
|
175446
|
+
try {
|
|
175447
|
+
if (!renewGitSweepLease(db, projectIdentity, holderId)) {
|
|
175448
|
+
log(`[git-commits] sweep lease renewal failed for ${projectIdentity}`);
|
|
175449
|
+
}
|
|
175450
|
+
} catch (error51) {
|
|
175451
|
+
log(`[git-commits] sweep lease renewal errored for ${projectIdentity}: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
175452
|
+
}
|
|
175453
|
+
}, GIT_SWEEP_LEASE_RENEWAL_MS);
|
|
175454
|
+
timer.unref?.();
|
|
175455
|
+
return () => clearInterval(timer);
|
|
175456
|
+
}
|
|
175083
175457
|
async function sweepGitCommits(args) {
|
|
175084
175458
|
const { directory, projectIdentity, db, gitCommitIndexing } = args;
|
|
175459
|
+
const holderId = crypto.randomUUID();
|
|
175460
|
+
const lease2 = acquireGitSweepLease(db, projectIdentity, holderId);
|
|
175461
|
+
if (!lease2.acquired) {
|
|
175462
|
+
const reason = lease2.reason === "cooldown_active" ? `cooldown active until ${lease2.nextAllowedAt}` : `lease held by ${lease2.leaseHolder ?? "another holder"} until ${lease2.leaseExpiresAt ?? "unknown"}`;
|
|
175463
|
+
log(`[git-commits] sweep skipped for ${projectIdentity}: ${reason}`);
|
|
175464
|
+
return;
|
|
175465
|
+
}
|
|
175085
175466
|
const startedAt = Date.now();
|
|
175086
|
-
|
|
175467
|
+
const stopRenewal = startGitSweepLeaseRenewal(db, projectIdentity, holderId);
|
|
175468
|
+
log(`[git-commits] sweep starting for ${projectIdentity} (sinceDays=${gitCommitIndexing.since_days} maxCommits=${gitCommitIndexing.max_commits})`);
|
|
175087
175469
|
try {
|
|
175088
175470
|
const result = await indexCommitsForProject(db, projectIdentity, directory, {
|
|
175089
175471
|
sinceDays: gitCommitIndexing.since_days,
|
|
@@ -175093,11 +175475,19 @@ async function sweepGitCommits(args) {
|
|
|
175093
175475
|
if (result.embedded > 0) {
|
|
175094
175476
|
drainedEmbeddings = await embedUnembeddedCommits(db, projectIdentity);
|
|
175095
175477
|
}
|
|
175478
|
+
const cooldownMarked = markGitSweepSuccessAndRelease(db, projectIdentity, holderId);
|
|
175479
|
+
if (!cooldownMarked) {
|
|
175480
|
+
releaseGitSweepLease(db, projectIdentity, holderId);
|
|
175481
|
+
log(`[git-commits] sweep finished for ${projectIdentity}, but lease was no longer active; cooldown not advanced`);
|
|
175482
|
+
}
|
|
175096
175483
|
const elapsedMs = Date.now() - startedAt;
|
|
175097
175484
|
log(`[git-commits] sweep finished for ${projectIdentity} in ${elapsedMs}ms: scanned=${result.scanned} inserted=${result.inserted} updated=${result.updated} evicted=${result.evicted} embedded=${result.embedded} drained=${drainedEmbeddings}`);
|
|
175098
175485
|
} catch (error51) {
|
|
175486
|
+
releaseGitSweepLease(db, projectIdentity, holderId);
|
|
175099
175487
|
const elapsedMs = Date.now() - startedAt;
|
|
175100
|
-
log(`[git-commits] sweep failed for ${
|
|
175488
|
+
log(`[git-commits] sweep failed for ${projectIdentity} after ${elapsedMs}ms: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
175489
|
+
} finally {
|
|
175490
|
+
stopRenewal();
|
|
175101
175491
|
}
|
|
175102
175492
|
}
|
|
175103
175493
|
|
|
@@ -175237,7 +175627,7 @@ init_models_dev_cache();
|
|
|
175237
175627
|
var DEFAULT_CONTEXT_LIMIT = 128000;
|
|
175238
175628
|
var MAX_EXECUTE_THRESHOLD = 80;
|
|
175239
175629
|
function resolveContextLimit(providerID, modelID, ctx) {
|
|
175240
|
-
const fromModelsDev = providerID && modelID ?
|
|
175630
|
+
const fromModelsDev = providerID && modelID ? getSdkContextLimit(providerID, modelID) : undefined;
|
|
175241
175631
|
const baseline = fromModelsDev ?? DEFAULT_CONTEXT_LIMIT;
|
|
175242
175632
|
if (ctx?.db && ctx.sessionID) {
|
|
175243
175633
|
try {
|
|
@@ -175250,7 +175640,7 @@ function resolveContextLimit(providerID, modelID, ctx) {
|
|
|
175250
175640
|
return baseline;
|
|
175251
175641
|
}
|
|
175252
175642
|
function resolveTrustedContextLimit(providerID, modelID, ctx) {
|
|
175253
|
-
const fromModelsDev = providerID && modelID ?
|
|
175643
|
+
const fromModelsDev = providerID && modelID ? getSdkContextLimit(providerID, modelID) : undefined;
|
|
175254
175644
|
let detected;
|
|
175255
175645
|
if (ctx?.db && ctx.sessionID) {
|
|
175256
175646
|
try {
|
|
@@ -175738,6 +176128,7 @@ function createTagger() {
|
|
|
175738
176128
|
// src/hooks/magic-context/hook.ts
|
|
175739
176129
|
init_magic_context();
|
|
175740
176130
|
init_project_identity();
|
|
176131
|
+
init_tool_definition_tokens();
|
|
175741
176132
|
await init_storage();
|
|
175742
176133
|
init_logger();
|
|
175743
176134
|
init_resolve_fallbacks();
|
|
@@ -176608,7 +176999,8 @@ function getSessionCreatedInfo(properties) {
|
|
|
176608
176999
|
id: info.id,
|
|
176609
177000
|
parentID: info.parentID,
|
|
176610
177001
|
providerID: typeof info.providerID === "string" ? info.providerID : undefined,
|
|
176611
|
-
modelID: typeof info.modelID === "string" ? info.modelID : undefined
|
|
177002
|
+
modelID: typeof info.modelID === "string" ? info.modelID : undefined,
|
|
177003
|
+
title: typeof info.title === "string" ? info.title : undefined
|
|
176612
177004
|
};
|
|
176613
177005
|
}
|
|
176614
177006
|
function getMessageUpdatedAssistantInfo(properties) {
|
|
@@ -177718,7 +178110,7 @@ async function runCompartmentPhase(args) {
|
|
|
177718
178110
|
async function awaitCompartmentRun(activeRun, reason) {
|
|
177719
178111
|
sessionLog(args.sessionId, reason);
|
|
177720
178112
|
const timeoutMs = args.historianTimeoutMs ?? 120000;
|
|
177721
|
-
const timeout = new Promise((
|
|
178113
|
+
const timeout = new Promise((resolve6) => setTimeout(() => resolve6("timeout"), timeoutMs));
|
|
177722
178114
|
const result = await Promise.race([activeRun.promise.then(() => "done"), timeout]);
|
|
177723
178115
|
if (result === "timeout") {
|
|
177724
178116
|
sessionLog(args.sessionId, `transform: compartment await timed out after ${timeoutMs}ms — proceeding without waiting`);
|
|
@@ -178675,6 +179067,64 @@ init_embedding();
|
|
|
178675
179067
|
|
|
178676
179068
|
// src/features/magic-context/search.ts
|
|
178677
179069
|
init_logger();
|
|
179070
|
+
|
|
179071
|
+
// src/features/magic-context/literal-probes.ts
|
|
179072
|
+
var MAX_PROBES = 5;
|
|
179073
|
+
var MIN_PROBE_LENGTH = 3;
|
|
179074
|
+
var SLASH_COMMAND_RE = /\/[a-z][a-z0-9]*(?:-[a-z0-9]+)+/gi;
|
|
179075
|
+
var KEBAB_SNAKE_RE = /[a-z][a-z0-9]*(?:[-_][a-z0-9]+)+/gi;
|
|
179076
|
+
var DOTTED_RE = /[a-z0-9][a-z0-9_-]*(?:\.[a-z0-9_-]+)+/gi;
|
|
179077
|
+
var CAMEL_RE = /\b[a-zA-Z][a-z0-9]*(?:[A-Z][a-z0-9]*)+\b/g;
|
|
179078
|
+
var SHA_RE = /\b[0-9a-f]{7,40}\b/gi;
|
|
179079
|
+
var ERROR_CODE_RE = /\b(?:TS\d{4,}|ERR_[A-Z][A-Z0-9_]*)\b/g;
|
|
179080
|
+
var QUOTED_RE = /["`]([^"`]{3,80})["`]/g;
|
|
179081
|
+
function looksLikeSha(token) {
|
|
179082
|
+
return /[0-9]/.test(token) && /^[0-9a-f]{7,40}$/i.test(token);
|
|
179083
|
+
}
|
|
179084
|
+
function extractLiteralProbes(query) {
|
|
179085
|
+
const trimmed = query.trim();
|
|
179086
|
+
if (trimmed.length === 0)
|
|
179087
|
+
return [];
|
|
179088
|
+
const ordered = [];
|
|
179089
|
+
const seen = new Set;
|
|
179090
|
+
const add = (raw) => {
|
|
179091
|
+
if (!raw)
|
|
179092
|
+
return;
|
|
179093
|
+
const probe = raw.trim();
|
|
179094
|
+
if (probe.length < MIN_PROBE_LENGTH)
|
|
179095
|
+
return;
|
|
179096
|
+
const key = probe.toLowerCase();
|
|
179097
|
+
if (seen.has(key))
|
|
179098
|
+
return;
|
|
179099
|
+
seen.add(key);
|
|
179100
|
+
ordered.push(probe);
|
|
179101
|
+
};
|
|
179102
|
+
for (const m of trimmed.matchAll(QUOTED_RE))
|
|
179103
|
+
add(m[1]);
|
|
179104
|
+
for (const m of trimmed.matchAll(SLASH_COMMAND_RE))
|
|
179105
|
+
add(m[0]);
|
|
179106
|
+
for (const m of trimmed.matchAll(ERROR_CODE_RE))
|
|
179107
|
+
add(m[0]);
|
|
179108
|
+
for (const m of trimmed.matchAll(DOTTED_RE))
|
|
179109
|
+
add(m[0]);
|
|
179110
|
+
for (const m of trimmed.matchAll(KEBAB_SNAKE_RE))
|
|
179111
|
+
add(m[0]);
|
|
179112
|
+
for (const m of trimmed.matchAll(CAMEL_RE))
|
|
179113
|
+
add(m[0]);
|
|
179114
|
+
for (const m of trimmed.matchAll(SHA_RE)) {
|
|
179115
|
+
if (looksLikeSha(m[0]))
|
|
179116
|
+
add(m[0]);
|
|
179117
|
+
}
|
|
179118
|
+
return ordered.slice(0, MAX_PROBES);
|
|
179119
|
+
}
|
|
179120
|
+
function containsProbeVerbatim(text, probes) {
|
|
179121
|
+
if (probes.length === 0)
|
|
179122
|
+
return false;
|
|
179123
|
+
const haystack = text.toLowerCase();
|
|
179124
|
+
return probes.some((probe) => haystack.includes(probe.toLowerCase()));
|
|
179125
|
+
}
|
|
179126
|
+
|
|
179127
|
+
// src/features/magic-context/search.ts
|
|
178678
179128
|
init_memory();
|
|
178679
179129
|
init_embedding();
|
|
178680
179130
|
init_storage_memory_fts();
|
|
@@ -178854,36 +179304,82 @@ function linearDecayScore(rank, total) {
|
|
|
178854
179304
|
return 0;
|
|
178855
179305
|
return Math.max(0, 1 - rank / total);
|
|
178856
179306
|
}
|
|
178857
|
-
function
|
|
178858
|
-
|
|
178859
|
-
if (sanitizedQuery.length === 0) {
|
|
179307
|
+
function runMessageFtsQuery(db, sessionId, ftsQuery, fetchLimit, cutoff) {
|
|
179308
|
+
if (ftsQuery.length === 0)
|
|
178860
179309
|
return [];
|
|
178861
|
-
|
|
178862
|
-
const
|
|
178863
|
-
|
|
178864
|
-
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
178865
|
-
const filtered = rows.map((row) => {
|
|
179310
|
+
const rows = getMessageSearchStatement(db).all(sessionId, ftsQuery, fetchLimit).map((row) => row);
|
|
179311
|
+
const result = [];
|
|
179312
|
+
for (const row of rows) {
|
|
178866
179313
|
const messageOrdinal = getMessageOrdinal(row.messageOrdinal);
|
|
178867
179314
|
if (messageOrdinal === null || typeof row.messageId !== "string" || typeof row.role !== "string" || typeof row.content !== "string") {
|
|
178868
|
-
|
|
179315
|
+
continue;
|
|
178869
179316
|
}
|
|
178870
179317
|
if (cutoff !== null && messageOrdinal > cutoff) {
|
|
178871
|
-
|
|
179318
|
+
continue;
|
|
178872
179319
|
}
|
|
178873
|
-
|
|
179320
|
+
result.push({
|
|
178874
179321
|
messageOrdinal,
|
|
178875
179322
|
messageId: row.messageId,
|
|
178876
179323
|
role: row.role,
|
|
178877
179324
|
content: row.content
|
|
178878
|
-
};
|
|
178879
|
-
}
|
|
178880
|
-
return
|
|
179325
|
+
});
|
|
179326
|
+
}
|
|
179327
|
+
return result;
|
|
179328
|
+
}
|
|
179329
|
+
var RRF_K = 60;
|
|
179330
|
+
var VERBATIM_PROBE_BONUS = 0.5;
|
|
179331
|
+
function searchMessages(args) {
|
|
179332
|
+
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
179333
|
+
const fetchLimit = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.limit * 3 : args.limit;
|
|
179334
|
+
const baseQuery = sanitizeFtsQuery(args.query.trim());
|
|
179335
|
+
const probes = args.probes ?? [];
|
|
179336
|
+
if (probes.length === 0) {
|
|
179337
|
+
const filtered = runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff).slice(0, args.limit);
|
|
179338
|
+
return filtered.map((row, rank) => ({
|
|
179339
|
+
source: "message",
|
|
179340
|
+
content: previewText(row.content),
|
|
179341
|
+
score: linearDecayScore(rank, filtered.length),
|
|
179342
|
+
messageOrdinal: row.messageOrdinal,
|
|
179343
|
+
messageId: row.messageId,
|
|
179344
|
+
role: row.role
|
|
179345
|
+
}));
|
|
179346
|
+
}
|
|
179347
|
+
const queryLists = [];
|
|
179348
|
+
if (baseQuery.length > 0) {
|
|
179349
|
+
queryLists.push(runMessageFtsQuery(args.db, args.sessionId, baseQuery, fetchLimit, cutoff));
|
|
179350
|
+
}
|
|
179351
|
+
for (const probe of probes) {
|
|
179352
|
+
const probeQuery = sanitizeFtsQuery(probe);
|
|
179353
|
+
if (probeQuery.length === 0)
|
|
179354
|
+
continue;
|
|
179355
|
+
queryLists.push(runMessageFtsQuery(args.db, args.sessionId, probeQuery, fetchLimit, cutoff));
|
|
179356
|
+
}
|
|
179357
|
+
const fused = new Map;
|
|
179358
|
+
for (const list of queryLists) {
|
|
179359
|
+
list.forEach((row, rank) => {
|
|
179360
|
+
const rrf = 1 / (RRF_K + rank);
|
|
179361
|
+
const existing = fused.get(row.messageId);
|
|
179362
|
+
if (existing) {
|
|
179363
|
+
existing.score += rrf;
|
|
179364
|
+
} else {
|
|
179365
|
+
fused.set(row.messageId, { row, score: rrf });
|
|
179366
|
+
}
|
|
179367
|
+
});
|
|
179368
|
+
}
|
|
179369
|
+
for (const entry of fused.values()) {
|
|
179370
|
+
if (containsProbeVerbatim(entry.row.content, probes)) {
|
|
179371
|
+
entry.score += VERBATIM_PROBE_BONUS;
|
|
179372
|
+
}
|
|
179373
|
+
}
|
|
179374
|
+
const ranked = [...fused.values()].sort((a, b) => b.score !== a.score ? b.score - a.score : a.row.messageOrdinal - b.row.messageOrdinal).slice(0, args.limit);
|
|
179375
|
+
const maxScore = ranked.length > 0 ? ranked[0].score : 1;
|
|
179376
|
+
return ranked.map((entry) => ({
|
|
178881
179377
|
source: "message",
|
|
178882
|
-
content: previewText(row.content),
|
|
178883
|
-
score:
|
|
178884
|
-
messageOrdinal: row.messageOrdinal,
|
|
178885
|
-
messageId: row.messageId,
|
|
178886
|
-
role: row.role
|
|
179378
|
+
content: previewText(entry.row.content),
|
|
179379
|
+
score: maxScore > 0 ? entry.score / maxScore : 0,
|
|
179380
|
+
messageOrdinal: entry.row.messageOrdinal,
|
|
179381
|
+
messageId: entry.row.messageId,
|
|
179382
|
+
role: entry.row.role
|
|
178887
179383
|
}));
|
|
178888
179384
|
}
|
|
178889
179385
|
function getSourceBoost(result) {
|
|
@@ -178967,12 +179463,14 @@ async function unifiedSearch(db, sessionId, projectPath, query, options = {}) {
|
|
|
178967
179463
|
return null;
|
|
178968
179464
|
}) : Promise.resolve(null);
|
|
178969
179465
|
await Promise.resolve();
|
|
179466
|
+
const messageProbes = options.explicitSearch ? extractLiteralProbes(trimmedQuery) : [];
|
|
178970
179467
|
const messageResults = runMessages ? searchMessages({
|
|
178971
179468
|
db,
|
|
178972
179469
|
sessionId,
|
|
178973
179470
|
query: trimmedQuery,
|
|
178974
179471
|
limit: tierLimit,
|
|
178975
|
-
maxOrdinal: options.maxMessageOrdinal
|
|
179472
|
+
maxOrdinal: options.maxMessageOrdinal,
|
|
179473
|
+
probes: messageProbes
|
|
178976
179474
|
}) : [];
|
|
178977
179475
|
const queryEmbedding = await queryEmbeddingPromise;
|
|
178978
179476
|
const [memoryResults, gitCommitResults] = await Promise.all([
|
|
@@ -179095,10 +179593,10 @@ var AUTO_SEARCH_TIMEOUT_MS = 3000;
|
|
|
179095
179593
|
async function unifiedSearchWithTimeout(db, sessionId, projectPath, prompt, options, timeoutMs) {
|
|
179096
179594
|
const controller = new AbortController;
|
|
179097
179595
|
let timer;
|
|
179098
|
-
const timeoutPromise = new Promise((
|
|
179596
|
+
const timeoutPromise = new Promise((resolve6) => {
|
|
179099
179597
|
timer = setTimeout(() => {
|
|
179100
179598
|
controller.abort();
|
|
179101
|
-
|
|
179599
|
+
resolve6(null);
|
|
179102
179600
|
}, timeoutMs);
|
|
179103
179601
|
});
|
|
179104
179602
|
try {
|
|
@@ -179555,7 +180053,7 @@ function isVisibleNoteReadPart(part) {
|
|
|
179555
180053
|
}
|
|
179556
180054
|
|
|
179557
180055
|
// src/hooks/magic-context/todo-view.ts
|
|
179558
|
-
import { createHash as
|
|
180056
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
179559
180057
|
var TERMINAL_STATUSES = new Set(["completed", "cancelled"]);
|
|
179560
180058
|
var TITLE_DONE_STATUSES = new Set(["completed"]);
|
|
179561
180059
|
var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
|
|
@@ -179600,7 +180098,7 @@ function buildSyntheticTodoPart(stateJson) {
|
|
|
179600
180098
|
};
|
|
179601
180099
|
}
|
|
179602
180100
|
function computeSyntheticCallId(stateJson) {
|
|
179603
|
-
const hash2 =
|
|
180101
|
+
const hash2 = createHash9("sha256").update(stateJson).digest("hex").slice(0, 16);
|
|
179604
180102
|
return `${SYNTHETIC_CALL_ID_PREFIX}${hash2}`;
|
|
179605
180103
|
}
|
|
179606
180104
|
function parseTodoState(stateJson) {
|
|
@@ -179792,7 +180290,8 @@ async function runPostTransformPhase(args) {
|
|
|
179792
180290
|
memoryInjectionBudgetTokens: args.m0M1.memoryInjectionBudgetTokens,
|
|
179793
180291
|
historyBudgetTokens: args.m0M1.historyBudgetTokens,
|
|
179794
180292
|
keyFiles: args.m0M1.keyFiles,
|
|
179795
|
-
isCacheBustingPass
|
|
180293
|
+
isCacheBustingPass,
|
|
180294
|
+
hardSignals: args.m0M1.hardSignals
|
|
179796
180295
|
});
|
|
179797
180296
|
if (result.injected) {
|
|
179798
180297
|
sessionLog(args.sessionId, `transform: injected m[0]/m[1] (rematerialized=${result.m0RematerializedThisPass}, reason=${result.decision.reason ?? "cache_hit"})`);
|
|
@@ -180166,6 +180665,10 @@ function createTransform(deps) {
|
|
|
180166
180665
|
return;
|
|
180167
180666
|
}
|
|
180168
180667
|
logTransformTiming(sessionId, "getOrCreateSessionMeta", tMeta);
|
|
180668
|
+
if (deps.internalChildSessions?.has(sessionId)) {
|
|
180669
|
+
sessionLog(sessionId, "transform skipped (internal magic-context child session)");
|
|
180670
|
+
return;
|
|
180671
|
+
}
|
|
180169
180672
|
const reducedMode = sessionMeta.isSubagent;
|
|
180170
180673
|
const fullFeatureMode = !reducedMode;
|
|
180171
180674
|
let sessionDirectory = deps.directory ?? "";
|
|
@@ -180536,6 +181039,22 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
180536
181039
|
const compartmentInProgress = compartmentPhase.compartmentInProgress;
|
|
180537
181040
|
sessionMeta = { ...sessionMeta, compartmentInProgress };
|
|
180538
181041
|
logTransformTiming(sessionId, "compartmentPhase", tCompartmentPhase);
|
|
181042
|
+
const hardModel = deps.liveModelBySession?.get(sessionId);
|
|
181043
|
+
const hardModelKey = hardModel ? `${hardModel.providerID}/${hardModel.modelID}` : "";
|
|
181044
|
+
const hardToolSetHash = deps.getToolSetHash?.(sessionId) ?? "";
|
|
181045
|
+
const hardSystemHash = typeof sessionMeta.systemPromptHash === "string" ? sessionMeta.systemPromptHash : "";
|
|
181046
|
+
let hardTtlMs = 5 * 60 * 1000;
|
|
181047
|
+
try {
|
|
181048
|
+
hardTtlMs = parseCacheTtl(sessionMeta.cacheTtl);
|
|
181049
|
+
} catch {}
|
|
181050
|
+
const hardCacheExpired = sessionMeta.lastResponseTime > 0 && Date.now() - sessionMeta.lastResponseTime >= hardTtlMs;
|
|
181051
|
+
const m0HardSignals = {
|
|
181052
|
+
systemHash: hardSystemHash,
|
|
181053
|
+
toolSetHash: hardToolSetHash,
|
|
181054
|
+
modelKey: hardModelKey,
|
|
181055
|
+
cacheExpired: hardCacheExpired,
|
|
181056
|
+
lastResponseTime: sessionMeta.lastResponseTime
|
|
181057
|
+
};
|
|
180539
181058
|
const lateActiveRunBlocksMaterialization = getActiveCompartmentRun(sessionId) !== undefined && contextUsageEarly.percentage < FORCE_MATERIALIZE_PERCENTAGE;
|
|
180540
181059
|
const canConsumeDeferredLate = canConsumeDeferredOnThisPass({
|
|
180541
181060
|
schedulerDecision: midTurnAdjustedSchedulerDecision,
|
|
@@ -180599,7 +181118,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
180599
181118
|
keyFiles: {
|
|
180600
181119
|
enabled: deps.experimentalPinKeyFiles === true,
|
|
180601
181120
|
tokenBudget: deps.experimentalPinKeyFilesTokenBudget ?? 1e4
|
|
180602
|
-
}
|
|
181121
|
+
},
|
|
181122
|
+
hardSignals: m0HardSignals
|
|
180603
181123
|
}
|
|
180604
181124
|
});
|
|
180605
181125
|
logTransformTiming(sessionId, "postTransformPhase", tPostProcess);
|
|
@@ -180761,6 +181281,7 @@ function truncateHistorianEmergencyError(error51) {
|
|
|
180761
181281
|
|
|
180762
181282
|
// src/hooks/magic-context/event-handler.ts
|
|
180763
181283
|
var CONTEXT_USAGE_TTL_MS = 60 * 60 * 1000;
|
|
181284
|
+
var INTERNAL_CHILD_TITLE_PREFIX = "magic-context-";
|
|
180764
181285
|
function formatTokens(value) {
|
|
180765
181286
|
return value.toLocaleString();
|
|
180766
181287
|
}
|
|
@@ -180825,6 +181346,10 @@ function createEventHandler2(deps) {
|
|
|
180825
181346
|
if (!info) {
|
|
180826
181347
|
return;
|
|
180827
181348
|
}
|
|
181349
|
+
if (deps.internalChildSessions && info.parentID.length > 0 && typeof info.title === "string" && info.title.startsWith(INTERNAL_CHILD_TITLE_PREFIX)) {
|
|
181350
|
+
deps.internalChildSessions.add(info.id);
|
|
181351
|
+
sessionLog(info.id, `marked internal magic-context child (title="${info.title}") — exempt from transform + injection`);
|
|
181352
|
+
}
|
|
180828
181353
|
try {
|
|
180829
181354
|
const modelKey = resolveModelKey(info.providerID, info.modelID);
|
|
180830
181355
|
updateSessionMeta(deps.db, info.id, {
|
|
@@ -181241,10 +181766,7 @@ await __promiseAll([
|
|
|
181241
181766
|
]);
|
|
181242
181767
|
|
|
181243
181768
|
// src/hooks/magic-context/text-complete.ts
|
|
181244
|
-
|
|
181245
|
-
/^(\u00a7\d+\u00a7\s*)+/,
|
|
181246
|
-
/\u00a7/g
|
|
181247
|
-
];
|
|
181769
|
+
init_tag_content_primitives();
|
|
181248
181770
|
function parseRegex(src) {
|
|
181249
181771
|
if (src.startsWith("/")) {
|
|
181250
181772
|
const lastSlash = src.lastIndexOf("/");
|
|
@@ -181258,17 +181780,19 @@ function parseRegex(src) {
|
|
|
181258
181780
|
}
|
|
181259
181781
|
function createTextCompleteHandler(stripConfig) {
|
|
181260
181782
|
const isEnabled = stripConfig?.enabled ?? true;
|
|
181261
|
-
let patterns;
|
|
181262
|
-
if (!isEnabled) {
|
|
181263
|
-
patterns = [];
|
|
181264
|
-
} else if (stripConfig?.patterns && stripConfig.patterns.length > 0) {
|
|
181783
|
+
let patterns = null;
|
|
181784
|
+
if (!isEnabled) {} else if (stripConfig?.patterns && stripConfig.patterns.length > 0) {
|
|
181265
181785
|
patterns = stripConfig.patterns.map(parseRegex);
|
|
181266
|
-
} else {
|
|
181267
|
-
patterns = DEFAULT_PATTERNS;
|
|
181268
181786
|
}
|
|
181269
181787
|
return async (_input, output) => {
|
|
181270
|
-
|
|
181271
|
-
|
|
181788
|
+
if (!isEnabled)
|
|
181789
|
+
return;
|
|
181790
|
+
if (patterns) {
|
|
181791
|
+
for (const regex of patterns) {
|
|
181792
|
+
output.text = output.text.replace(regex, "");
|
|
181793
|
+
}
|
|
181794
|
+
} else {
|
|
181795
|
+
output.text = stripPersistedAssistantText(output.text);
|
|
181272
181796
|
}
|
|
181273
181797
|
};
|
|
181274
181798
|
}
|
|
@@ -181491,7 +182015,7 @@ function createToolExecuteAfterHook(args) {
|
|
|
181491
182015
|
init_send_session_notification();
|
|
181492
182016
|
|
|
181493
182017
|
// src/hooks/magic-context/system-prompt-hash.ts
|
|
181494
|
-
import { createHash as
|
|
182018
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
181495
182019
|
|
|
181496
182020
|
// src/agents/magic-context-prompt.ts
|
|
181497
182021
|
var LONG_TERM_PARTNER_FRAME = `### You are the user's long-term partner on this project — not a one-off hire
|
|
@@ -181613,6 +182137,9 @@ function clearSystemPromptHashSession(sessionId, handleMaps) {
|
|
|
181613
182137
|
function isInternalOpenCodeAgent(systemPromptContent) {
|
|
181614
182138
|
return systemPromptContent.includes("You are a title generator. You output ONLY a thread title.") || systemPromptContent.includes("Summarize what was done in this conversation. Write like a pull request description.") || systemPromptContent.includes("You are an anchored context summarization assistant for coding sessions.");
|
|
181615
182139
|
}
|
|
182140
|
+
function isMagicContextInternalAgent(systemPromptContent) {
|
|
182141
|
+
return systemPromptContent.includes("You are Historian — the hippocampus of a long-running coding agent.") || systemPromptContent.includes("You are a memory maintenance agent for the magic-context system.") || systemPromptContent.includes("You are Sidekick, a focused memory-retrieval subagent for an AI coding assistant.") || systemPromptContent.includes("You are a file importance evaluator. Given read statistics about files");
|
|
182142
|
+
}
|
|
181616
182143
|
function createSystemPromptHashHandler(deps) {
|
|
181617
182144
|
const stickyDateBySession = new Map;
|
|
181618
182145
|
const handler = async (input, output) => {
|
|
@@ -181625,6 +182152,10 @@ function createSystemPromptHashHandler(deps) {
|
|
|
181625
182152
|
sessionLog(sessionId, "system-prompt-hash skipped (OpenCode internal agent: title/summary/compaction)");
|
|
181626
182153
|
return;
|
|
181627
182154
|
}
|
|
182155
|
+
if (deps.internalChildSessions?.has(sessionId) || isMagicContextInternalAgent(fullPromptForDetection)) {
|
|
182156
|
+
sessionLog(sessionId, "system-prompt-hash skipped (Magic Context internal child: historian/dreamer/sidekick/migration)");
|
|
182157
|
+
return;
|
|
182158
|
+
}
|
|
181628
182159
|
const injectionEnabled = deps.injectionEnabled !== false;
|
|
181629
182160
|
const skipSignatures = deps.injectionSkipSignatures ?? [];
|
|
181630
182161
|
if (!injectionEnabled) {
|
|
@@ -181675,7 +182206,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
181675
182206
|
`);
|
|
181676
182207
|
if (systemContent.length === 0)
|
|
181677
182208
|
return;
|
|
181678
|
-
const currentHash =
|
|
182209
|
+
const currentHash = createHash10("md5").update(systemContent).digest("hex");
|
|
181679
182210
|
if (!sessionMetaEarly) {
|
|
181680
182211
|
return;
|
|
181681
182212
|
}
|
|
@@ -181883,6 +182414,7 @@ function createMagicContextHook(deps) {
|
|
|
181883
182414
|
const liveModelBySession = deps.liveSessionState?.liveModelBySession ?? new Map;
|
|
181884
182415
|
const agentBySession = deps.liveSessionState?.agentBySession ?? new Map;
|
|
181885
182416
|
const sessionDirectoryBySession = deps.liveSessionState?.sessionDirectoryBySession ?? new Map;
|
|
182417
|
+
const internalChildSessions = deps.liveSessionState?.internalChildSessions ?? new Set;
|
|
181886
182418
|
const recompProgressBySession = deps.liveSessionState?.recompProgressBySession ?? new Map;
|
|
181887
182419
|
const recentReduceBySession = new Map;
|
|
181888
182420
|
const toolUsageSinceUserTurn = new Map;
|
|
@@ -181914,7 +182446,8 @@ function createMagicContextHook(deps) {
|
|
|
181914
182446
|
pendingMaterializationSessions,
|
|
181915
182447
|
deferredMaterializationSessions,
|
|
181916
182448
|
sessionDirectoryBySession,
|
|
181917
|
-
recompProgressBySession
|
|
182449
|
+
recompProgressBySession,
|
|
182450
|
+
internalChildSessions
|
|
181918
182451
|
},
|
|
181919
182452
|
directory: deps.directory,
|
|
181920
182453
|
historianChunkTokens: getHistorianChunkTokens(),
|
|
@@ -181959,6 +182492,7 @@ function createMagicContextHook(deps) {
|
|
|
181959
182492
|
deferredMaterializationSessions,
|
|
181960
182493
|
lastHeuristicsTurnId,
|
|
181961
182494
|
commitSeenLastPass,
|
|
182495
|
+
internalChildSessions,
|
|
181962
182496
|
client: deps.client,
|
|
181963
182497
|
directory: deps.directory,
|
|
181964
182498
|
memoryConfig: deps.config.memory ? {
|
|
@@ -181978,6 +182512,12 @@ function createMagicContextHook(deps) {
|
|
|
181978
182512
|
const model = liveModelBySession.get(sessionId);
|
|
181979
182513
|
return resolveModelKey(model?.providerID, model?.modelID);
|
|
181980
182514
|
},
|
|
182515
|
+
getToolSetHash: (sessionId) => {
|
|
182516
|
+
const model = liveModelBySession.get(sessionId);
|
|
182517
|
+
if (!model)
|
|
182518
|
+
return "";
|
|
182519
|
+
return getCurrentToolSetHash(model.providerID, model.modelID, agentBySession.get(sessionId));
|
|
182520
|
+
},
|
|
181981
182521
|
getFallbackModelId: (sessionId) => {
|
|
181982
182522
|
const model = liveModelBySession.get(sessionId);
|
|
181983
182523
|
return model ? `${model.providerID}/${model.modelID}` : undefined;
|
|
@@ -182010,6 +182550,7 @@ function createMagicContextHook(deps) {
|
|
|
182010
182550
|
tagger: deps.tagger,
|
|
182011
182551
|
db,
|
|
182012
182552
|
client: deps.client,
|
|
182553
|
+
internalChildSessions,
|
|
182013
182554
|
getNotificationParams: (sessionId) => getLiveNotificationParams(sessionId, liveModelBySession, variantBySession, agentBySession),
|
|
182014
182555
|
nudgePlacements,
|
|
182015
182556
|
onSessionCacheInvalidated: (sessionId) => {
|
|
@@ -182027,6 +182568,7 @@ function createMagicContextHook(deps) {
|
|
|
182027
182568
|
recompProgressBySession.delete(sessionId);
|
|
182028
182569
|
recentReduceBySession.delete(sessionId);
|
|
182029
182570
|
toolUsageSinceUserTurn.delete(sessionId);
|
|
182571
|
+
internalChildSessions.delete(sessionId);
|
|
182030
182572
|
}
|
|
182031
182573
|
});
|
|
182032
182574
|
const runDreamQueueInBackground = () => {
|
|
@@ -182137,6 +182679,7 @@ function createMagicContextHook(deps) {
|
|
|
182137
182679
|
injectionSkipSignatures: deps.config.system_prompt_injection?.skip_signatures ?? [
|
|
182138
182680
|
"<!-- magic-context: skip -->"
|
|
182139
182681
|
],
|
|
182682
|
+
internalChildSessions,
|
|
182140
182683
|
experimentalUserMemories: deps.config.dreamer?.user_memories?.enabled,
|
|
182141
182684
|
experimentalPinKeyFiles: deps.config.dreamer?.pin_key_files?.enabled ?? false,
|
|
182142
182685
|
experimentalPinKeyFilesTokenBudget: deps.config.dreamer?.pin_key_files?.token_budget,
|
|
@@ -182905,6 +183448,7 @@ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, inject
|
|
|
182905
183448
|
if (!p)
|
|
182906
183449
|
return null;
|
|
182907
183450
|
return {
|
|
183451
|
+
kind: p.kind ?? "recomp",
|
|
182908
183452
|
phase: p.phase,
|
|
182909
183453
|
processedMessages: p.processedMessages,
|
|
182910
183454
|
totalMessages: p.totalMessages,
|
|
@@ -182924,6 +183468,7 @@ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, inject
|
|
|
182924
183468
|
return {
|
|
182925
183469
|
...empty,
|
|
182926
183470
|
recompProgress: {
|
|
183471
|
+
kind: p.kind ?? "recomp",
|
|
182927
183472
|
phase: p.phase,
|
|
182928
183473
|
processedMessages: p.processedMessages,
|
|
182929
183474
|
totalMessages: p.totalMessages,
|
|
@@ -183640,16 +184185,30 @@ Example: \`ctx_note(action="write", content="Implement X because Y", surface_con
|
|
|
183640
184185
|
|
|
183641
184186
|
Historian reads these notes, deduplicates them, and rewrites the remaining useful notes over time.`;
|
|
183642
184187
|
// src/tools/ctx-note/tools.ts
|
|
183643
|
-
await
|
|
184188
|
+
await __promiseAll([
|
|
184189
|
+
init_message_index(),
|
|
184190
|
+
init_storage()
|
|
184191
|
+
]);
|
|
183644
184192
|
import { tool as tool3 } from "@opencode-ai/plugin";
|
|
184193
|
+
function captureAnchorOrdinal(db, sessionId) {
|
|
184194
|
+
try {
|
|
184195
|
+
const ordinal = getLastIndexedOrdinal(db, sessionId);
|
|
184196
|
+
return ordinal > 0 ? ordinal : null;
|
|
184197
|
+
} catch {
|
|
184198
|
+
return null;
|
|
184199
|
+
}
|
|
184200
|
+
}
|
|
184201
|
+
function anchorSuffix(note) {
|
|
184202
|
+
return note.anchorOrdinal !== null ? ` ↳ @msg ${note.anchorOrdinal}` : "";
|
|
184203
|
+
}
|
|
183645
184204
|
function formatNoteLine(note) {
|
|
183646
184205
|
const statusSuffix = note.status === "active" ? "" : ` (${note.status})`;
|
|
183647
184206
|
if (note.type === "session") {
|
|
183648
|
-
return `- **#${note.id}**${statusSuffix}: ${note.content}`;
|
|
184207
|
+
return `- **#${note.id}**${statusSuffix}: ${note.content}${anchorSuffix(note)}`;
|
|
183649
184208
|
}
|
|
183650
184209
|
const conditionText = note.status === "ready" ? note.readyReason ?? note.surfaceCondition ?? "Condition satisfied" : note.surfaceCondition ?? "No condition recorded";
|
|
183651
184210
|
const conditionLabel = note.status === "ready" ? "Condition met" : "Condition";
|
|
183652
|
-
return `- **#${note.id}**${statusSuffix}: ${note.content}
|
|
184211
|
+
return `- **#${note.id}**${statusSuffix}: ${note.content}${anchorSuffix(note)}
|
|
183653
184212
|
${conditionLabel}: ${conditionText}`;
|
|
183654
184213
|
}
|
|
183655
184214
|
var DISMISS_FOOTER = `
|
|
@@ -183727,6 +184286,7 @@ function createCtxNoteTool(deps) {
|
|
|
183727
184286
|
if (!content) {
|
|
183728
184287
|
return "Error: 'content' is required when action is 'write'.";
|
|
183729
184288
|
}
|
|
184289
|
+
const anchorOrdinal = captureAnchorOrdinal(deps.db, sessionId);
|
|
183730
184290
|
if (args.surface_condition?.trim()) {
|
|
183731
184291
|
if (!deps.dreamerEnabled) {
|
|
183732
184292
|
return "Error: Smart notes require dreamer to be enabled. Enable dreamer in magic-context.jsonc to use surface_condition.";
|
|
@@ -183738,13 +184298,14 @@ function createCtxNoteTool(deps) {
|
|
|
183738
184298
|
content,
|
|
183739
184299
|
projectPath: projectIdentity,
|
|
183740
184300
|
sessionId,
|
|
183741
|
-
surfaceCondition: args.surface_condition.trim()
|
|
184301
|
+
surfaceCondition: args.surface_condition.trim(),
|
|
184302
|
+
anchorOrdinal
|
|
183742
184303
|
});
|
|
183743
184304
|
return `Created smart note #${note2.id}. Dreamer will evaluate the condition during nightly runs:
|
|
183744
184305
|
- Content: ${content}
|
|
183745
184306
|
- Condition: ${args.surface_condition.trim()}`;
|
|
183746
184307
|
}
|
|
183747
|
-
const note = addNote(deps.db, "session", { sessionId, content });
|
|
184308
|
+
const note = addNote(deps.db, "session", { sessionId, content, anchorOrdinal });
|
|
183748
184309
|
return `Saved session note #${note.id}. Historian will rewrite or deduplicate notes as needed.`;
|
|
183749
184310
|
}
|
|
183750
184311
|
if (action === "dismiss") {
|
|
@@ -183807,9 +184368,13 @@ ${parts.join(`
|
|
|
183807
184368
|
|
|
183808
184369
|
No session notes or smart notes.`;
|
|
183809
184370
|
}
|
|
183810
|
-
|
|
184371
|
+
const body = sections.join(`
|
|
184372
|
+
|
|
184373
|
+
`);
|
|
184374
|
+
const anchorHint = body.includes("↳ @msg ") ? `
|
|
183811
184375
|
|
|
183812
|
-
|
|
184376
|
+
↳ @msg N marks the conversation tail when a note was written. To see what led to it: ctx_expand(start=N-x, end=N) (pick x for how far back to look).` : "";
|
|
184377
|
+
return body + anchorHint + DISMISS_FOOTER;
|
|
183813
184378
|
}
|
|
183814
184379
|
});
|
|
183815
184380
|
}
|
|
@@ -184100,7 +184665,8 @@ function createCtxSearchTool(deps) {
|
|
|
184100
184665
|
maxMessageOrdinal: lastCompartmentEnd >= 0 ? lastCompartmentEnd : undefined,
|
|
184101
184666
|
gitCommitsEnabled,
|
|
184102
184667
|
sources: normalizeSources(args.sources),
|
|
184103
|
-
visibleMemoryIds
|
|
184668
|
+
visibleMemoryIds,
|
|
184669
|
+
explicitSearch: true
|
|
184104
184670
|
});
|
|
184105
184671
|
return formatSearchResults(query, results);
|
|
184106
184672
|
}
|
|
@@ -184201,22 +184767,22 @@ init_models_dev_cache();
|
|
|
184201
184767
|
init_logger();
|
|
184202
184768
|
import { randomBytes } from "node:crypto";
|
|
184203
184769
|
import {
|
|
184204
|
-
mkdirSync as
|
|
184770
|
+
mkdirSync as mkdirSync8,
|
|
184205
184771
|
readdirSync,
|
|
184206
184772
|
readFileSync as readFileSync12,
|
|
184207
|
-
renameSync,
|
|
184773
|
+
renameSync as renameSync2,
|
|
184208
184774
|
unlinkSync as unlinkSync3,
|
|
184209
|
-
writeFileSync as
|
|
184775
|
+
writeFileSync as writeFileSync5
|
|
184210
184776
|
} from "node:fs";
|
|
184211
184777
|
import { createServer } from "node:http";
|
|
184212
184778
|
import { dirname as dirname5 } from "node:path";
|
|
184213
184779
|
|
|
184214
184780
|
// src/shared/rpc-utils.ts
|
|
184215
|
-
import { createHash as
|
|
184781
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
184216
184782
|
import { join as join20 } from "node:path";
|
|
184217
184783
|
function projectHash(directory) {
|
|
184218
184784
|
const normalized = directory.replace(/\/+$/, "");
|
|
184219
|
-
return
|
|
184785
|
+
return createHash11("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
184220
184786
|
}
|
|
184221
184787
|
function rpcPortDir(storageDir, directory) {
|
|
184222
184788
|
return join20(storageDir, "rpc", projectHash(directory));
|
|
@@ -184282,7 +184848,7 @@ class MagicContextRpcServer {
|
|
|
184282
184848
|
this.handlers.set(method, handler);
|
|
184283
184849
|
}
|
|
184284
184850
|
async start() {
|
|
184285
|
-
return new Promise((
|
|
184851
|
+
return new Promise((resolve6, reject) => {
|
|
184286
184852
|
const server = createServer((req, res) => this.dispatch(req, res));
|
|
184287
184853
|
server.on("error", (err) => {
|
|
184288
184854
|
log(`[rpc] server error: ${err.message}`);
|
|
@@ -184299,20 +184865,20 @@ class MagicContextRpcServer {
|
|
|
184299
184865
|
try {
|
|
184300
184866
|
this.warnIfOtherLiveInstance();
|
|
184301
184867
|
const dir = dirname5(this.portFilePath);
|
|
184302
|
-
|
|
184868
|
+
mkdirSync8(dir, { recursive: true, mode: 448 });
|
|
184303
184869
|
const tmpPath = `${this.portFilePath}.tmp`;
|
|
184304
|
-
|
|
184870
|
+
writeFileSync5(tmpPath, JSON.stringify({
|
|
184305
184871
|
port: this.port,
|
|
184306
184872
|
pid: process.pid,
|
|
184307
184873
|
started_at: this.startedAt,
|
|
184308
184874
|
token: this.token
|
|
184309
184875
|
}), { encoding: "utf-8", mode: 384 });
|
|
184310
|
-
|
|
184876
|
+
renameSync2(tmpPath, this.portFilePath);
|
|
184311
184877
|
log(`[rpc] server listening on 127.0.0.1:${this.port}`);
|
|
184312
184878
|
} catch (err) {
|
|
184313
184879
|
log(`[rpc] failed to write port file: ${err}`);
|
|
184314
184880
|
}
|
|
184315
|
-
|
|
184881
|
+
resolve6(this.port);
|
|
184316
184882
|
});
|
|
184317
184883
|
server.unref();
|
|
184318
184884
|
});
|
|
@@ -184405,6 +184971,7 @@ var plugin = async (ctx) => {
|
|
|
184405
184971
|
cacheSizeMb: pluginConfig.sqlite.cache_size_mb,
|
|
184406
184972
|
mmapSizeMb: pluginConfig.sqlite.mmap_size_mb
|
|
184407
184973
|
});
|
|
184974
|
+
setKeepSubagents(pluginConfig.keep_subagents === true);
|
|
184408
184975
|
if (pluginConfig.configWarnings?.length) {
|
|
184409
184976
|
for (const w of pluginConfig.configWarnings) {
|
|
184410
184977
|
log(`[magic-context] config warning: ${w}`);
|
|
@@ -184503,7 +185070,7 @@ var plugin = async (ctx) => {
|
|
|
184503
185070
|
rpcServer.start().catch((err) => {
|
|
184504
185071
|
log(`[magic-context] RPC server failed to start: ${err}`);
|
|
184505
185072
|
});
|
|
184506
|
-
refreshModelLimitsFromApi(ctx.client);
|
|
185073
|
+
refreshModelLimitsFromApi(ctx.client, { retries: 3, retryDelayMs: 1000 });
|
|
184507
185074
|
}
|
|
184508
185075
|
{
|
|
184509
185076
|
const fence = getSchemaFenceRejection();
|