@cortexkit/pi-magic-context 0.22.0 → 0.22.1

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 CHANGED
@@ -146144,18 +146144,32 @@ function loadModelsDevMetadataFromFile() {
146144
146144
  return metadata;
146145
146145
  }
146146
146146
  function getModelsDevContextLimit(providerID, modelID) {
146147
- const key = `${providerID}/${modelID}`;
146148
- if (apiCache) {
146149
- const fromApi = apiCache.get(key)?.limit;
146150
- if (typeof fromApi === "number")
146151
- return fromApi;
146152
- }
146153
146147
  const now = Date.now();
146154
146148
  if (!fileCache || now - fileLastAttempt > RELOAD_INTERVAL_MS) {
146155
146149
  fileLastAttempt = now;
146156
146150
  fileCache = loadModelsDevMetadataFromFile();
146157
146151
  }
146158
- return fileCache.get(key)?.limit;
146152
+ const fromApi = lookupLimitWithTagFallback(apiCache, providerID, modelID);
146153
+ const fromFile = lookupLimitWithTagFallback(fileCache, providerID, modelID);
146154
+ if (typeof fromApi === "number" && typeof fromFile === "number") {
146155
+ return Math.max(fromApi, fromFile);
146156
+ }
146157
+ return fromApi ?? fromFile;
146158
+ }
146159
+ function lookupLimitWithTagFallback(cache, providerID, modelID) {
146160
+ if (!cache)
146161
+ return;
146162
+ const exact = cache.get(`${providerID}/${modelID}`)?.limit;
146163
+ if (typeof exact === "number")
146164
+ return exact;
146165
+ const colonIdx = modelID.lastIndexOf(":");
146166
+ if (colonIdx > 0) {
146167
+ const baseModel = modelID.slice(0, colonIdx);
146168
+ const fallback = cache.get(`${providerID}/${baseModel}`)?.limit;
146169
+ if (typeof fallback === "number")
146170
+ return fallback;
146171
+ }
146172
+ return;
146159
146173
  }
146160
146174
  function clearModelsDevCache() {
146161
146175
  apiCache = null;
@@ -146345,8 +146359,21 @@ function resolveExecuteThresholdDetail(config, modelKey, fallback, options) {
146345
146359
  if (!Number.isFinite(resolved) || resolved < 0) {
146346
146360
  resolved = fallback;
146347
146361
  }
146362
+ const cappedPercentage = Math.min(resolved, MAX_EXECUTE_THRESHOLD);
146363
+ if (cappedPercentage < resolved) {
146364
+ const dedupeKey = `pct|${options?.sessionId ?? "__global__"}|${modelKey ?? "__default__"}|${resolved}`;
146365
+ if (!clampWarnSeen.has(dedupeKey)) {
146366
+ clampWarnSeen.add(dedupeKey);
146367
+ const msg = `execute_threshold clamped ${resolved}% → ${MAX_EXECUTE_THRESHOLD}% for ${modelKey ?? "default"} (capped for cache safety; a large step can overflow before compaction, and 80% stays below the 85%/95% emergency bands)`;
146368
+ if (options?.sessionId) {
146369
+ sessionLog(options.sessionId, `WARN: ${msg}`);
146370
+ } else {
146371
+ log(`[magic-context] WARN: ${msg}`);
146372
+ }
146373
+ }
146374
+ }
146348
146375
  return {
146349
- percentage: Math.min(resolved, MAX_EXECUTE_THRESHOLD),
146376
+ percentage: cappedPercentage,
146350
146377
  mode: "percentage",
146351
146378
  matchedKey
146352
146379
  };
@@ -146680,7 +146707,12 @@ function markAnnouncementSeen(version) {
146680
146707
  function shouldShowAnnouncement() {
146681
146708
  if (!ANNOUNCEMENT_VERSION || ANNOUNCEMENT_FEATURES.length === 0)
146682
146709
  return false;
146683
- return readLastAnnouncedVersion() !== ANNOUNCEMENT_VERSION;
146710
+ const lastVersion = readLastAnnouncedVersion();
146711
+ if (!lastVersion) {
146712
+ markAnnouncementSeen(ANNOUNCEMENT_VERSION);
146713
+ return false;
146714
+ }
146715
+ return lastVersion !== ANNOUNCEMENT_VERSION;
146684
146716
  }
146685
146717
 
146686
146718
  // src/index.ts
@@ -164841,25 +164873,26 @@ var PermissionSchema = exports_external.object({
164841
164873
  external_directory: PermissionValueSchema.optional()
164842
164874
  }).optional();
164843
164875
  var AgentOverrideConfigSchema = exports_external.object({
164844
- model: exports_external.string().optional(),
164845
- temperature: exports_external.number().min(0).max(2).optional(),
164846
- top_p: exports_external.number().min(0).max(1).optional(),
164847
- prompt: exports_external.string().optional(),
164848
- tools: exports_external.record(exports_external.string(), exports_external.boolean()).optional(),
164849
- disable: exports_external.boolean().optional(),
164850
- description: exports_external.string().optional(),
164851
- mode: exports_external.enum(["subagent", "primary", "all"]).optional(),
164852
- color: exports_external.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),
164853
- maxSteps: exports_external.number().optional(),
164854
- permission: PermissionSchema,
164855
- maxTokens: exports_external.number().optional(),
164856
- variant: exports_external.string().optional(),
164857
- fallback_models: exports_external.union([exports_external.string(), exports_external.array(exports_external.string())]).optional()
164876
+ model: exports_external.string().optional().describe("Primary model ID (e.g. 'claude-sonnet-4-6')"),
164877
+ temperature: exports_external.number().min(0).max(2).optional().describe("Sampling temperature (0-2)"),
164878
+ top_p: exports_external.number().min(0).max(1).optional().describe("Nucleus sampling top_p (0-1)"),
164879
+ prompt: exports_external.string().optional().describe("Additional system prompt text"),
164880
+ tools: exports_external.record(exports_external.string(), exports_external.boolean()).optional().describe("Tool enable/disable overrides"),
164881
+ disable: exports_external.boolean().optional().describe("Disable this agent"),
164882
+ description: exports_external.string().optional().describe("Agent description"),
164883
+ mode: exports_external.enum(["subagent", "primary", "all"]).optional().describe("Agent mode (subagent, primary, or all)"),
164884
+ color: exports_external.string().regex(/^#[0-9A-Fa-f]{6}$/).optional().describe("Hex color for the agent (e.g. '#a1b2c3')"),
164885
+ maxSteps: exports_external.number().optional().describe("Maximum tool-call steps per invocation"),
164886
+ permission: PermissionSchema.describe("Per-tool permission overrides"),
164887
+ maxTokens: exports_external.number().optional().describe("Maximum output tokens"),
164888
+ variant: exports_external.string().optional().describe("OpenCode reasoning variant (e.g. for extended thinking)"),
164889
+ fallback_models: exports_external.union([exports_external.string(), exports_external.array(exports_external.string())]).optional().describe("Fallback model IDs if primary is unavailable")
164858
164890
  });
164859
164891
 
164860
164892
  // ../plugin/src/config/schema/magic-context.ts
164861
164893
  var DEFAULT_NUDGE_INTERVAL_TOKENS = 1e4;
164862
164894
  var DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65;
164895
+ var EXECUTE_THRESHOLD_CAP_MESSAGE = "execute_threshold is capped at 80% for cache safety: a single large agent step can overflow the context window before Magic Context can compact between turns, forcing OpenCode's native compaction (hard to recover from). 80% also leaves headroom below the 85%/95% emergency bands. Use a value between 20 and 80.";
164863
164896
  var DEFAULT_HISTORIAN_TIMEOUT_MS = 300000;
164864
164897
  var DEFAULT_HISTORY_BUDGET_PERCENTAGE = 0.15;
164865
164898
  var DEFAULT_LOCAL_EMBEDDING_MODEL = "Xenova/all-MiniLM-L6-v2";
@@ -164879,36 +164912,38 @@ var DEFAULT_DREAMER_TASKS = [
164879
164912
  ];
164880
164913
  var PiThinkingLevelSchema = exports_external.enum(["off", "minimal", "low", "medium", "high", "xhigh"]).optional();
164881
164914
  var DreamerConfigSchema = AgentOverrideConfigSchema.merge(exports_external.object({
164882
- schedule: exports_external.string().default("02:00-06:00"),
164883
- max_runtime_minutes: exports_external.number().min(10).default(120),
164884
- tasks: exports_external.array(DreamingTaskSchema).default(DEFAULT_DREAMER_TASKS),
164885
- task_timeout_minutes: exports_external.number().min(5).default(20),
164886
- inject_docs: exports_external.boolean().default(true),
164915
+ schedule: exports_external.string().default("02:00-06:00").describe("Scheduled window for overnight dreaming (e.g. '02:00-06:00')"),
164916
+ max_runtime_minutes: exports_external.number().min(10).default(120).describe("Maximum runtime per dream session in minutes"),
164917
+ tasks: exports_external.array(DreamingTaskSchema).default(DEFAULT_DREAMER_TASKS).describe("Tasks to run during dreaming, in order"),
164918
+ task_timeout_minutes: exports_external.number().min(5).default(20).describe("Minutes allocated per task before moving to next"),
164919
+ inject_docs: exports_external.boolean().default(true).describe("Inject ARCHITECTURE.md and STRUCTURE.md into system prompt"),
164887
164920
  user_memories: exports_external.object({
164888
- enabled: exports_external.boolean().default(true),
164889
- promotion_threshold: exports_external.number().min(2).max(20).default(3)
164890
- }).default({ enabled: true, promotion_threshold: 3 }),
164921
+ enabled: exports_external.boolean().default(true).describe("Enable user memory extraction and promotion (default: true)"),
164922
+ promotion_threshold: exports_external.number().min(2).max(20).default(3).describe("Minimum candidate observations before dreamer considers promotion (default: 3)")
164923
+ }).default({ enabled: true, promotion_threshold: 3 }).describe("User memory pipeline: historian extracts behavior observations from each compartment run; dreamer reviews recurring patterns and promotes them to stable user memories injected into all sessions as <user-profile>. Requires dreamer to not be disabled for promotion to actually happen. Graduated from experimental in v0.14. Default: enabled."),
164891
164924
  pin_key_files: exports_external.object({
164892
- enabled: exports_external.boolean().default(false),
164893
- token_budget: exports_external.number().min(2000).max(30000).default(1e4),
164894
- min_reads: exports_external.number().min(2).max(20).default(4)
164895
- }).default({ enabled: false, token_budget: 1e4, min_reads: 4 }),
164896
- thinking_level: PiThinkingLevelSchema
164925
+ enabled: exports_external.boolean().default(false).describe("Enable key file pinning (default: false)"),
164926
+ token_budget: exports_external.number().min(2000).max(30000).default(1e4).describe("Total token budget for all pinned key files (min: 2000, max: 30000, default: 10000)"),
164927
+ min_reads: exports_external.number().min(2).max(20).default(4).describe("Minimum full-read count before a file is considered for pinning (min: 2, default: 4)")
164928
+ }).default({ enabled: false, token_budget: 1e4, min_reads: 4 }).describe("Pin frequently-read key files into the system prompt so the agent doesn't need to re-read them after context drops. Dreamer identifies key files per session based on read patterns. Requires dreamer to not be disabled for selection to happen. Graduated from experimental in v0.14. Default: disabled."),
164929
+ thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level for dreamer subagent invocations. See historian.thinking_level.")
164897
164930
  }));
