@cortexkit/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.
Files changed (2) hide show
  1. package/dist/index.js +118 -87
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -162149,25 +162149,25 @@ var init_agent_overrides = __esm(() => {
162149
162149
  external_directory: PermissionValueSchema.optional()
162150
162150
  }).optional();
162151
162151
  AgentOverrideConfigSchema = exports_external.object({
162152
- model: exports_external.string().optional(),
162153
- temperature: exports_external.number().min(0).max(2).optional(),
162154
- top_p: exports_external.number().min(0).max(1).optional(),
162155
- prompt: exports_external.string().optional(),
162156
- tools: exports_external.record(exports_external.string(), exports_external.boolean()).optional(),
162157
- disable: exports_external.boolean().optional(),
162158
- description: exports_external.string().optional(),
162159
- mode: exports_external.enum(["subagent", "primary", "all"]).optional(),
162160
- color: exports_external.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),
162161
- maxSteps: exports_external.number().optional(),
162162
- permission: PermissionSchema,
162163
- maxTokens: exports_external.number().optional(),
162164
- variant: exports_external.string().optional(),
162165
- fallback_models: exports_external.union([exports_external.string(), exports_external.array(exports_external.string())]).optional()
162152
+ model: exports_external.string().optional().describe("Primary model ID (e.g. 'claude-sonnet-4-6')"),
162153
+ temperature: exports_external.number().min(0).max(2).optional().describe("Sampling temperature (0-2)"),
162154
+ top_p: exports_external.number().min(0).max(1).optional().describe("Nucleus sampling top_p (0-1)"),
162155
+ prompt: exports_external.string().optional().describe("Additional system prompt text"),
162156
+ tools: exports_external.record(exports_external.string(), exports_external.boolean()).optional().describe("Tool enable/disable overrides"),
162157
+ disable: exports_external.boolean().optional().describe("Disable this agent"),
162158
+ description: exports_external.string().optional().describe("Agent description"),
162159
+ mode: exports_external.enum(["subagent", "primary", "all"]).optional().describe("Agent mode (subagent, primary, or all)"),
162160
+ color: exports_external.string().regex(/^#[0-9A-Fa-f]{6}$/).optional().describe("Hex color for the agent (e.g. '#a1b2c3')"),
162161
+ maxSteps: exports_external.number().optional().describe("Maximum tool-call steps per invocation"),
162162
+ permission: PermissionSchema.describe("Per-tool permission overrides"),
162163
+ maxTokens: exports_external.number().optional().describe("Maximum output tokens"),
162164
+ variant: exports_external.string().optional().describe("OpenCode reasoning variant (e.g. for extended thinking)"),
162165
+ fallback_models: exports_external.union([exports_external.string(), exports_external.array(exports_external.string())]).optional().describe("Fallback model IDs if primary is unavailable")
162166
162166
  });
162167
162167
  });
162168
162168
 
162169
162169
  // ../plugin/src/config/schema/magic-context.ts
