@cortexkit/pi-magic-context 0.46.0 → 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.
@@ -138,7 +138,7 @@ class Parser {
138
138
  } else
139
139
  break;
140
140
  }
141
- const expression = { steps, cap: 300 };
141
+ const expression = { steps };
142
142
  if (this.take(".each(")) {
143
143
  if (relative)
144
144
  return this.error();
@@ -205,9 +205,23 @@ function compiled(source) {
205
205
  function oneLine(value) {
206
206
  return value.replace(/[\r\n\u2028\u2029]+/g, " ");
207
207
  }
208
- function truncate(value, cap) {
208
+ function truncate(value, cap, legacyPreview = false) {
209
209
  const chars = Array.from(oneLine(value));
210
- return chars.length > cap ? `${chars.slice(0, cap).join("")}…` : chars.join("");
210
+ if (cap === undefined || chars.length <= cap)
211
+ return chars.join("");
212
+ if (legacyPreview)
213
+ return `${chars.slice(0, cap).join("")}…`;
214
+ let end = 0;
215
+ for (let i = 0;i < Math.min(cap, chars.length); i++) {
216
+ if (!".!?。!?".includes(chars[i]))
217
+ continue;
218
+ let next = i + 1;
219
+ while (next < chars.length && `"'”’)]`.includes(chars[next]))
220
+ next++;
221
+ if (next <= cap && ("。!?".includes(chars[i]) || next === chars.length || /[ \t]/.test(chars[next])))
222
+ end = next;
223
+ }
224
+ return `${end ? `${chars.slice(0, end).join("")} ` : ""}[… ${chars.length - end} more characters]`;
211
225
  }
212
226
  function scalar(value) {
213
227
  if (value === undefined)
@@ -224,10 +238,11 @@ function compactJson(value) {
224
238
  function field(value, key) {
225
239
  return value !== null && typeof value === "object" && !Array.isArray(value) && Object.hasOwn(value, key) ? value[key] : undefined;
226
240
  }
227
- function render(nodes, root) {
241
+ function render(nodes, root, legacyPreview) {
228
242
  return nodes.map((node) => {
229
243
  if (typeof node === "string")
230
244
  return node;
245
+ const cap = node.cap ?? (legacyPreview ? 300 : undefined);
231
246
  let value = root;
232
247
  let list = false;
233
248
  for (const step of node.steps) {
@@ -241,19 +256,19 @@ function render(nodes, root) {
241
256
  }
242
257
  }
243
258
  if (node.count)
244
- return truncate(Array.isArray(value) ? String(value.length) : "", node.cap);
259
+ return truncate(Array.isArray(value) ? String(value.length) : "", cap, legacyPreview);
245
260
  if (node.each || list || node.join !== undefined) {
246
261
  if (!Array.isArray(value))
247
262
  return "";
248
- const elements = value.slice(0, 10).map((item) => truncate(node.each ? render(node.each, item) : scalar(item), 300));
249
- if (value.length > 10)
263
+ const elements = value.slice(0, legacyPreview ? 10 : undefined).map((item) => truncate(node.each ? render(node.each, item, legacyPreview) : scalar(item), legacyPreview ? 300 : undefined, legacyPreview));
264
+ if (legacyPreview && value.length > 10)
250
265
  elements.push(`… +${value.length - 10} more`);
251
- return truncate(elements.join(node.join ?? (node.each ? "; " : ", ")), node.cap);
266
+ return truncate(elements.join(node.join ?? (node.each ? "; " : ", ")), cap, legacyPreview);
252
267
  }
253
- return truncate(scalar(value), node.cap);
268
+ return truncate(scalar(value), cap, legacyPreview);
254
269
  }).join("");
255
270
  }
256
- function renderToolTemplate(source, input, output) {
271
+ function renderToolTemplate(source, input, output, legacyPreview = false) {
257
272
  const nodes = compiled(source);
258
273
  if (!nodes)
259
274
  return null;
@@ -268,8 +283,8 @@ function renderToolTemplate(source, input, output) {
268
283
  }
269
284
  }
270
285
  const root = { input, output: structured };
271
- 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);
272
- return truncate(render(bareOutputNodes, root), 1000);
286
+ 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);
287
+ return truncate(render(bareOutputNodes, root, legacyPreview), legacyPreview ? 1000 : undefined, legacyPreview);
273
288
  }
274
289
 
275
290
  // ../plugin/src/shared/protected-tools-policy.ts
@@ -3,7 +3,7 @@ import {
3
3
  toolTemplateError,
4
4
  DEFAULT_PROTECTED_TOOLS,
5
5
  mergeProtectedTools
6
- } from "./index-phh7e055.js";
6
+ } from "./index-spk5vrhy.js";
7
7
  import {
8
8
  getHarness,
9
9
  getMagicContextStorageDir,
@@ -5293,6 +5293,7 @@ var AgentMetadataSchema = AgentOverrideConfigSchema.pick({
5293
5293
  maxTokens: true
5294
5294
  });
5295
5295
  var DreamerConfigSchema = AgentMetadataSchema.extend({
5296
+ disable: boolean2().optional().describe("Disable this agent"),
5296
5297
  runner: _enum(["broca", "host"]).optional().describe(`Which side runs the dreamer completions the Rust module routes (classify-memories) in Rust transform mode: "host" runs them on this process's carrier, "broca" routes them to the Broca module. When unset, historian.runner applies, and when that is unset too the harness decides the same way it does for the historian. User-level config only.`),
5297
5298
  opencode: DreamerOpenCodeHarnessBlockSchema.optional(),
5298
5299
  pi: DreamerPiHarnessBlockSchema.optional(),
@@ -5308,7 +5309,7 @@ var HistorianConfigSchema = AgentMetadataSchema.extend({
5308
5309
  ctx.addIssue({ code: "custom", message: error });
5309
5310
  }),
5310
5311
  literal(false)
5311
- ])).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; placeholders default to 300 characters, lists to 10 elements, expansions to 1000 characters. Valid in user and project config; affects historian/recomp and verbose ctx_expand only, never the wire or default ctx_expand transcript.'),
5312
+ ])).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.'),
5312
5313
  opencode: OpenCodeHarnessBlockSchema.optional(),