164898
164931
  var SidekickConfigSchema = AgentOverrideConfigSchema.extend({
164899
- timeout_ms: exports_external.number().default(30000),
164900
- system_prompt: exports_external.string().optional(),
164901
- thinking_level: PiThinkingLevelSchema
164932
+ timeout_ms: exports_external.number().default(30000).describe("Timeout for sidekick calls in milliseconds"),
164933
+ system_prompt: exports_external.string().optional().describe("Custom system prompt for sidekick"),
164934
+ thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level for sidekick subagent invocations. See historian.thinking_level.")
164902
164935
  }).optional();
164903
164936
  var HistorianConfigSchema = AgentOverrideConfigSchema.extend({
164904
- two_pass: exports_external.boolean().default(false),
164905
- thinking_level: PiThinkingLevelSchema
164937
+ two_pass: exports_external.boolean().default(false).describe("Run a second editor pass over historian output to clean low-signal U: lines and cross-compartment duplicates. Adds ~1 extra API call and ~1.3x cost per historian run. Useful for models without extended thinking support. (default: false)"),
164938
+ thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level passed as --thinking <level> to Pi historian subagent invocations. Required when using reasoning models (e.g. github-copilot/gpt-5.4) because Pi's default thinking-level resolution can pick a value the provider rejects. OpenCode users set variant instead. Valid: off | minimal | low | medium | high | xhigh")
164906
164939
  }).optional();