162170
- var DEFAULT_NUDGE_INTERVAL_TOKENS = 1e4, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65, DEFAULT_HISTORIAN_TIMEOUT_MS = 300000, DEFAULT_HISTORY_BUDGET_PERCENTAGE = 0.15, DEFAULT_LOCAL_EMBEDDING_MODEL = "Xenova/all-MiniLM-L6-v2", DREAMER_TASKS, DreamingTaskSchema, DEFAULT_DREAMER_TASKS, PiThinkingLevelSchema, DreamerConfigSchema, SidekickConfigSchema, HistorianConfigSchema, BaseEmbeddingConfigSchema, EmbeddingConfigSchema, MagicContextConfigSchema;
162170
+ var DEFAULT_NUDGE_INTERVAL_TOKENS = 1e4, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE = 65, 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.", DEFAULT_HISTORIAN_TIMEOUT_MS = 300000, DEFAULT_HISTORY_BUDGET_PERCENTAGE = 0.15, DEFAULT_LOCAL_EMBEDDING_MODEL = "Xenova/all-MiniLM-L6-v2", DREAMER_TASKS, DreamingTaskSchema, DEFAULT_DREAMER_TASKS, PiThinkingLevelSchema, DreamerConfigSchema, SidekickConfigSchema, HistorianConfigSchema, BaseEmbeddingConfigSchema, EmbeddingConfigSchema, MagicContextConfigSchema;
162171
162171
  var init_magic_context = __esm(() => {
162172
162172
  init_zod();
162173
162173
  init_agent_overrides();
@@ -162187,36 +162187,38 @@ var init_magic_context = __esm(() => {
162187
162187
  ];
162188
162188
  PiThinkingLevelSchema = exports_external.enum(["off", "minimal", "low", "medium", "high", "xhigh"]).optional();
162189
162189
  DreamerConfigSchema = AgentOverrideConfigSchema.merge(exports_external.object({
162190
- schedule: exports_external.string().default("02:00-06:00"),
162191
- max_runtime_minutes: exports_external.number().min(10).default(120),
162192
- tasks: exports_external.array(DreamingTaskSchema).default(DEFAULT_DREAMER_TASKS),
162193
- task_timeout_minutes: exports_external.number().min(5).default(20),
162194
- inject_docs: exports_external.boolean().default(true),
162190
+ schedule: exports_external.string().default("02:00-06:00").describe("Scheduled window for overnight dreaming (e.g. '02:00-06:00')"),
162191
+ max_runtime_minutes: exports_external.number().min(10).default(120).describe("Maximum runtime per dream session in minutes"),
162192
+ tasks: exports_external.array(DreamingTaskSchema).default(DEFAULT_DREAMER_TASKS).describe("Tasks to run during dreaming, in order"),
162193
+ task_timeout_minutes: exports_external.number().min(5).default(20).describe("Minutes allocated per task before moving to next"),
162194
+ inject_docs: exports_external.boolean().default(true).describe("Inject ARCHITECTURE.md and STRUCTURE.md into system prompt"),
162195
162195
  user_memories: exports_external.object({
162196
- enabled: exports_external.boolean().default(true),
162197
- promotion_threshold: exports_external.number().min(2).max(20).default(3)
162198
- }).default({ enabled: true, promotion_threshold: 3 }),
162196
+ enabled: exports_external.boolean().default(true).describe("Enable user memory extraction and promotion (default: true)"),
162197
+ promotion_threshold: exports_external.number().min(2).max(20).default(3).describe("Minimum candidate observations before dreamer considers promotion (default: 3)")
162198
+ }).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."),
162199
162199
  pin_key_files: exports_external.object({
162200
- enabled: exports_external.boolean().default(false),
162201
- token_budget: exports_external.number().min(2000).max(30000).default(1e4),
162202
- min_reads: exports_external.number().min(2).max(20).default(4)
162203
- }).default({ enabled: false, token_budget: 1e4, min_reads: 4 }),
162204
- thinking_level: PiThinkingLevelSchema
162200
+ enabled: exports_external.boolean().default(false).describe("Enable key file pinning (default: false)"),
162201
+ 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)"),
162202
+ 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)")
162203
+ }).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."),
162204
+ thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level for dreamer subagent invocations. See historian.thinking_level.")
162205
162205
  }));
162206
162206
  SidekickConfigSchema = AgentOverrideConfigSchema.extend({
162207
- timeout_ms: exports_external.number().default(30000),
162208
- system_prompt: exports_external.string().optional(),
162209
- thinking_level: PiThinkingLevelSchema
162207
+ timeout_ms: exports_external.number().default(30000).describe("Timeout for sidekick calls in milliseconds"),
162208
+ system_prompt: exports_external.string().optional().describe("Custom system prompt for sidekick"),
162209
+ thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level for sidekick subagent invocations. See historian.thinking_level.")
162210
162210
  }).optional();