5313
5314
  pi: PiHarnessBlockSchema.optional(),
5314
5315
  omp: OmpHarnessBlockSchema.optional(),
@@ -5460,7 +5461,11 @@ var MagicContextConfigSchema = object({
5460
5461
  }).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."),
5461
5462
  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)."),
5462
5463
  protected_tags: unknown().optional().describe("Deprecated: number of recent tags to protect. Ignored for behaviour; use protected_tokens instead.").meta({ deprecated: true }),
5463
- clear_reasoning_age: number2().min(10).default(50).describe("Clear reasoning/thinking blocks older than N tags (default: 50)"),
5464
+ clear_reasoning_age: unknown().optional().describe("Deprecated and ignored. Use keep_reasoning_tokens instead.").meta({ deprecated: true }),
5465
+ keep_reasoning_tokens: union([
5466
+ number2().int().min(0).max(1e6),
5467
+ object({ default: number2().int().min(0).max(1e6).optional() }).catchall(number2().int().min(0).max(1e6))
5468
+ ]).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."),
5464
5469
  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)"),
5465
5470
  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)"),
5466
5471
  commit_cluster_trigger: object({
@@ -5559,6 +5564,7 @@ var LIVE_RELOAD_CONFIG_PATHS = [
5559
5564
  "commit_cluster_trigger.enabled",
5560
5565
  "commit_cluster_trigger.min_clusters",
5561
5566
  "memory.auto_promote",
5567
+ "dreamer.disable",
5562
5568
  "dreamer.maxTokens",
5563
5569
  "dreamer.opencode.model",
5564
5570
  "dreamer.opencode.fallback_models",