@cortexkit/magic-context 0.46.1 → 0.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +202 -29
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2973,7 +2973,7 @@ function sortJson(value) {
|
|
|
2973
2973
|
if (value && typeof value === "object") {
|
|
2974
2974
|
const sorted = {};
|
|
2975
2975
|
for (const key of Object.keys(value).sort()) {
|
|
2976
|
-
if (key === "protected_tags")
|
|
2976
|
+
if (key === "protected_tags" || key === "clear_reasoning_age")
|
|
2977
2977
|
continue;
|
|
2978
2978
|
sorted[key] = sortJson(value[key]);
|
|
2979
2979
|
}
|
|
@@ -3108,7 +3108,9 @@ function migrateConfigFile(opts) {
|
|
|
3108
3108
|
let migratedContent = first.content;
|
|
3109
3109
|
let strippedProtectedTags = false;
|
|
3110
3110
|
try {
|
|
3111
|
-
const stripped = removeJsoncValue(first.content, ["protected_tags"])
|
|
3111
|
+
const stripped = removeJsoncValue(removeJsoncValue(first.content, ["protected_tags"]), [
|
|
3112
|
+
"clear_reasoning_age"
|
|
3113
|
+
]);
|
|
3112
3114
|
if (stripped !== first.content) {
|
|
3113
3115
|
migratedContent = stripped;
|
|
3114
3116
|
strippedProtectedTags = true;
|
|
@@ -3116,7 +3118,10 @@ function migrateConfigFile(opts) {
|
|
|
3116
3118
|
} catch {}
|
|
3117
3119
|
atomicWriteConfigFile(opts.targetPath, migratedContent);
|
|
3118
3120
|
if (strippedProtectedTags) {
|
|
3119
|
-
|
|
3121
|
+
if (first.content.includes('"protected_tags"'))
|
|
3122
|
+
info?.(`Stripped deprecated "protected_tags" key during config location migration`);
|
|
3123
|
+
if (first.content.includes('"clear_reasoning_age"'))
|
|
3124
|
+
info?.(`Stripped deprecated "clear_reasoning_age" key during config location migration`);
|
|
3120
3125
|
}
|
|
3121
3126
|
info?.(`Migrated Magic Context ${opts.scope} config from ${first.path} to ${opts.targetPath}`);
|
|
3122
3127
|
warnings.push(...markLegacySourcesMovedAside(sources, opts.targetPath, opts.logger));
|
|
@@ -8694,7 +8699,7 @@ class Parser {
|
|
|
8694
8699
|
} else
|
|
8695
8700
|
break;
|
|
8696
8701
|
}
|
|
8697
|
-
const expression = { steps
|
|
8702
|
+
const expression = { steps };
|
|
8698
8703
|
if (this.take(".each(")) {
|
|
8699
8704
|
if (relative)
|
|
8700
8705
|
return this.error();
|
|
@@ -8760,9 +8765,23 @@ function compiled(source) {
|
|
|
8760
8765
|
function oneLine(value) {
|
|
8761
8766
|
return value.replace(/[\r\n\u2028\u2029]+/g, " ");
|
|
8762
8767
|
}
|
|
8763
|
-
function truncate(value, cap) {
|
|
8768
|
+
function truncate(value, cap, legacyPreview = false) {
|
|
8764
8769
|
const chars = Array.from(oneLine(value));
|
|
8765
|
-
|
|
8770
|
+
if (cap === undefined || chars.length <= cap)
|
|
8771
|
+
return chars.join("");
|
|
8772
|
+
if (legacyPreview)
|
|
8773
|
+
return `${chars.slice(0, cap).join("")}…`;
|
|
8774
|
+
let end = 0;
|
|
8775
|
+
for (let i = 0;i < Math.min(cap, chars.length); i++) {
|
|
8776
|
+
if (!".!?。!?".includes(chars[i]))
|
|
8777
|
+
continue;
|
|
8778
|
+
let next = i + 1;
|
|
8779
|
+
while (next < chars.length && `"'”’)]`.includes(chars[next]))
|
|
8780
|
+
next++;
|
|
8781
|
+
if (next <= cap && ("。!?".includes(chars[i]) || next === chars.length || /[ \t]/.test(chars[next])))
|
|
8782
|
+
end = next;
|
|
8783
|
+
}
|
|
8784
|
+
return `${end ? `${chars.slice(0, end).join("")} ` : ""}[… ${chars.length - end} more characters]`;
|
|
8766
8785
|
}
|
|
8767
8786
|
function scalar(value) {
|
|
8768
8787
|
if (value === undefined)
|
|
@@ -8779,10 +8798,11 @@ function compactJson(value) {
|
|
|
8779
8798
|
function field(value, key) {
|
|
8780
8799
|
return value !== null && typeof value === "object" && !Array.isArray(value) && Object.hasOwn(value, key) ? value[key] : undefined;
|
|
8781
8800
|
}
|
|
8782
|
-
function render(nodes, root) {
|
|
8801
|
+
function render(nodes, root, legacyPreview) {
|
|
8783
8802
|
return nodes.map((node) => {
|
|
8784
8803
|
if (typeof node === "string")
|
|
8785
8804
|
return node;
|
|
8805
|
+
const cap = node.cap ?? (legacyPreview ? 300 : undefined);
|
|
8786
8806
|
let value = root;
|
|
8787
8807
|
let list = false;
|
|
8788
8808
|
for (const step of node.steps) {
|
|
@@ -8796,19 +8816,19 @@ function render(nodes, root) {
|
|
|
8796
8816
|
}
|
|
8797
8817
|
}
|
|
8798
8818
|
if (node.count)
|
|
8799
|
-
return truncate(Array.isArray(value) ? String(value.length) : "",
|
|
8819
|
+
return truncate(Array.isArray(value) ? String(value.length) : "", cap, legacyPreview);
|
|
8800
8820
|
if (node.each || list || node.join !== undefined) {
|
|
8801
8821
|
if (!Array.isArray(value))
|
|
8802
8822
|
return "";
|
|
8803
|
-
const elements = value.slice(0, 10).map((item) => truncate(node.each ? render(node.each, item) : scalar(item), 300));
|
|
8804
|
-
if (value.length > 10)
|
|
8823
|
+
const elements = value.slice(0, legacyPreview ? 10 : undefined).map((item) => truncate(node.each ? render(node.each, item, legacyPreview) : scalar(item), legacyPreview ? 300 : undefined, legacyPreview));
|
|
8824
|
+
if (legacyPreview && value.length > 10)
|
|
8805
8825
|
elements.push(`… +${value.length - 10} more`);
|
|
8806
|
-
return truncate(elements.join(node.join ?? (node.each ? "; " : ", ")),
|
|
8826
|
+
return truncate(elements.join(node.join ?? (node.each ? "; " : ", ")), cap, legacyPreview);
|
|
8807
8827
|
}
|
|
8808
|
-
return truncate(scalar(value),
|
|
8828
|
+
return truncate(scalar(value), cap, legacyPreview);
|
|
8809
8829
|
}).join("");
|
|
8810
8830
|
}
|
|
8811
|
-
function renderToolTemplate(source, input, output) {
|
|
8831
|
+
function renderToolTemplate(source, input, output, legacyPreview = false) {
|
|
8812
8832
|
const nodes = compiled(source);
|
|
8813
8833
|
if (!nodes)
|
|
8814
8834
|
return null;
|
|
@@ -8823,8 +8843,8 @@ function renderToolTemplate(source, input, output) {
|
|
|
8823
8843
|
}
|
|
8824
8844
|
}
|
|
8825
8845
|
const root = { input, output: structured };
|
|
8826
|
-
const bareOutputNodes = nodes.map((node) => typeof node !== "string" && node.steps.length === 1 && ("field" in node.steps[0]) && node.steps[0].field === "output" && !node.each && !node.count && node.join === undefined ? truncate(text ?? "", node.cap) : node);
|
|
8827
|
-
return truncate(render(bareOutputNodes, root), 1000);
|
|
8846
|
+
const bareOutputNodes = nodes.map((node) => typeof node !== "string" && node.steps.length === 1 && ("field" in node.steps[0]) && node.steps[0].field === "output" && !node.each && !node.count && node.join === undefined ? truncate(text ?? "", node.cap ?? (legacyPreview ? 300 : undefined), legacyPreview) : node);
|
|
8847
|
+
return truncate(render(bareOutputNodes, root, legacyPreview), legacyPreview ? 1000 : undefined, legacyPreview);
|
|
8828
8848
|
}
|
|
8829
8849
|
var templates;
|
|
8830
8850
|
var init_historian_tool_template = __esm(() => {
|
|
@@ -9182,7 +9202,7 @@ var init_magic_context = __esm(() => {
|
|
|
9182
9202
|
ctx.addIssue({ code: "custom", message: error });
|
|
9183
9203
|
}),
|
|
9184
9204
|
literal(false)
|
|
9185
|
-
])).optional().describe('Readable historian tool expansions, keyed by exact host tool name. Templates override built-in defaults; false disables an expansion. Supports ${input.path}, ${output.path}, bare ${output}, array [N], [*].field, .each("${field}"), .join("separator"), .count and final .truncate(N). Missing fields are empty;
|
|
9205
|
+
])).optional().describe('Readable historian tool expansions, keyed by exact host tool name. Templates override built-in defaults; false disables an expansion. Supports ${input.path}, ${output.path}, bare ${output}, array [N], [*].field, .each("${field}"), .join("separator"), .count and final .truncate(N). Missing fields are empty. Historian text and lists have no implicit caps; explicit .truncate(N) keeps complete sentences and marks omitted characters, or emits only the marker if no sentence fits. When the ctx_expand history-recovery tool is called in verbose mode, its tool-call previews retain their original built-in templates and limits (300 characters per placeholder, 10 list elements, 1000 characters per expansion). Valid in user and project config; never changes the wire or default ctx_expand transcript.'),
|
|
9186
9206
|
opencode: OpenCodeHarnessBlockSchema.optional(),
|
|
9187
9207
|
pi: PiHarnessBlockSchema.optional(),
|
|
9188
9208
|
omp: OmpHarnessBlockSchema.optional(),
|
|
@@ -9326,7 +9346,11 @@ var init_magic_context = __esm(() => {
|
|
|
9326
9346
|
}).catchall(number2().min(5000).max(2000000)).optional().describe("Absolute token thresholds per model. When matched, overrides execute_threshold_percentage for that model. Accepts `default` for all models or per-model keys. Values above 90% × context_limit are clamped with a warning log. Min 5_000, max 2_000_000."),
|
|
9327
9347
|
protected_tokens: number2().int().min(PROTECTED_TOKENS_MIN).max(1e6).optional().describe("Positive integer token floor to protect from automatic reclaim (min: 4_000, max: 1_000_000). When omitted, the derived default is clamp(round(0.05 × usableSoft), min(16_000, round(0.08 × usableSoft)), 64_000)."),
|
|
9328
9348
|
protected_tags: unknown().optional().describe("Deprecated: number of recent tags to protect. Ignored for behaviour; use protected_tokens instead.").meta({ deprecated: true }),
|
|
9329
|
-
clear_reasoning_age:
|
|
9349
|
+
clear_reasoning_age: unknown().optional().describe("Deprecated and ignored. Use keep_reasoning_tokens instead.").meta({ deprecated: true }),
|
|
9350
|
+
keep_reasoning_tokens: union([
|
|
9351
|
+
number2().int().min(0).max(1e6),
|
|
9352
|
+
object({ default: number2().int().min(0).max(1e6).optional() }).catchall(number2().int().min(0).max(1e6))
|
|
9353
|
+
]).optional().describe("Reasoning tokens to keep on rebuilding passes. Number or per-model object; exact, shorter model keys, provider/*, then default. Omitted: fixed 10,000. 0 removes all eligible historical reasoning; newest and exempt steps always stay."),
|
|
9330
9354
|
history_budget_percentage: number2().min(0.05).max(0.5).default(DEFAULT_HISTORY_BUDGET_PERCENTAGE).describe("Fraction of usable context (context_limit × execute_threshold) reserved for the session history block (default: 0.15)"),
|
|
9331
9355
|
historian_timeout_ms: number2().min(60000).default(DEFAULT_HISTORIAN_TIMEOUT_MS).describe("Timeout for each historian prompt call in both TypeScript and Rust transform modes, in milliseconds (default: 600000)"),
|
|
9332
9356
|
commit_cluster_trigger: object({
|
|
@@ -10891,6 +10915,11 @@ function warnProtectedTagsDeprecationOnce() {
|
|
|
10891
10915
|
function parsePluginConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
10892
10916
|
const preMigrationWarnings = [];
|
|
10893
10917
|
const configWithoutRemovedAgent = stripRemovedAgentConfig(rawConfig, preMigrationWarnings);
|
|
10918
|
+
if (Object.hasOwn(rawConfig, "clear_reasoning_age")) {
|
|
10919
|
+
const warning = "clear_reasoning_age is deprecated and ignored. Magic Context now keeps reasoning up to a token budget, keep_reasoning_tokens (default 10,000). Remove the key, or set keep_reasoning_tokens to a token count.";
|
|
10920
|
+
preMigrationWarnings.push(warning);
|
|
10921
|
+
log(`[magic-context] ${warning}`);
|
|
10922
|
+
}
|
|
10894
10923
|
if (Object.hasOwn(rawConfig, "protected_tags")) {
|
|
10895
10924
|
warnProtectedTagsDeprecationOnce();
|
|
10896
10925
|
preMigrationWarnings.push("protected_tags is deprecated and ignored; use protected_tokens instead.");
|
|
@@ -12822,9 +12851,12 @@ __export(exports_sqlite, {
|
|
|
12822
12851
|
Database: () => Database,
|
|
12823
12852
|
SqliteAcquisitionBusyError: () => SqliteAcquisitionBusyError,
|
|
12824
12853
|
SqliteRuntimeUnavailableError: () => SqliteRuntimeUnavailableError,
|
|
12854
|
+
assertTransformWrite: () => assertTransformWrite,
|
|
12825
12855
|
beginSqliteWriterAsync: () => beginSqliteWriterAsync,
|
|
12826
12856
|
detectSqliteRuntime: () => detectSqliteRuntime,
|
|
12857
|
+
getSqliteDatabasePath: () => getSqliteDatabasePath,
|
|
12827
12858
|
getSqliteMemoryStats: () => getSqliteMemoryStats,
|
|
12859
|
+
guardSqliteTransformPass: () => guardSqliteTransformPass,
|
|
12828
12860
|
isTransientSqliteError: () => isTransientSqliteError,
|
|
12829
12861
|
loadSqliteModule: () => loadSqliteModule,
|
|
12830
12862
|
prepareCachedStatement: () => prepareCachedStatement,
|
|
@@ -12885,6 +12917,8 @@ function installTransactionRouting(db, readonly) {
|
|
|
12885
12917
|
configurable: true,
|
|
12886
12918
|
writable: true,
|
|
12887
12919
|
value: (sql) => {
|
|
12920
|
+
if (/^\s*(?:COMMIT|END)\b/i.test(sql))
|
|
12921
|
+
assertTransformWrite();
|
|
12888
12922
|
if (/^\s*BEGIN\s+(?:IMMEDIATE|EXCLUSIVE)(?:\s+TRANSACTION)?\s*;?\s*$/i.test(sql)) {
|
|
12889
12923
|
openWriterTransactions.delete(db);
|
|
12890
12924
|
if (transformPassScope.getStore()?.active || backgroundWriterScope.getStore())
|
|
@@ -13014,6 +13048,14 @@ function buildNodeSqliteDatabaseClass(DatabaseSync) {
|
|
|
13014
13048
|
}
|
|
13015
13049
|
return NodeSqliteDatabase;
|
|
13016
13050
|
}
|
|
13051
|
+
function getSqliteDatabasePath(db) {
|
|
13052
|
+
for (const connection of trackedSqliteConnections.values()) {
|
|
13053
|
+
if (connection.reference.deref() === db) {
|
|
13054
|
+
return connection.filename === ":memory:" || connection.filename === "<buffer>" ? null : connection.filename;
|
|
13055
|
+
}
|
|
13056
|
+
}
|
|
13057
|
+
return null;
|
|
13058
|
+
}
|
|
13017
13059
|
function pragmaValue(db, name) {
|
|
13018
13060
|
const row = db.prepare(`PRAGMA ${name}`).get();
|
|
13019
13061
|
if (!row)
|
|
@@ -13166,6 +13208,15 @@ function withSqliteTransformPass(operation) {
|
|
|
13166
13208
|
function withoutSqliteTransformPass(operation) {
|
|
13167
13209
|
return transformPassScope.run(undefined, operation);
|
|
13168
13210
|
}
|
|
13211
|
+
function guardSqliteTransformPass(guard) {
|
|
13212
|
+
const lease = transformPassScope.getStore();
|
|
13213
|
+
if (lease)
|
|
13214
|
+
lease.guard = guard;
|
|
13215
|
+
}
|
|
13216
|
+
function assertTransformWrite() {
|
|
13217
|
+
if (!backgroundWriterScope.getStore())
|
|
13218
|
+
transformPassScope.getStore()?.guard?.assert();
|
|
13219
|
+
}
|
|
13169
13220
|
function isTransientSqliteError(error) {
|
|
13170
13221
|
if (!error || typeof error !== "object")
|
|
13171
13222
|
return false;
|
|
@@ -13177,6 +13228,7 @@ function foregroundWaitLease() {
|
|
|
13177
13228
|
return lease?.active && !admissionScope.getStore() && !backgroundWriterScope.getStore() ? lease : undefined;
|
|
13178
13229
|
}
|
|
13179
13230
|
function withAutocommitTimeout(db, operation) {
|
|
13231
|
+
assertTransformWrite();
|
|
13180
13232
|
const lease = foregroundWaitLease();
|
|
13181
13233
|
if (isInTransaction(db) || !lease && !backgroundWriterScope.getStore())
|
|
13182
13234
|
return operation();
|
|
@@ -13197,6 +13249,7 @@ function withAutocommitTimeout(db, operation) {
|
|
|
13197
13249
|
}
|
|
13198
13250
|
}
|
|
13199
13251
|
function acquireShort(db, acquire, site) {
|
|
13252
|
+
assertTransformWrite();
|
|
13200
13253
|
const started = performance.now();
|
|
13201
13254
|
const previous = pragmaNumber(db, "busy_timeout");
|
|
13202
13255
|
const outer = writerAcquisitionScope.getStore();
|
|
@@ -13208,7 +13261,7 @@ function acquireShort(db, acquire, site) {
|
|
|
13208
13261
|
let acquiredAt;
|
|
13209
13262
|
try {
|
|
13210
13263
|
const lease = foregroundWaitLease();
|
|
13211
|
-
const timeout =
|
|
13264
|
+
const timeout = Math.floor(Math.min(lease ? lease.remainingWaitMs : SHORT_BUSY_TIMEOUT_MS, owner?.remainingMs?.() ?? lease?.guard?.remainingMs() ?? Infinity));
|
|
13212
13265
|
db.exec(`PRAGMA busy_timeout=${timeout}`);
|
|
13213
13266
|
acquire();
|
|
13214
13267
|
acquiredAt = performance.now();
|
|
@@ -13281,29 +13334,53 @@ async function beginSqliteWriterAsync(db, site) {
|
|
|
13281
13334
|
}
|
|
13282
13335
|
}
|
|
13283
13336
|
}
|
|
13284
|
-
async function withAsyncPrivilegedWriter(db, operation) {
|
|
13337
|
+
async function withAsyncPrivilegedWriter(db, operation, options = {}) {
|
|
13285
13338
|
const started = performance.now();
|
|
13339
|
+
const budgetMs = Math.max(0, Math.min(FOREGROUND_ACQUISITION_BUDGET_MS, options.budgetMs ?? Infinity));
|
|
13286
13340
|
let attempts = 0;
|
|
13287
13341
|
for (;; ) {
|
|
13342
|
+
options.signal?.throwIfAborted();
|
|
13343
|
+
options.assertCurrentPass?.();
|
|
13288
13344
|
attempts++;
|
|
13345
|
+
let entered = false;
|
|
13289
13346
|
try {
|
|
13290
13347
|
const acquisition = {
|
|
13291
13348
|
site: "privileged_writer",
|
|
13292
13349
|
lane: "foreground",
|
|
13293
13350
|
startedAt: started,
|
|
13294
13351
|
attempts,
|
|
13295
|
-
claimed: false
|
|
13352
|
+
claimed: false,
|
|
13353
|
+
remainingMs: () => Math.max(0, budgetMs - (performance.now() - started))
|
|
13296
13354
|
};
|
|
13297
|
-
return admissionScope.run(true, () => withSqliteTransformPass(() => writerAcquisitionScope.run(acquisition, () => withPrivilegedWriter(db,
|
|
13355
|
+
return admissionScope.run(true, () => withSqliteTransformPass(() => writerAcquisitionScope.run(acquisition, () => withPrivilegedWriter(db, () => {
|
|
13356
|
+
entered = true;
|
|
13357
|
+
return operation();
|
|
13358
|
+
}))));
|
|
13298
13359
|
} catch (error) {
|
|
13299
|
-
if (!(error instanceof SqliteAcquisitionBusyError))
|
|
13360
|
+
if (entered || !(error instanceof SqliteAcquisitionBusyError))
|
|
13300
13361
|
throw error;
|
|
13362
|
+
options.beforeRetry?.(error);
|
|
13301
13363
|
const elapsed = performance.now() - started;
|
|
13302
|
-
if (elapsed >=
|
|
13364
|
+
if (elapsed >= budgetMs) {
|
|
13303
13365
|
reportSqliteDiagnostic(`sqlite writer site=privileged_writer lane=foreground acquire_ms=${Math.round(elapsed)} attempts=${attempts} outcome=busy`);
|
|
13304
13366
|
throw error;
|
|
13305
13367
|
}
|
|
13306
|
-
|
|
13368
|
+
const backoff = attempts === 1 ? 500 : 1000;
|
|
13369
|
+
const delay = Math.min(options.jitter ? backoff * (0.8 + Math.random() * 0.4) : backoff, budgetMs - elapsed);
|
|
13370
|
+
await new Promise((resolve, reject) => {
|
|
13371
|
+
const abort = () => {
|
|
13372
|
+
clearTimeout(timer);
|
|
13373
|
+
options.signal?.removeEventListener("abort", abort);
|
|
13374
|
+
reject(options.signal?.reason ?? new Error("Writer wait aborted"));
|
|
13375
|
+
};
|
|
13376
|
+
const timer = setTimeout(() => {
|
|
13377
|
+
options.signal?.removeEventListener("abort", abort);
|
|
13378
|
+
resolve();
|
|
13379
|
+
}, delay);
|
|
13380
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
13381
|
+
if (options.signal?.aborted)
|
|
13382
|
+
abort();
|
|
13383
|
+
});
|
|
13307
13384
|
}
|
|
13308
13385
|
}
|
|
13309
13386
|
}
|
|
@@ -29800,6 +29877,24 @@ var init_storage_tags = __esm(() => {
|
|
|
29800
29877
|
var historian_tool_defaults_default;
|
|
29801
29878
|
var init_historian_tool_defaults = __esm(() => {
|
|
29802
29879
|
historian_tool_defaults_default = {
|
|
29880
|
+
ctx_note: "Note ${input.action} ${input.note_ids}: ${input.content} → ${output.truncate(160)}",
|
|
29881
|
+
ctx_memory: "Memory ${input.action} ${input.category} ${input.ids}: ${input.content} → ${output.truncate(160)}",
|
|
29882
|
+
todowrite: 'Todos (${input.todos.count}): ${input.todos.each("${status}: ${content}")}',
|
|
29883
|
+
question: 'Asked user: ${input.questions[*].question.join(" / ")} → ${output}',
|
|
29884
|
+
task: "Task ${input.subagent_type}: ${input.prompt.truncate(600)} → ${output.truncate(200)}",
|
|
29885
|
+
ask: 'Asked: ${input.question} [options: ${input.options.join(" / ")}] ${input.text}${input.resolution} → ${output.truncate(300)}',
|
|
29886
|
+
peer_send: "PM ${input.recipient}: ${input.message}",
|
|
29887
|
+
board: 'Board ${input.verb}${input.board_lane}: ${input.ops.each("${op} ${lane_label} ${item}${props.text}${lane.items} ${state}${props.state}${lane.status}${id}${title}")}',
|
|
29888
|
+
room: "Room ${input.action} ${input.room_label}: ${input.room_detail}",
|
|
29889
|
+
work: "Work ${input.action} ${input.title}${input.id}: ${input.prompt.truncate(600)}${input.notes.truncate(600)} → ${output.truncate(160)}",
|
|
29890
|
+
knowhow: "Looked up how-to: ${input.query}${input.id}"
|
|
29891
|
+
};
|
|
29892
|
+
});
|
|
29893
|
+
|
|
29894
|
+
// ../plugin/src/shared/historian-tool-preview-defaults.json
|
|
29895
|
+
var historian_tool_preview_defaults_default;
|
|
29896
|
+
var init_historian_tool_preview_defaults = __esm(() => {
|
|
29897
|
+
historian_tool_preview_defaults_default = {
|
|
29803
29898
|
ctx_note: "Note ${input.action} ${input.note_ids}: ${input.content} → ${output.truncate(160)}",
|
|
29804
29899
|
ctx_memory: "Memory ${input.action} ${input.category} ${input.ids}: ${input.content} → ${output.truncate(160)}",
|
|
29805
29900
|
todowrite: 'Todos (${input.todos.count}): ${input.todos.each("${status}: ${content}")}',
|
|
@@ -29815,20 +29910,52 @@ var init_historian_tool_defaults = __esm(() => {
|
|
|
29815
29910
|
});
|
|
29816
29911
|
|
|
29817
29912
|
// ../plugin/src/shared/historian-tool-expansions.ts
|
|
29818
|
-
function
|
|
29913
|
+
function builtinInput(tool, input) {
|
|
29914
|
+
if (!input || typeof input !== "object")
|
|
29915
|
+
return input;
|
|
29916
|
+
const i = input;
|
|
29917
|
+
if (tool === "peer_send") {
|
|
29918
|
+
const external = i.external;
|
|
29919
|
+
const recipient = i.reply_to_pmid ? `reply to ${i.reply_to_pmid}` : i.agent || i.agent_id ? `to ${i.agent || i.agent_id}` : external?.session_id || i.session_id ? `to session ${external?.session_id || i.session_id}` : "to unknown recipient";
|
|
29920
|
+
return { ...i, recipient };
|
|
29921
|
+
}
|
|
29922
|
+
if (tool === "room") {
|
|
29923
|
+
return {
|
|
29924
|
+
...i,
|
|
29925
|
+
room_label: i.room_id || i.title,
|
|
29926
|
+
room_detail: i.action === "create" || i.action === "invite" ? `invitees: ${renderToolTemplate("${input.invitees}", i)}` : i.text
|
|
29927
|
+
};
|
|
29928
|
+
}
|
|
29929
|
+
if (tool === "board") {
|
|
29930
|
+
return {
|
|
29931
|
+
...i,
|
|
29932
|
+
board_lane: i.lane ? ` ${i.lane}` : "",
|
|
29933
|
+
ops: Array.isArray(i.ops) ? i.ops.map((op) => op && typeof op === "object" ? {
|
|
29934
|
+
...op,
|
|
29935
|
+
lane_label: typeof op.lane === "string" ? op.lane : op.lane?.title || op.lane?.id
|
|
29936
|
+
} : op) : i.ops
|
|
29937
|
+
};
|
|
29938
|
+
}
|
|
29939
|
+
return input;
|
|
29940
|
+
}
|
|
29941
|
+
function expandToolPart(part, overrides, legacyPreview = false) {
|
|
29819
29942
|
if (!part || typeof part !== "object")
|
|
29820
29943
|
return null;
|
|
29821
29944
|
const p = part;
|
|
29822
29945
|
if (p.type !== "tool" || typeof p.tool !== "string")
|
|
29823
29946
|
return null;
|
|
29824
|
-
const
|
|
29947
|
+
const builtinDefaults = legacyPreview ? historian_tool_preview_defaults_default : historian_tool_defaults_default;
|
|
29948
|
+
const overridden = overrides && Object.hasOwn(overrides, p.tool);
|
|
29949
|
+
const template = overridden ? overrides[p.tool] : Object.hasOwn(builtinDefaults, p.tool) ? builtinDefaults[p.tool] : undefined;
|
|
29825
29950
|
if (typeof template !== "string")
|
|
29826
29951
|
return null;
|
|
29827
29952
|
const state = p.state;
|
|
29828
|
-
|
|
29953
|
+
const input = overridden || legacyPreview ? state?.input : builtinInput(p.tool, state?.input);
|
|
29954
|
+
return renderToolTemplate(template, input, state?.output ?? state?.error, legacyPreview);
|
|
29829
29955
|
}
|
|
29830
29956
|
var init_historian_tool_expansions = __esm(() => {
|
|
29831
29957
|
init_historian_tool_defaults();
|
|
29958
|
+
init_historian_tool_preview_defaults();
|
|
29832
29959
|
init_historian_tool_template();
|
|
29833
29960
|
});
|
|
29834
29961
|
|
|
@@ -30591,7 +30718,8 @@ var init_overflow_detection = __esm(() => {
|
|
|
30591
30718
|
PREFIX_BOUND_THINKING_MODELS = [
|
|
30592
30719
|
["fable", 5, 1],
|
|
30593
30720
|
["opus", 5, 5],
|
|
30594
|
-
["sonnet", 5, 5]
|
|
30721
|
+
["sonnet", 5, 5],
|
|
30722
|
+
["haiku", 5, 5]
|
|
30595
30723
|
];
|
|
30596
30724
|
PREFIX_BOUND_THINKING_PATTERN = new RegExp(`(?:^|[-_.:/])(?:${PREFIX_BOUND_THINKING_MODELS.map(([family, major, minor]) => `${family}[-_.]?${major}[-_.]${minor}`).join("|")})(?:$|[-_.:/@])`, "i");
|
|
30597
30725
|
});
|
|
@@ -42624,6 +42752,9 @@ function mergeRawConfigs(base, override) {
|
|
|
42624
42752
|
}
|
|
42625
42753
|
function parsePiConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
42626
42754
|
const preMigrationWarnings = [];
|
|
42755
|
+
if (Object.hasOwn(rawConfig, "clear_reasoning_age")) {
|
|
42756
|
+
preMigrationWarnings.push("clear_reasoning_age is deprecated and ignored. Magic Context now keeps reasoning up to a token budget, keep_reasoning_tokens (default 10,000). Remove the key, or set keep_reasoning_tokens to a token count.");
|
|
42757
|
+
}
|
|
42627
42758
|
const configWithoutRemovedAgent = stripRemovedAgentConfig(rawConfig, preMigrationWarnings);
|
|
42628
42759
|
const hasDeprecatedProtectedTags = Object.hasOwn(rawConfig, "protected_tags");
|
|
42629
42760
|
if (hasDeprecatedProtectedTags) {
|
|
@@ -46799,6 +46930,20 @@ function formatUnresolvedCompartmentSession(session) {
|
|
|
46799
46930
|
return `session=${session.sessionId} unresolved=${session.count}`;
|
|
46800
46931
|
}
|
|
46801
46932
|
|
|
46933
|
+
// src/commands/reasoning-config-migration.ts
|
|
46934
|
+
function removeDeprecatedReasoningAge(config) {
|
|
46935
|
+
if (!Object.hasOwn(config, "clear_reasoning_age"))
|
|
46936
|
+
return [];
|
|
46937
|
+
const age = config.clear_reasoning_age;
|
|
46938
|
+
delete config.clear_reasoning_age;
|
|
46939
|
+
const messages = [
|
|
46940
|
+
"Removed deprecated clear_reasoning_age (reasoning is now kept up to a token budget, keep_reasoning_tokens, default 10,000)."
|
|
46941
|
+
];
|
|
46942
|
+
if (typeof age === "number" && age < 50)
|
|
46943
|
+
messages.push("You had set a lower age to keep less reasoning; set keep_reasoning_tokens (for example 8000) to keep less than the default.");
|
|
46944
|
+
return messages;
|
|
46945
|
+
}
|
|
46946
|
+
|
|
46802
46947
|
// src/commands/doctor-opencode.ts
|
|
46803
46948
|
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
46804
46949
|
import { existsSync as existsSync45, mkdtempSync as mkdtempSync3, readFileSync as readFileSync28, rmSync as rmSync8 } from "node:fs";
|
|
@@ -47615,6 +47760,13 @@ async function runDoctor2(options = {}) {
|
|
|
47615
47760
|
log3.success("Removed deprecated compaction_markers (always-on since v0.21.4)");
|
|
47616
47761
|
fixed++;
|
|
47617
47762
|
}
|
|
47763
|
+
const reasoningMessages = removeDeprecatedReasoningAge(mcConfig);
|
|
47764
|
+
if (reasoningMessages.length > 0) {
|
|
47765
|
+
mcChanged = true;
|
|
47766
|
+
fixed++;
|
|
47767
|
+
for (const message of reasoningMessages)
|
|
47768
|
+
log3.success(message);
|
|
47769
|
+
}
|
|
47618
47770
|
for (const deadKey of ["auto_drop_tool_age", "drop_tool_structure"]) {
|
|
47619
47771
|
if (deadKey in mcConfig) {
|
|
47620
47772
|
delete mcConfig[deadKey];
|
|
@@ -49126,7 +49278,8 @@ async function runHealthChecks2(options) {
|
|
|
49126
49278
|
const repairPlan = {
|
|
49127
49279
|
addPackageEntry: false,
|
|
49128
49280
|
writeUserConfig: false,
|
|
49129
|
-
clearCachePaths: []
|
|
49281
|
+
clearCachePaths: [],
|
|
49282
|
+
reasoningAgeConfigPaths: []
|
|
49130
49283
|
};
|
|
49131
49284
|
const self = options.deps.selfVersion();
|
|
49132
49285
|
const pi = options.deps.detectPiBinary();
|
|
@@ -49197,6 +49350,10 @@ async function runHealthChecks2(options) {
|
|
|
49197
49350
|
continue;
|
|
49198
49351
|
}
|
|
49199
49352
|
const parsed = readMagicContextJsonc(path, label);
|
|
49353
|
+
if (!parsed.error && Object.hasOwn(parsed.value, "clear_reasoning_age")) {
|
|
49354
|
+
repairPlan.reasoningAgeConfigPaths.push(path);
|
|
49355
|
+
add2(results, "warn", `${label} clear_reasoning_age is deprecated and ignored; doctor removes it`);
|
|
49356
|
+
}
|
|
49200
49357
|
if (parsed.error)
|
|
49201
49358
|
add2(results, "fail", `${label} magic-context.jsonc is invalid JSONC: ${parsed.error}`);
|
|
49202
49359
|
else
|
|
@@ -49452,6 +49609,21 @@ function writeDefaultMagicContextConfig(path) {
|
|
|
49452
49609
|
}
|
|
49453
49610
|
function repair2(plan, prompts) {
|
|
49454
49611
|
let fixed = 0;
|
|
49612
|
+
for (const path of plan.reasoningAgeConfigPaths) {
|
|
49613
|
+
const content = readFileSync30(path, "utf8");
|
|
49614
|
+
const parsed = readJsonc2(path);
|
|
49615
|
+
if (parsed.error)
|
|
49616
|
+
continue;
|
|
49617
|
+
const messages = removeDeprecatedReasoningAge(parsed.value);
|
|
49618
|
+
if (messages.length === 0)
|
|
49619
|
+
continue;
|
|
49620
|
+
writeFileAtomic(path, removeJsoncValue(content, ["clear_reasoning_age"]), {
|
|
49621
|
+
ownerOnly: true
|
|
49622
|
+
});
|
|
49623
|
+
for (const message of messages)
|
|
49624
|
+
prompts.log.success(message);
|
|
49625
|
+
fixed++;
|
|
49626
|
+
}
|
|
49455
49627
|
if (plan.addPackageEntry) {
|
|
49456
49628
|
const settingsPath = getPiUserExtensionsPath();
|
|
49457
49629
|
try {
|
|
@@ -49678,6 +49850,7 @@ var init_doctor_pi = __esm(async () => {
|
|
|
49678
49850
|
init_tick_failure();
|
|
49679
49851
|
init_embedding_synapse();
|
|
49680
49852
|
init_data_path();
|
|
49853
|
+
init_jsonc_edit();
|
|
49681
49854
|
init_jsonc_parser();
|
|
49682
49855
|
init_config2();
|
|
49683
49856
|
init_model_chain_health();
|