162211
162211
  HistorianConfigSchema = AgentOverrideConfigSchema.extend({
162212
- two_pass: exports_external.boolean().default(false),
162213
- thinking_level: PiThinkingLevelSchema
162212
+ 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)"),
162213
+ 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")
162214
162214
  }).optional();
162215
162215
  BaseEmbeddingConfigSchema = exports_external.object({
162216
- provider: exports_external.enum(["local", "openai-compatible", "off"]).default("local"),
162217
- model: exports_external.string().optional(),
162218
- endpoint: exports_external.string().optional(),
162219
- api_key: exports_external.string().optional()
162216
+ 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."),
162217
+ model: exports_external.string().optional().describe("Embedding model name. Required for openai-compatible, ignored for local."),
162218
+ endpoint: exports_external.string().optional().describe("API endpoint URL. Required when provider is openai-compatible."),
162219
+ api_key: exports_external.string().optional().describe("API key for remote embedding provider (optional)"),
162220
+ 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."),
162221
+ 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.")
162220
162222
  }).superRefine((data, ctx) => {
162221
162223
  if (data.provider === "openai-compatible" && !data.endpoint?.trim()) {
162222
162224
  ctx.addIssue({
@@ -162242,76 +162244,80 @@ var init_magic_context = __esm(() => {
162242
162244
  }
162243
162245
  if (data.provider === "openai-compatible") {
162244
162246
  const apiKey = data.api_key?.trim();
162247
+ const inputType = data.input_type?.trim();
162248
+ const truncate = data.truncate?.trim();
162245
162249
  return {
162246
162250
  provider: "openai-compatible",
162247
162251
  model: data.model?.trim() ?? "",
162248
162252
  endpoint: data.endpoint?.trim() ?? "",
162249
- ...apiKey ? { api_key: apiKey } : {}
162253
+ ...apiKey ? { api_key: apiKey } : {},
162254
+ ...inputType ? { input_type: inputType } : {},
162255
+ ...truncate ? { truncate } : {}
162250
162256
  };
162251
162257
  }
162252
162258
  return { provider: "off" };
162253
162259
  });
162254
162260
  MagicContextConfigSchema = exports_external.object({
162255
- enabled: exports_external.boolean().default(true),
162256
- auto_update: exports_external.boolean().optional(),
162257
- ctx_reduce_enabled: exports_external.boolean().default(true),
162258
- historian: HistorianConfigSchema,
162259
- dreamer: DreamerConfigSchema.optional(),
162260
- cache_ttl: exports_external.union([exports_external.string(), exports_external.object({ default: exports_external.string() }).catchall(exports_external.string())]).default("5m"),
162261
- nudge_interval_tokens: exports_external.number().min(1000).default(DEFAULT_NUDGE_INTERVAL_TOKENS),
162261
+ enabled: exports_external.boolean().default(true).describe("Enable magic context (default: true)"),
162262
+ 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."),
162263
+ 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)"),
162264
+ historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
162265
+ dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
162266
+ 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" })'),
162267
+ 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)"),
162262
162268
  execute_threshold_percentage: exports_external.union([
162263
- exports_external.number().min(20).max(80),
162264
- exports_external.object({ default: exports_external.number().min(20).max(80) }).catchall(exports_external.number().min(20).max(80))
162265
- ]).default(DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE),
162269
+ exports_external.number().min(20).max(80, EXECUTE_THRESHOLD_CAP_MESSAGE),
162270
+ 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))
162271
+ ]).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'),
162266
162272
  execute_threshold_tokens: exports_external.object({
162267
162273
  default: exports_external.number().min(5000).max(2000000).optional()
162268
- }).catchall(exports_external.number().min(5000).max(2000000)).optional(),
162269
- protected_tags: exports_external.number().min(1).max(100).optional(),
162270
- auto_drop_tool_age: exports_external.number().min(10).default(100),
162271
- drop_tool_structure: exports_external.boolean().default(true),
162272
- clear_reasoning_age: exports_external.number().min(10).default(50),
162273
- iteration_nudge_threshold: exports_external.number().min(5).default(15),
162274
- history_budget_percentage: exports_external.number().min(0.05).max(0.5).default(DEFAULT_HISTORY_BUDGET_PERCENTAGE),
162275
- historian_timeout_ms: exports_external.number().min(60000).default(DEFAULT_HISTORIAN_TIMEOUT_MS),
162274
+ }).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."),
162275
+ 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)"),
162276
+ 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)"),
162277
+ drop_tool_structure: exports_external.boolean().default(true).describe("When true, dropped tool parts are fully removed instead of truncated in place (default: true)"),
162278
+ clear_reasoning_age: exports_external.number().min(10).default(50).describe("Clear reasoning/thinking blocks older than N tags (default: 50)"),
162279
+ 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)"),
162280
+ 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)"),
162281
+ historian_timeout_ms: exports_external.number().min(60000).default(DEFAULT_HISTORIAN_TIMEOUT_MS).describe("Timeout for each historian prompt call in milliseconds (default: 300000)"),
162276
162282
  commit_cluster_trigger: exports_external.object({
162277
- enabled: exports_external.boolean().default(true),
162278
- min_clusters: exports_external.number().min(1).default(3)
162279
- }).default({ enabled: true, min_clusters: 3 }),
162283
+ enabled: exports_external.boolean().default(true).describe("Enable commit-cluster based historian triggering (default: true)"),
162284
+ min_clusters: exports_external.number().min(1).default(3).describe("Minimum commit clusters required to trigger historian (min: 1, default: 3)")
162285
+ }).default({ enabled: true, min_clusters: 3 }).describe("Commit-cluster trigger: fire historian when enough commit clusters accumulate in the unsummarized tail"),
162280
162286
  system_prompt_injection: exports_external.object({
162281
- enabled: exports_external.boolean().default(true),
162282
- skip_signatures: exports_external.array(exports_external.string()).default(["<!-- magic-context: skip -->"])
162287
+ enabled: exports_external.boolean().default(true).describe("When false, NO injection happens for ANY agent — global escape hatch. (default: true)"),
162288
+ 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.`)
162283
162289
  }).default({
162284
162290
  enabled: true,
162285
162291
  skip_signatures: ["<!-- magic-context: skip -->"]
162286
- }),
162292
+ }).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."),
162287
162293
  sqlite: exports_external.object({
162288
- cache_size_mb: exports_external.number().min(2).max(2048).default(64),
162289
- mmap_size_mb: exports_external.number().min(0).max(8192).default(0)
162290
- }).default({ cache_size_mb: 64, mmap_size_mb: 0 }),
162294
+ 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)"),
162295
+ 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)")
162296
+ }).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."),
162291
162297
  embedding: EmbeddingConfigSchema.default({
162292
162298
  provider: "local",
162293
162299
  model: DEFAULT_LOCAL_EMBEDDING_MODEL
162294
- }),
162295
- temporal_awareness: exports_external.boolean().default(true),
162300
+ }).describe("Embedding provider configuration"),
162301
+ 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).'),
162296
162302
  caveman_text_compression: exports_external.object({
162297
- enabled: exports_external.boolean().default(false),
162298
- min_chars: exports_external.number().min(100).max(1e4).default(500)
162299
- }).default({ enabled: false, min_chars: 500 }),
162303
+ 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%)."),
162304
+ 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.")
162305
+ }).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)."),
162300
162306
  memory: exports_external.object({
162301
- enabled: exports_external.boolean().default(true),
162302
- injection_budget_tokens: exports_external.number().min(500).max(20000).default(4000),
162303
- auto_promote: exports_external.boolean().default(true),
162304
- retrieval_count_promotion_threshold: exports_external.number().min(1).default(3),
162307
+ enabled: exports_external.boolean().default(true).describe("Enable cross-session memory (default: true)"),
162308
+ 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)"),
162309
+ auto_promote: exports_external.boolean().default(true).describe("Automatically promote eligible session facts into memory (default: true)"),
162310
+ 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)"),
162305
162311
  auto_search: exports_external.object({
162306
- enabled: exports_external.boolean().default(true),
162307
- score_threshold: exports_external.number().min(0.3).max(0.95).default(0.6),
162308
- min_prompt_chars: exports_external.number().min(5).max(500).default(20)
162309
- }).default({ enabled: true, score_threshold: 0.6, min_prompt_chars: 20 }),
162312
+ 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."),
162313
+ 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)"),
162314
+ 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)")
162315
+ }).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."),
162310
162316
  git_commit_indexing: exports_external.object({
162311
- enabled: exports_external.boolean().default(false),
162312
- since_days: exports_external.number().min(7).max(3650).default(365),
162313
- max_commits: exports_external.number().min(100).max(20000).default(2000)
162314
- }).default({ enabled: false, since_days: 365, max_commits: 2000 })
162317
+ 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."),
162318
+ since_days: exports_external.number().min(7).max(3650).default(365).describe("Days of HEAD history to index (min: 7, max: 3650, default: 365)"),
162319
+ 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)")
162320
+ }).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.")
162315
162321
  }).default({
162316
162322
  enabled: true,
162317
162323
  injection_budget_tokens: 4000,
@@ -162319,8 +162325,8 @@ var init_magic_context = __esm(() => {
162319
162325
  retrieval_count_promotion_threshold: 3,
162320
162326
  auto_search: { enabled: true, score_threshold: 0.6, min_prompt_chars: 20 },
162321
162327
  git_commit_indexing: { enabled: false, since_days: 365, max_commits: 2000 }
162322
- }),
162323
- sidekick: SidekickConfigSchema
162328
+ }).describe("Cross-session memory configuration"),
162329
+ sidekick: SidekickConfigSchema.describe("Optional sidekick agent configuration for session-start memory retrieval")
162324
162330
  }).transform((data) => {
162325
162331
  return {
162326
162332
  ...data,
@@ -162496,10 +162502,19 @@ function parsePluginConfig(rawConfig, recoveredTopLevelKeys = []) {
162496
162502
  const defaults = MagicContextConfigSchema.parse({});
162497
162503
  const warnings = [];
162498
162504
  const errorPaths = new Set;
162505
+ const customMessagesByKey = new Map;
162506
+ const GENERIC_ZOD_PREFIXES = ["Too big", "Too small", "Invalid input", "Invalid", "Expected"];
162499
162507
  for (const issue2 of parsed.error.issues) {
162500
162508
  const topKey = issue2.path[0];
162501
162509
  if (topKey !== undefined) {
162502
- errorPaths.add(String(topKey));
162510
+ const key = String(topKey);
162511
+ errorPaths.add(key);
162512
+ const msg = issue2.message;
162513
+ if (msg && !GENERIC_ZOD_PREFIXES.some((p2) => msg.startsWith(p2))) {
162514
+ if (!customMessagesByKey.has(key)) {
162515
+ customMessagesByKey.set(key, msg);
162516
+ }
162517
+ }
162503
162518
  }
162504
162519
  }
162505
162520
  const patched = { ...rawConfig };
@@ -162512,7 +162527,8 @@ function parsePluginConfig(rawConfig, recoveredTopLevelKeys = []) {
162512
162527
  } else {
162513
162528
  delete patched[key];
162514
162529
  const defaultVal = defaults[key];
162515
- warnings.push(`"${key}": invalid value (${redactConfigValue(rawConfig[key])}), using default ${JSON.stringify(defaultVal)}.`);
162530
+ const reason = customMessagesByKey.get(key);
162531
+ warnings.push(`"${key}": invalid value (${redactConfigValue(rawConfig[key])}), using default ${JSON.stringify(defaultVal)}.${reason ? ` ${reason}` : ""}`);
162516
162532
  }
162517
162533
  }
162518
162534
  const retryMigrated = migrateLegacyExperimental(patched, preMigrationWarnings);
@@ -162671,7 +162687,14 @@ async function probeEmbeddingEndpoint(options) {
162671
162687
  if (apiKey) {
162672
162688
  headers.authorization = `Bearer ${apiKey}`;
162673
162689
  }
162674
- const body = JSON.stringify({ model: options.model, input: "magic-context probe" });
162690
+ const inputType = options.inputType?.trim();
162691
+ const truncateMode = options.truncate?.trim();
162692
+ const body = JSON.stringify({
162693
+ model: options.model,
162694
+ input: "magic-context probe",
162695
+ ...inputType ? { input_type: inputType } : {},
162696
+ ...truncateMode ? { truncate: truncateMode } : {}
162697
+ });
162675
162698
  let response;
162676
162699
  try {
162677
162700
  response = await fetchImpl(url2, {
@@ -164016,6 +164039,8 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
164016
164039
  const endpoint = typeof embedding?.endpoint === "string" ? embedding.endpoint.trim() : "";
164017
164040
  const model = typeof embedding?.model === "string" ? embedding.model.trim() : "";
164018
164041
  const apiKey = typeof embedding?.api_key === "string" ? embedding.api_key : undefined;
164042
+ const inputType = typeof embedding?.input_type === "string" ? embedding.input_type.trim() : undefined;
164043
+ const truncateMode = typeof embedding?.truncate === "string" ? embedding.truncate.trim() : undefined;
164019
164044
  let localIssues = 0;
164020
164045
  if (!endpoint) {
164021
164046
  log.error("Embedding provider is openai-compatible but 'endpoint' is missing");
@@ -164047,6 +164072,8 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
164047
164072
  endpoint,
164048
164073
  model,
164049
164074
  apiKey,
164075
+ ...inputType ? { inputType } : {},
164076
+ ...truncateMode ? { truncate: truncateMode } : {},
164050
164077
  timeoutMs: 1e4
164051
164078
  });
164052
164079
  } catch (error51) {
@@ -165581,6 +165608,8 @@ async function runHealthChecks(options) {
165581
165608
  const endpoint = typeof mergedEmbedding.endpoint === "string" ? mergedEmbedding.endpoint.trim() : "";
165582
165609
  const model = typeof mergedEmbedding.model === "string" ? mergedEmbedding.model.trim() : "";
165583
165610
  const apiKey = typeof mergedEmbedding.api_key === "string" ? mergedEmbedding.api_key : undefined;
165611
+ const inputType = typeof mergedEmbedding.input_type === "string" ? mergedEmbedding.input_type.trim() : undefined;
165612
+ const truncateMode = typeof mergedEmbedding.truncate === "string" ? mergedEmbedding.truncate.trim() : undefined;
165584
165613
  if (!endpoint || !model) {
165585
165614
  add(results, "fail", "Embedding provider is openai-compatible but endpoint/model is missing");
165586
165615
  } else {
@@ -165589,6 +165618,8 @@ async function runHealthChecks(options) {
165589
165618
  endpoint,
165590
165619
  model,
165591
165620
  apiKey,
165621
+ ...inputType ? { inputType } : {},
165622
+ ...truncateMode ? { truncate: truncateMode } : {},
165592
165623
  timeoutMs: 1e4
165593
165624
  });
165594
165625
  const classified = classifyEmbeddingOutcome(outcome);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/magic-context",
3
- "version": "0.22.0",
3
+ "version": "0.22.1",
4
4
  "description": "Unified CLI for Magic Context — setup, doctor, and migration across OpenCode and Pi",
5
5
  "keywords": [
6
6
  "opencode",