164907
164940
  var BaseEmbeddingConfigSchema = exports_external.object({
164908
- provider: exports_external.enum(["local", "openai-compatible", "off"]).default("local"),
164909
- model: exports_external.string().optional(),
164910
- endpoint: exports_external.string().optional(),
164911
- api_key: exports_external.string().optional()
164941
+ provider: exports_external.enum(["local", "openai-compatible", "off"]).default("local").describe("Embedding provider. 'local' uses Xenova/all-MiniLM-L6-v2, 'openai-compatible' requires endpoint and model, 'off' disables embeddings."),
164942
+ model: exports_external.string().optional().describe("Embedding model name. Required for openai-compatible, ignored for local."),
164943
+ endpoint: exports_external.string().optional().describe("API endpoint URL. Required when provider is openai-compatible."),
164944
+ api_key: exports_external.string().optional().describe("API key for remote embedding provider (optional)"),
164945
+ input_type: exports_external.string().optional().describe("Optional input_type sent in the embedding request body. Required by some openai-compatible providers (e.g. NVIDIA NIM expects 'query' or 'passage'). Omitted from the request when unset."),
164946
+ truncate: exports_external.string().optional().describe("Optional truncate mode sent in the embedding request body (e.g. NVIDIA NIM accepts 'NONE' | 'START' | 'END'). Omitted from the request when unset.")
164912
164947
  }).superRefine((data, ctx) => {
164913
164948
  if (data.provider === "openai-compatible" && !data.endpoint?.trim()) {
164914
164949
  ctx.addIssue({
@@ -164934,76 +164969,80 @@ var EmbeddingConfigSchema = BaseEmbeddingConfigSchema.transform((data) => {
164934
164969
  }
164935
164970
  if (data.provider === "openai-compatible") {
164936
164971
  const apiKey = data.api_key?.trim();
164972
+ const inputType = data.input_type?.trim();
164973
+ const truncate = data.truncate?.trim();
164937
164974
  return {
164938
164975
  provider: "openai-compatible",
164939
164976
  model: data.model?.trim() ?? "",
164940
164977
  endpoint: data.endpoint?.trim() ?? "",
164941
- ...apiKey ? { api_key: apiKey } : {}
164978
+ ...apiKey ? { api_key: apiKey } : {},
164979
+ ...inputType ? { input_type: inputType } : {},
164980
+ ...truncate ? { truncate } : {}
164942
164981
  };
164943
164982
  }
164944
164983
  return { provider: "off" };
164945
164984
  });
164946
164985
  var MagicContextConfigSchema = exports_external.object({
164947
- enabled: exports_external.boolean().default(true),
164948
- auto_update: exports_external.boolean().optional(),
164949
- ctx_reduce_enabled: exports_external.boolean().default(true),
164950
- historian: HistorianConfigSchema,
164951
- dreamer: DreamerConfigSchema.optional(),
164952
- cache_ttl: exports_external.union([exports_external.string(), exports_external.object({ default: exports_external.string() }).catchall(exports_external.string())]).default("5m"),
164953
- nudge_interval_tokens: exports_external.number().min(1000).default(DEFAULT_NUDGE_INTERVAL_TOKENS),
164986
+ enabled: exports_external.boolean().default(true).describe("Enable magic context (default: true)"),
164987
+ auto_update: exports_external.boolean().optional().describe("Enable automatic npm self-update checks for the OpenCode plugin. Security: USER-only in config loader, so hostile project configs cannot suppress updates."),
164988
+ ctx_reduce_enabled: exports_external.boolean().default(true).describe("When false, ctx_reduce tool is hidden, all nudges disabled, and prompt guidance about ctx_reduce stripped. Heuristic cleanup, compartments, memory, and other features still work. (default: true)"),
164989
+ historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
164990
+ dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
164991
+ cache_ttl: exports_external.union([exports_external.string(), exports_external.object({ default: exports_external.string() }).catchall(exports_external.string())]).default("5m").describe('Cache TTL: string (e.g. "5m") or per-model object ({ default: "5m", "model-id": "10m" })'),
164992
+ nudge_interval_tokens: exports_external.number().min(1000).default(DEFAULT_NUDGE_INTERVAL_TOKENS).describe("Minimum token growth between low-priority rolling nudges (default: DEFAULT_NUDGE_INTERVAL_TOKENS)"),
164954
164993
  execute_threshold_percentage: exports_external.union([
164955
- exports_external.number().min(20).max(80),
164956
- exports_external.object({ default: exports_external.number().min(20).max(80) }).catchall(exports_external.number().min(20).max(80))
164957
- ]).default(DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE),
164994
+ exports_external.number().min(20).max(80, EXECUTE_THRESHOLD_CAP_MESSAGE),
164995
+ exports_external.object({ default: exports_external.number().min(20).max(80, EXECUTE_THRESHOLD_CAP_MESSAGE) }).catchall(exports_external.number().min(20).max(80, EXECUTE_THRESHOLD_CAP_MESSAGE))
164996
+ ]).default(DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE).describe('Context percentage that forces queued operations to execute. Number or per-model object ({ default: 65, "provider/model": 45 }). Values above 80 are rejected because the runtime caps at 80% for cache safety (MAX_EXECUTE_THRESHOLD). Default: DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE'),
164958
164997
  execute_threshold_tokens: exports_external.object({
164959
164998
  default: exports_external.number().min(5000).max(2000000).optional()
164960
- }).catchall(exports_external.number().min(5000).max(2000000)).optional(),
164961
- protected_tags: exports_external.number().min(1).max(100).optional(),
164962
- auto_drop_tool_age: exports_external.number().min(10).default(100),
164963
- drop_tool_structure: exports_external.boolean().default(true),
164964
- clear_reasoning_age: exports_external.number().min(10).default(50),
164965
- iteration_nudge_threshold: exports_external.number().min(5).default(15),
164966
- history_budget_percentage: exports_external.number().min(0.05).max(0.5).default(DEFAULT_HISTORY_BUDGET_PERCENTAGE),
164967
- historian_timeout_ms: exports_external.number().min(60000).default(DEFAULT_HISTORIAN_TIMEOUT_MS),
164999
+ }).catchall(exports_external.number().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 80% × context_limit are clamped with a warning log. Min 5_000, max 2_000_000."),
165000
+ protected_tags: exports_external.number().min(1).max(100).optional().describe("Number of recent tags to protect from dropping (min: 1, max: 100, default: 20)"),
165001
+ auto_drop_tool_age: exports_external.number().min(10).default(100).describe("Auto-drop tool outputs older than N tags during queue execution (default: 100)"),
165002
+ drop_tool_structure: exports_external.boolean().default(true).describe("When true, dropped tool parts are fully removed instead of truncated in place (default: true)"),
165003
+ clear_reasoning_age: exports_external.number().min(10).default(50).describe("Clear reasoning/thinking blocks older than N tags (default: 50)"),
165004
+ iteration_nudge_threshold: exports_external.number().min(5).default(15).describe("Number of consecutive assistant messages without user input to trigger iteration nudge (default: 15)"),
165005
+ history_budget_percentage: exports_external.number().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)"),
165006
+ historian_timeout_ms: exports_external.number().min(60000).default(DEFAULT_HISTORIAN_TIMEOUT_MS).describe("Timeout for each historian prompt call in milliseconds (default: 300000)"),
164968
165007
  commit_cluster_trigger: exports_external.object({
164969
- enabled: exports_external.boolean().default(true),
164970
- min_clusters: exports_external.number().min(1).default(3)
164971
- }).default({ enabled: true, min_clusters: 3 }),
165008
+ enabled: exports_external.boolean().default(true).describe("Enable commit-cluster based historian triggering (default: true)"),
165009
+ min_clusters: exports_external.number().min(1).default(3).describe("Minimum commit clusters required to trigger historian (min: 1, default: 3)")
165010
+ }).default({ enabled: true, min_clusters: 3 }).describe("Commit-cluster trigger: fire historian when enough commit clusters accumulate in the unsummarized tail"),
164972
165011
  system_prompt_injection: exports_external.object({
164973
- enabled: exports_external.boolean().default(true),
164974
- skip_signatures: exports_external.array(exports_external.string()).default(["<!-- magic-context: skip -->"])
165012
+ enabled: exports_external.boolean().default(true).describe("When false, NO injection happens for ANY agent — global escape hatch. (default: true)"),
165013
+ skip_signatures: exports_external.array(exports_external.string()).default(["<!-- magic-context: skip -->"]).describe(`Substring opt-out list. If the agent's system prompt contains any of these strings, skip ALL Magic Context injection for that call. Default "<!-- magic-context: skip -->" is meant to be added inside a user's custom agent prompt to opt that agent out.`)
164975
165014
  }).default({
164976
165015
  enabled: true,
164977
165016
  skip_signatures: ["<!-- magic-context: skip -->"]
164978
- }),
165017
+ }).describe("Controls whether and where Magic Context augments the system prompt. Lets users opt specific agents out of the Magic Context guidance and the surrounding project-docs / user-profile / key-files blocks. OpenCode's internal hidden agents — title, summary, and compaction — are always skipped automatically."),
164979
165018
  sqlite: exports_external.object({
164980
- cache_size_mb: exports_external.number().min(2).max(2048).default(64),
164981
- mmap_size_mb: exports_external.number().min(0).max(8192).default(0)
164982
- }).default({ cache_size_mb: 64, mmap_size_mb: 0 }),
165019
+ cache_size_mb: exports_external.number().min(2).max(2048).default(64).describe("Page-cache size in MiB per connection (PRAGMA cache_size). Larger keeps more hot pages resident, cutting re-reads on repeated full-table scans. (min 2, max 2048, default 64)"),
165020
+ mmap_size_mb: exports_external.number().min(0).max(8192).default(0).describe("Memory-mapped I/O size in MiB (PRAGMA mmap_size). 0 disables mmap (SQLite default). Raising it can cut read overhead on large DBs at the cost of address space. (min 0, max 8192, default 0)")
165021
+ }).default({ cache_size_mb: 64, mmap_size_mb: 0 }).describe("SQLite connection tuning for Magic Context's own context.db. These are per-connection PRAGMAs applied at open; they do not change the schema or what is stored."),
164983
165022
  embedding: EmbeddingConfigSchema.default({
164984
165023
  provider: "local",
164985
165024
  model: DEFAULT_LOCAL_EMBEDDING_MODEL
164986
- }),
164987
- temporal_awareness: exports_external.boolean().default(true),
165025
+ }).describe("Embedding provider configuration"),
165026
+ 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).'),
164988
165027
  caveman_text_compression: exports_external.object({
164989
- enabled: exports_external.boolean().default(false),
164990
- min_chars: exports_external.number().min(100).max(1e4).default(500)
164991
- }).default({ enabled: false, min_chars: 500 }),
165028
+ 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%)."),
165029
+ 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.")
165030
+ }).default({ enabled: false, min_chars: 500 }).describe("Age-tier caveman compression for long user/assistant text parts. Only active when ctx_reduce_enabled is false. Oldest 20% of eligible tags (outside protected tail) go to ultra, next 20% to full, next 20% to lite, newest 40% untouched. Graduated from experimental.caveman_text_compression; opt-in, default off (lossy)."),
164992
165031
  memory: exports_external.object({
164993
- enabled: exports_external.boolean().default(true),
164994
- injection_budget_tokens: exports_external.number().min(500).max(20000).default(4000),
164995
- auto_promote: exports_external.boolean().default(true),
164996
- retrieval_count_promotion_threshold: exports_external.number().min(1).default(3),
165032
+ enabled: exports_external.boolean().default(true).describe("Enable cross-session memory (default: true)"),
165033
+ injection_budget_tokens: exports_external.number().min(500).max(20000).default(4000).describe("Token budget for memory injection on session start (min: 500, max: 20000, default: 4000)"),
165034
+ auto_promote: exports_external.boolean().default(true).describe("Automatically promote eligible session facts into memory (default: true)"),
165035
+ retrieval_count_promotion_threshold: exports_external.number().min(1).default(3).describe("retrieval_count threshold for promoting memory to permanent status (min: 1, default: 3)"),
164997
165036
  auto_search: exports_external.object({
164998
- enabled: exports_external.boolean().default(true),
164999
- score_threshold: exports_external.number().min(0.3).max(0.95).default(0.6),
165000
- min_prompt_chars: exports_external.number().min(5).max(500).default(20)
165001
- }).default({ enabled: true, score_threshold: 0.6, min_prompt_chars: 20 }),
165037
+ enabled: exports_external.boolean().default(true).describe("Automatically append a compact <ctx-search-hint> to eligible user messages when relevant memories, conversation, or commits are found. Graduated from experimental.auto_search; on by default (set false to opt out). Independent of memory.enabled."),
165038
+ score_threshold: exports_external.number().min(0.3).max(0.95).default(0.6).describe("Top hit score must exceed this threshold for the hint to fire (min: 0.3, max: 0.95, default: 0.60)"),
165039
+ min_prompt_chars: exports_external.number().min(5).max(500).default(20).describe("Skip hint when user message is shorter than this (min: 5, max: 500, default: 20)")
165040
+ }).default({ enabled: true, score_threshold: 0.6, min_prompt_chars: 20 }).describe("Auto-search hint: transform-time ctx_search on each new user message; when the top hit clears the threshold, append a compact <ctx-search-hint> block of vague fragments to that user message. Does NOT inject full content. Graduated from experimental.auto_search; enabled by default (set enabled: false to opt out). Independent of memory.enabled."),
165002
165041
  git_commit_indexing: exports_external.object({
165003
- enabled: exports_external.boolean().default(false),
165004
- since_days: exports_external.number().min(7).max(3650).default(365),
165005
- max_commits: exports_external.number().min(100).max(20000).default(2000)
165006
- }).default({ enabled: false, since_days: 365, max_commits: 2000 })
165042
+ enabled: exports_external.boolean().default(false).describe("Index HEAD git commits for ctx_search (git_commit source). Graduated from experimental.git_commit_indexing; opt-in, default off. Independent of memory.enabled."),
165043
+ since_days: exports_external.number().min(7).max(3650).default(365).describe("Days of HEAD history to index (min: 7, max: 3650, default: 365)"),
165044
+ max_commits: exports_external.number().min(100).max(20000).default(2000).describe("Max commits kept per project; oldest evicted (min: 100, max: 20000, default: 2000)")
165045
+ }).default({ enabled: false, since_days: 365, max_commits: 2000 }).describe("Index git commit messages from HEAD into ctx_search. Commits become a 4th searchable source alongside memories and session history. Graduated from experimental.git_commit_indexing; opt-in, default off (per-project embedding cost). Independent of memory.enabled.")
165007
165046
  }).default({
165008
165047
  enabled: true,
165009
165048
  injection_budget_tokens: 4000,
@@ -165011,8 +165050,8 @@ var MagicContextConfigSchema = exports_external.object({
165011
165050
  retrieval_count_promotion_threshold: 3,
165012
165051
  auto_search: { enabled: true, score_threshold: 0.6, min_prompt_chars: 20 },
165013
165052
  git_commit_indexing: { enabled: false, since_days: 365, max_commits: 2000 }
165014
- }),
165015
- sidekick: SidekickConfigSchema
165053
+ }).describe("Cross-session memory configuration"),
165054
+ sidekick: SidekickConfigSchema.describe("Optional sidekick agent configuration for session-start memory retrieval")
165016
165055
  }).transform((data) => {
165017
165056
  return {
165018
165057
  ...data,
@@ -165052,7 +165091,8 @@ function getEmbeddingProviderIdentity(config2) {
165052
165091
  provider: "openai-compatible",
165053
165092
  model: config2.model.trim(),
165054
165093
  endpoint: normalizeEndpoint(config2.endpoint),
165055
- apiKeyPresent: Boolean(config2.api_key?.trim())
165094
+ apiKeyPresent: Boolean(config2.api_key?.trim()),
165095
+ inputType: config2.input_type?.trim() || ""
165056
165096
  } : {
165057
165097
  provider: "local",
165058
165098
  model: config2.model?.trim() || DEFAULT_LOCAL_EMBEDDING_MODEL,
@@ -165418,6 +165458,8 @@ class OpenAICompatibleEmbeddingProvider {
165418
165458
  endpoint;
165419
165459
  model;
165420
165460
  apiKey;
165461
+ inputType;
165462
+ truncate;
165421
165463
  initialized = false;
165422
165464
  failureTimes = [];
165423
165465
  circuitOpenUntil = 0;
@@ -165427,6 +165469,8 @@ class OpenAICompatibleEmbeddingProvider {
165427
165469
  this.endpoint = normalizeEndpoint2(options.endpoint);
165428
165470
  this.model = options.model?.trim() ?? "";
165429
165471
  this.apiKey = options.apiKey?.trim() ?? "";
165472
+ this.inputType = options.inputType?.trim() ?? "";
165473
+ this.truncate = options.truncate?.trim() ?? "";
165430
165474
  this.modelId = getEmbeddingProviderIdentity({
165431
165475
  provider: "openai-compatible",
165432
165476
  endpoint: this.endpoint,
@@ -165483,7 +165527,9 @@ class OpenAICompatibleEmbeddingProvider {
165483
165527
  },
165484
165528
  body: JSON.stringify({
165485
165529
  model: this.model,
165486
- input: texts
165530
+ input: texts,
165531
+ ...this.inputType ? { input_type: this.inputType } : {},
165532
+ ...this.truncate ? { truncate: this.truncate } : {}
165487
165533
  }),
165488
165534
  signal: internalController.signal
165489
165535
  });
@@ -165999,7 +166045,9 @@ function createProvider2(config2) {
165999
166045
  return new OpenAICompatibleEmbeddingProvider({
166000
166046
  endpoint: config2.endpoint,
166001
166047
  model: config2.model,
166002
- apiKey: config2.api_key
166048
+ apiKey: config2.api_key,
166049
+ inputType: config2.input_type,
166050
+ truncate: config2.truncate
166003
166051
  });
166004
166052
  }
166005
166053
  return new LocalEmbeddingProvider(config2.model);
@@ -180430,7 +180478,7 @@ function formatThresholdPercent(value) {
180430
180478
  // package.json
180431
180479
  var package_default = {
180432
180480
  name: "@cortexkit/pi-magic-context",
180433
- version: "0.22.0",
180481
+ version: "0.22.1",
180434
180482
  type: "module",
180435
180483
  description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
180436
180484
  main: "dist/index.js",
@@ -157156,25 +157156,26 @@ var PermissionSchema = exports_external.object({
157156
157156
  external_directory: PermissionValueSchema.optional()
157157
157157
  }).optional();
157158
157158
  var AgentOverrideConfigSchema = exports_external.object({
157159
- model: exports_external.string().optional(),
157160
- temperature: exports_external.number().min(0).max(2).optional(),
157161
- top_p: exports_external.number().min(0).max(1).optional(),
157162
- prompt: exports_external.string().optional(),
157163
- tools: exports_external.record(exports_external.string(), exports_external.boolean()).optional(),
157164
- disable: exports_external.boolean().optional(),
157165
- description: exports_external.string().optional(),
157166
- mode: exports_external.enum(["subagent", "primary", "all"]).optional(),
157167
- color: exports_external.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),
157168
- maxSteps: exports_external.number().optional(),
157169
- permission: PermissionSchema,
157170
- maxTokens: exports_external.number().optional(),
157171
- variant: exports_external.string().optional(),
157172
- fallback_models: exports_external.union([exports_external.string(), exports_external.array(exports_external.string())]).optional()
157159
+ model: exports_external.string().optional().describe("Primary model ID (e.g. 'claude-sonnet-4-6')"),
157160
+ temperature: exports_external.number().min(0).max(2).optional().describe("Sampling temperature (0-2)"),
157161
+ top_p: exports_external.number().min(0).max(1).optional().describe("Nucleus sampling top_p (0-1)"),
157162
+ prompt: exports_external.string().optional().describe("Additional system prompt text"),
157163
+ tools: exports_external.record(exports_external.string(), exports_external.boolean()).optional().describe("Tool enable/disable overrides"),
157164
+ disable: exports_external.boolean().optional().describe("Disable this agent"),
157165
+ description: exports_external.string().optional().describe("Agent description"),
157166
+ mode: exports_external.enum(["subagent", "primary", "all"]).optional().describe("Agent mode (subagent, primary, or all)"),
157167
+ color: exports_external.string().regex(/^#[0-9A-Fa-f]{6}$/).optional().describe("Hex color for the agent (e.g. '#a1b2c3')"),
157168
+ maxSteps: exports_external.number().optional().describe("Maximum tool-call steps per invocation"),
157169
+ permission: PermissionSchema.describe("Per-tool permission overrides"),
157170
+ maxTokens: exports_external.number().optional().describe("Maximum output tokens"),
157171
+ variant: exports_external.string().optional().describe("OpenCode reasoning variant (e.g. for extended thinking)"),
157172
+ fallback_models: exports_external.union([exports_external.string(), exports_external.array(exports_external.string())]).optional().describe("Fallback model IDs if primary is unavailable")
157173
157173
  });
157174
157174
 
157175
157175
  // ../plugin/src/config/schema/magic-context.ts
157176
157176
  var DEFAULT_NUDGE_INTERVAL_TOKENS = 1e4;
157177
157177
  var DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65;
157178
+ var EXECUTE_THRESHOLD_CAP_MESSAGE = "execute_threshold is capped at 80% for cache safety: a single large agent step can overflow the context window before Magic Context can compact between turns, forcing OpenCode's native compaction (hard to recover from). 80% also leaves headroom below the 85%/95% emergency bands. Use a value between 20 and 80.";
157178
157179
  var DEFAULT_HISTORIAN_TIMEOUT_MS = 300000;
157179
157180
  var DEFAULT_HISTORY_BUDGET_PERCENTAGE = 0.15;
157180
157181
  var DEFAULT_LOCAL_EMBEDDING_MODEL = "Xenova/all-MiniLM-L6-v2";
@@ -157194,36 +157195,38 @@ var DEFAULT_DREAMER_TASKS = [
157194
157195
  ];
157195
157196
  var PiThinkingLevelSchema = exports_external.enum(["off", "minimal", "low", "medium", "high", "xhigh"]).optional();
157196
157197
  var DreamerConfigSchema = AgentOverrideConfigSchema.merge(exports_external.object({
157197
- schedule: exports_external.string().default("02:00-06:00"),
157198
- max_runtime_minutes: exports_external.number().min(10).default(120),
157199
- tasks: exports_external.array(DreamingTaskSchema).default(DEFAULT_DREAMER_TASKS),
157200
- task_timeout_minutes: exports_external.number().min(5).default(20),
157201
- inject_docs: exports_external.boolean().default(true),
157198
+ schedule: exports_external.string().default("02:00-06:00").describe("Scheduled window for overnight dreaming (e.g. '02:00-06:00')"),
157199
+ max_runtime_minutes: exports_external.number().min(10).default(120).describe("Maximum runtime per dream session in minutes"),
157200
+ tasks: exports_external.array(DreamingTaskSchema).default(DEFAULT_DREAMER_TASKS).describe("Tasks to run during dreaming, in order"),
157201
+ task_timeout_minutes: exports_external.number().min(5).default(20).describe("Minutes allocated per task before moving to next"),
157202
+ inject_docs: exports_external.boolean().default(true).describe("Inject ARCHITECTURE.md and STRUCTURE.md into system prompt"),
157202
157203
  user_memories: exports_external.object({
157203
- enabled: exports_external.boolean().default(true),
157204
- promotion_threshold: exports_external.number().min(2).max(20).default(3)
157205
- }).default({ enabled: true, promotion_threshold: 3 }),
157204
+ enabled: exports_external.boolean().default(true).describe("Enable user memory extraction and promotion (default: true)"),
157205
+ promotion_threshold: exports_external.number().min(2).max(20).default(3).describe("Minimum candidate observations before dreamer considers promotion (default: 3)")
157206
+ }).default({ enabled: true, promotion_threshold: 3 }).describe("User memory pipeline: historian extracts behavior observations from each compartment run; dreamer reviews recurring patterns and promotes them to stable user memories injected into all sessions as <user-profile>. Requires dreamer to not be disabled for promotion to actually happen. Graduated from experimental in v0.14. Default: enabled."),
157206
157207
  pin_key_files: exports_external.object({
157207
- enabled: exports_external.boolean().default(false),
157208
- token_budget: exports_external.number().min(2000).max(30000).default(1e4),
157209
- min_reads: exports_external.number().min(2).max(20).default(4)
157210
- }).default({ enabled: false, token_budget: 1e4, min_reads: 4 }),
157211
- thinking_level: PiThinkingLevelSchema
157208
+ enabled: exports_external.boolean().default(false).describe("Enable key file pinning (default: false)"),
157209
+ token_budget: exports_external.number().min(2000).max(30000).default(1e4).describe("Total token budget for all pinned key files (min: 2000, max: 30000, default: 10000)"),
157210
+ min_reads: exports_external.number().min(2).max(20).default(4).describe("Minimum full-read count before a file is considered for pinning (min: 2, default: 4)")
157211
+ }).default({ enabled: false, token_budget: 1e4, min_reads: 4 }).describe("Pin frequently-read key files into the system prompt so the agent doesn't need to re-read them after context drops. Dreamer identifies key files per session based on read patterns. Requires dreamer to not be disabled for selection to happen. Graduated from experimental in v0.14. Default: disabled."),
157212
+ thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level for dreamer subagent invocations. See historian.thinking_level.")
157212
157213
  }));
157213
157214
  var SidekickConfigSchema = AgentOverrideConfigSchema.extend({
157214
- timeout_ms: exports_external.number().default(30000),
157215
- system_prompt: exports_external.string().optional(),
157216
- thinking_level: PiThinkingLevelSchema
157215
+ timeout_ms: exports_external.number().default(30000).describe("Timeout for sidekick calls in milliseconds"),
157216
+ system_prompt: exports_external.string().optional().describe("Custom system prompt for sidekick"),
157217
+ thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level for sidekick subagent invocations. See historian.thinking_level.")
157217
157218
  }).optional();
157218
157219
  var HistorianConfigSchema = AgentOverrideConfigSchema.extend({
157219
- two_pass: exports_external.boolean().default(false),
157220
- thinking_level: PiThinkingLevelSchema
157220
+ two_pass: exports_external.boolean().default(false).describe("Run a second editor pass over historian output to clean low-signal U: lines and cross-compartment duplicates. Adds ~1 extra API call and ~1.3x cost per historian run. Useful for models without extended thinking support. (default: false)"),
157221
+ thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level passed as --thinking <level> to Pi historian subagent invocations. Required when using reasoning models (e.g. github-copilot/gpt-5.4) because Pi's default thinking-level resolution can pick a value the provider rejects. OpenCode users set variant instead. Valid: off | minimal | low | medium | high | xhigh")
157221
157222
  }).optional();
157222
157223
  var BaseEmbeddingConfigSchema = exports_external.object({
157223
- provider: exports_external.enum(["local", "openai-compatible", "off"]).default("local"),
157224
- model: exports_external.string().optional(),
157225
- endpoint: exports_external.string().optional(),
157226
- api_key: exports_external.string().optional()
157224
+ provider: exports_external.enum(["local", "openai-compatible", "off"]).default("local").describe("Embedding provider. 'local' uses Xenova/all-MiniLM-L6-v2, 'openai-compatible' requires endpoint and model, 'off' disables embeddings."),
157225
+ model: exports_external.string().optional().describe("Embedding model name. Required for openai-compatible, ignored for local."),
157226
+ endpoint: exports_external.string().optional().describe("API endpoint URL. Required when provider is openai-compatible."),
157227
+ api_key: exports_external.string().optional().describe("API key for remote embedding provider (optional)"),
157228
+ input_type: exports_external.string().optional().describe("Optional input_type sent in the embedding request body. Required by some openai-compatible providers (e.g. NVIDIA NIM expects 'query' or 'passage'). Omitted from the request when unset."),
157229
+ truncate: exports_external.string().optional().describe("Optional truncate mode sent in the embedding request body (e.g. NVIDIA NIM accepts 'NONE' | 'START' | 'END'). Omitted from the request when unset.")
157227
157230
  }).superRefine((data, ctx) => {
157228
157231
  if (data.provider === "openai-compatible" && !data.endpoint?.trim()) {
157229
157232
  ctx.addIssue({
@@ -157249,76 +157252,80 @@ var EmbeddingConfigSchema = BaseEmbeddingConfigSchema.transform((data) => {
157249
157252
  }
157250
157253
  if (data.provider === "openai-compatible") {
157251
157254
  const apiKey = data.api_key?.trim();
157255
+ const inputType = data.input_type?.trim();
157256
+ const truncate = data.truncate?.trim();
157252
157257
  return {
157253
157258
  provider: "openai-compatible",
157254
157259
  model: data.model?.trim() ?? "",
157255
157260
  endpoint: data.endpoint?.trim() ?? "",
157256
- ...apiKey ? { api_key: apiKey } : {}
157261
+ ...apiKey ? { api_key: apiKey } : {},
157262
+ ...inputType ? { input_type: inputType } : {},
157263
+ ...truncate ? { truncate } : {}
157257
157264
  };
157258
157265
  }
157259
157266
  return { provider: "off" };
157260
157267
  });
157261
157268
  var MagicContextConfigSchema = exports_external.object({
157262
- enabled: exports_external.boolean().default(true),
157263
- auto_update: exports_external.boolean().optional(),
157264
- ctx_reduce_enabled: exports_external.boolean().default(true),
157265
- historian: HistorianConfigSchema,
157266
- dreamer: DreamerConfigSchema.optional(),
157267
- cache_ttl: exports_external.union([exports_external.string(), exports_external.object({ default: exports_external.string() }).catchall(exports_external.string())]).default("5m"),
157268
- nudge_interval_tokens: exports_external.number().min(1000).default(DEFAULT_NUDGE_INTERVAL_TOKENS),
157269
+ enabled: exports_external.boolean().default(true).describe("Enable magic context (default: true)"),
157270
+ auto_update: exports_external.boolean().optional().describe("Enable automatic npm self-update checks for the OpenCode plugin. Security: USER-only in config loader, so hostile project configs cannot suppress updates."),
157271
+ ctx_reduce_enabled: exports_external.boolean().default(true).describe("When false, ctx_reduce tool is hidden, all nudges disabled, and prompt guidance about ctx_reduce stripped. Heuristic cleanup, compartments, memory, and other features still work. (default: true)"),
157272
+ historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
157273
+ dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
157274
+ cache_ttl: exports_external.union([exports_external.string(), exports_external.object({ default: exports_external.string() }).catchall(exports_external.string())]).default("5m").describe('Cache TTL: string (e.g. "5m") or per-model object ({ default: "5m", "model-id": "10m" })'),
157275
+ nudge_interval_tokens: exports_external.number().min(1000).default(DEFAULT_NUDGE_INTERVAL_TOKENS).describe("Minimum token growth between low-priority rolling nudges (default: DEFAULT_NUDGE_INTERVAL_TOKENS)"),
157269
157276
  execute_threshold_percentage: exports_external.union([
157270
- exports_external.number().min(20).max(80),
157271
- exports_external.object({ default: exports_external.number().min(20).max(80) }).catchall(exports_external.number().min(20).max(80))
157272
- ]).default(DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE),
157277
+ exports_external.number().min(20).max(80, EXECUTE_THRESHOLD_CAP_MESSAGE),
157278
+ exports_external.object({ default: exports_external.number().min(20).max(80, EXECUTE_THRESHOLD_CAP_MESSAGE) }).catchall(exports_external.number().min(20).max(80, EXECUTE_THRESHOLD_CAP_MESSAGE))
157279
+ ]).default(DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE).describe('Context percentage that forces queued operations to execute. Number or per-model object ({ default: 65, "provider/model": 45 }). Values above 80 are rejected because the runtime caps at 80% for cache safety (MAX_EXECUTE_THRESHOLD). Default: DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE'),
157273
157280
  execute_threshold_tokens: exports_external.object({
157274
157281
  default: exports_external.number().min(5000).max(2000000).optional()
157275
- }).catchall(exports_external.number().min(5000).max(2000000)).optional(),
157276
- protected_tags: exports_external.number().min(1).max(100).optional(),
157277
- auto_drop_tool_age: exports_external.number().min(10).default(100),
157278
- drop_tool_structure: exports_external.boolean().default(true),
157279
- clear_reasoning_age: exports_external.number().min(10).default(50),
157280
- iteration_nudge_threshold: exports_external.number().min(5).default(15),
157281
- history_budget_percentage: exports_external.number().min(0.05).max(0.5).default(DEFAULT_HISTORY_BUDGET_PERCENTAGE),
157282
- historian_timeout_ms: exports_external.number().min(60000).default(DEFAULT_HISTORIAN_TIMEOUT_MS),
157282
+ }).catchall(exports_external.number().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 80% × context_limit are clamped with a warning log. Min 5_000, max 2_000_000."),
157283
+ protected_tags: exports_external.number().min(1).max(100).optional().describe("Number of recent tags to protect from dropping (min: 1, max: 100, default: 20)"),
157284
+ auto_drop_tool_age: exports_external.number().min(10).default(100).describe("Auto-drop tool outputs older than N tags during queue execution (default: 100)"),
157285
+ drop_tool_structure: exports_external.boolean().default(true).describe("When true, dropped tool parts are fully removed instead of truncated in place (default: true)"),
157286
+ clear_reasoning_age: exports_external.number().min(10).default(50).describe("Clear reasoning/thinking blocks older than N tags (default: 50)"),
157287
+ iteration_nudge_threshold: exports_external.number().min(5).default(15).describe("Number of consecutive assistant messages without user input to trigger iteration nudge (default: 15)"),
157288
+ history_budget_percentage: exports_external.number().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)"),
157289
+ historian_timeout_ms: exports_external.number().min(60000).default(DEFAULT_HISTORIAN_TIMEOUT_MS).describe("Timeout for each historian prompt call in milliseconds (default: 300000)"),
157283
157290
  commit_cluster_trigger: exports_external.object({
157284
- enabled: exports_external.boolean().default(true),
157285
- min_clusters: exports_external.number().min(1).default(3)
157286
- }).default({ enabled: true, min_clusters: 3 }),
157291
+ enabled: exports_external.boolean().default(true).describe("Enable commit-cluster based historian triggering (default: true)"),
157292
+ min_clusters: exports_external.number().min(1).default(3).describe("Minimum commit clusters required to trigger historian (min: 1, default: 3)")
157293
+ }).default({ enabled: true, min_clusters: 3 }).describe("Commit-cluster trigger: fire historian when enough commit clusters accumulate in the unsummarized tail"),
157287
157294
  system_prompt_injection: exports_external.object({
157288
- enabled: exports_external.boolean().default(true),
157289
- skip_signatures: exports_external.array(exports_external.string()).default(["<!-- magic-context: skip -->"])
157295
+ enabled: exports_external.boolean().default(true).describe("When false, NO injection happens for ANY agent — global escape hatch. (default: true)"),
157296
+ skip_signatures: exports_external.array(exports_external.string()).default(["<!-- magic-context: skip -->"]).describe(`Substring opt-out list. If the agent's system prompt contains any of these strings, skip ALL Magic Context injection for that call. Default "<!-- magic-context: skip -->" is meant to be added inside a user's custom agent prompt to opt that agent out.`)
157290
157297
  }).default({
157291
157298
  enabled: true,
157292
157299
  skip_signatures: ["<!-- magic-context: skip -->"]
157293
- }),
157300
+ }).describe("Controls whether and where Magic Context augments the system prompt. Lets users opt specific agents out of the Magic Context guidance and the surrounding project-docs / user-profile / key-files blocks. OpenCode's internal hidden agents — title, summary, and compaction — are always skipped automatically."),
157294
157301
  sqlite: exports_external.object({
157295
- cache_size_mb: exports_external.number().min(2).max(2048).default(64),
157296
- mmap_size_mb: exports_external.number().min(0).max(8192).default(0)
157297
- }).default({ cache_size_mb: 64, mmap_size_mb: 0 }),
157302
+ cache_size_mb: exports_external.number().min(2).max(2048).default(64).describe("Page-cache size in MiB per connection (PRAGMA cache_size). Larger keeps more hot pages resident, cutting re-reads on repeated full-table scans. (min 2, max 2048, default 64)"),
157303
+ mmap_size_mb: exports_external.number().min(0).max(8192).default(0).describe("Memory-mapped I/O size in MiB (PRAGMA mmap_size). 0 disables mmap (SQLite default). Raising it can cut read overhead on large DBs at the cost of address space. (min 0, max 8192, default 0)")
157304
+ }).default({ cache_size_mb: 64, mmap_size_mb: 0 }).describe("SQLite connection tuning for Magic Context's own context.db. These are per-connection PRAGMAs applied at open; they do not change the schema or what is stored."),
157298
157305
  embedding: EmbeddingConfigSchema.default({
157299
157306
  provider: "local",
157300
157307
  model: DEFAULT_LOCAL_EMBEDDING_MODEL
157301
- }),
157302
- temporal_awareness: exports_external.boolean().default(true),
157308
+ }).describe("Embedding provider configuration"),
157309
+ 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).'),
157303
157310
  caveman_text_compression: exports_external.object({
157304
- enabled: exports_external.boolean().default(false),
157305
- min_chars: exports_external.number().min(100).max(1e4).default(500)
157306
- }).default({ enabled: false, min_chars: 500 }),
157311
+ 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%)."),
157312
+ 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.")
157313
+ }).default({ enabled: false, min_chars: 500 }).describe("Age-tier caveman compression for long user/assistant text parts. Only active when ctx_reduce_enabled is false. Oldest 20% of eligible tags (outside protected tail) go to ultra, next 20% to full, next 20% to lite, newest 40% untouched. Graduated from experimental.caveman_text_compression; opt-in, default off (lossy)."),
157307
157314
  memory: exports_external.object({
157308
- enabled: exports_external.boolean().default(true),
157309
- injection_budget_tokens: exports_external.number().min(500).max(20000).default(4000),
157310
- auto_promote: exports_external.boolean().default(true),
157311
- retrieval_count_promotion_threshold: exports_external.number().min(1).default(3),
157315
+ enabled: exports_external.boolean().default(true).describe("Enable cross-session memory (default: true)"),
157316
+ injection_budget_tokens: exports_external.number().min(500).max(20000).default(4000).describe("Token budget for memory injection on session start (min: 500, max: 20000, default: 4000)"),
157317
+ auto_promote: exports_external.boolean().default(true).describe("Automatically promote eligible session facts into memory (default: true)"),
157318
+ retrieval_count_promotion_threshold: exports_external.number().min(1).default(3).describe("retrieval_count threshold for promoting memory to permanent status (min: 1, default: 3)"),
157312
157319
  auto_search: exports_external.object({
157313
- enabled: exports_external.boolean().default(true),
157314
- score_threshold: exports_external.number().min(0.3).max(0.95).default(0.6),
157315
- min_prompt_chars: exports_external.number().min(5).max(500).default(20)
157316
- }).default({ enabled: true, score_threshold: 0.6, min_prompt_chars: 20 }),
157320
+ enabled: exports_external.boolean().default(true).describe("Automatically append a compact <ctx-search-hint> to eligible user messages when relevant memories, conversation, or commits are found. Graduated from experimental.auto_search; on by default (set false to opt out). Independent of memory.enabled."),
157321
+ score_threshold: exports_external.number().min(0.3).max(0.95).default(0.6).describe("Top hit score must exceed this threshold for the hint to fire (min: 0.3, max: 0.95, default: 0.60)"),
157322
+ min_prompt_chars: exports_external.number().min(5).max(500).default(20).describe("Skip hint when user message is shorter than this (min: 5, max: 500, default: 20)")
157323
+ }).default({ enabled: true, score_threshold: 0.6, min_prompt_chars: 20 }).describe("Auto-search hint: transform-time ctx_search on each new user message; when the top hit clears the threshold, append a compact <ctx-search-hint> block of vague fragments to that user message. Does NOT inject full content. Graduated from experimental.auto_search; enabled by default (set enabled: false to opt out). Independent of memory.enabled."),
157317
157324
  git_commit_indexing: exports_external.object({
157318
- enabled: exports_external.boolean().default(false),
157319
- since_days: exports_external.number().min(7).max(3650).default(365),
157320
- max_commits: exports_external.number().min(100).max(20000).default(2000)
157321
- }).default({ enabled: false, since_days: 365, max_commits: 2000 })
157325
+ enabled: exports_external.boolean().default(false).describe("Index HEAD git commits for ctx_search (git_commit source). Graduated from experimental.git_commit_indexing; opt-in, default off. Independent of memory.enabled."),
157326
+ since_days: exports_external.number().min(7).max(3650).default(365).describe("Days of HEAD history to index (min: 7, max: 3650, default: 365)"),
157327
+ max_commits: exports_external.number().min(100).max(20000).default(2000).describe("Max commits kept per project; oldest evicted (min: 100, max: 20000, default: 2000)")
157328
+ }).default({ enabled: false, since_days: 365, max_commits: 2000 }).describe("Index git commit messages from HEAD into ctx_search. Commits become a 4th searchable source alongside memories and session history. Graduated from experimental.git_commit_indexing; opt-in, default off (per-project embedding cost). Independent of memory.enabled.")
157322
157329
  }).default({
157323
157330
  enabled: true,
157324
157331
  injection_budget_tokens: 4000,
@@ -157326,8 +157333,8 @@ var MagicContextConfigSchema = exports_external.object({
157326
157333
  retrieval_count_promotion_threshold: 3,
157327
157334
  auto_search: { enabled: true, score_threshold: 0.6, min_prompt_chars: 20 },
157328
157335
  git_commit_indexing: { enabled: false, since_days: 365, max_commits: 2000 }
157329
- }),
157330
- sidekick: SidekickConfigSchema
157336
+ }).describe("Cross-session memory configuration"),
157337
+ sidekick: SidekickConfigSchema.describe("Optional sidekick agent configuration for session-start memory retrieval")
157331
157338
  }).transform((data) => {
157332
157339
  return {
157333
157340
  ...data,
@@ -157791,7 +157798,8 @@ function getEmbeddingProviderIdentity(config2) {
157791
157798
  provider: "openai-compatible",
157792
157799
  model: config2.model.trim(),
157793
157800
  endpoint: normalizeEndpoint(config2.endpoint),
157794
- apiKeyPresent: Boolean(config2.api_key?.trim())
157801
+ apiKeyPresent: Boolean(config2.api_key?.trim()),
157802
+ inputType: config2.input_type?.trim() || ""
157795
157803
  } : {
157796
157804
  provider: "local",
157797
157805
  model: config2.model?.trim() || DEFAULT_LOCAL_EMBEDDING_MODEL,
@@ -158157,6 +158165,8 @@ class OpenAICompatibleEmbeddingProvider {
158157
158165
  endpoint;
158158
158166
  model;
158159
158167
  apiKey;
158168
+ inputType;
158169
+ truncate;
158160
158170
  initialized = false;
158161
158171
  failureTimes = [];
158162
158172
  circuitOpenUntil = 0;
@@ -158166,6 +158176,8 @@ class OpenAICompatibleEmbeddingProvider {
158166
158176
  this.endpoint = normalizeEndpoint2(options.endpoint);
158167
158177
  this.model = options.model?.trim() ?? "";
158168
158178
  this.apiKey = options.apiKey?.trim() ?? "";
158179
+ this.inputType = options.inputType?.trim() ?? "";
158180
+ this.truncate = options.truncate?.trim() ?? "";
158169
158181
  this.modelId = getEmbeddingProviderIdentity({
158170
158182
  provider: "openai-compatible",
158171
158183
  endpoint: this.endpoint,
@@ -158222,7 +158234,9 @@ class OpenAICompatibleEmbeddingProvider {
158222
158234
  },
158223
158235
  body: JSON.stringify({
158224
158236
  model: this.model,
158225
- input: texts
158237
+ input: texts,
158238
+ ...this.inputType ? { input_type: this.inputType } : {},
158239
+ ...this.truncate ? { truncate: this.truncate } : {}
158226
158240
  }),
158227
158241
  signal: internalController.signal
158228
158242
  });
@@ -158851,7 +158865,9 @@ function createProvider2(config2) {
158851
158865
  return new OpenAICompatibleEmbeddingProvider({
158852
158866
  endpoint: config2.endpoint,
158853
158867
  model: config2.model,
158854
- apiKey: config2.api_key
158868
+ apiKey: config2.api_key,
158869
+ inputType: config2.input_type,
158870
+ truncate: config2.truncate
158855
158871
  });
158856
158872
  }
158857
158873
  return new LocalEmbeddingProvider(config2.model);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/pi-magic-context",
3
- "version": "0.22.0",
3
+ "version": "0.22.1",
4
4
  "type": "module",
5
5
  "description": "Pi coding agent extension for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",