@cortexkit/magic-context 0.22.0 → 0.22.2
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 +162 -88
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -145495,6 +145495,17 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
145495
145495
|
updated_at INTEGER NOT NULL DEFAULT 0
|
|
145496
145496
|
);
|
|
145497
145497
|
|
|
145498
|
+
CREATE TABLE IF NOT EXISTS git_sweep_coordinator (
|
|
145499
|
+
project_path TEXT PRIMARY KEY,
|
|
145500
|
+
lease_holder TEXT,
|
|
145501
|
+
lease_expires_at INTEGER,
|
|
145502
|
+
last_swept_at INTEGER
|
|
145503
|
+
);
|
|
145504
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_lease_expires
|
|
145505
|
+
ON git_sweep_coordinator(lease_expires_at);
|
|
145506
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_last_swept
|
|
145507
|
+
ON git_sweep_coordinator(last_swept_at);
|
|
145508
|
+
|
|
145498
145509
|
CREATE TABLE IF NOT EXISTS m0_mutation_log (
|
|
145499
145510
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
145500
145511
|
session_id TEXT NOT NULL,
|
|
@@ -146030,7 +146041,7 @@ function closeDatabase() {
|
|
|
146030
146041
|
}
|
|
146031
146042
|
}
|
|
146032
146043
|
}
|
|
146033
|
-
var databases, persistenceByDatabase, persistenceErrorByDatabase, lastSchemaFenceRejection = null, LATEST_SUPPORTED_VERSION =
|
|
146044
|
+
var databases, persistenceByDatabase, persistenceErrorByDatabase, lastSchemaFenceRejection = null, LATEST_SUPPORTED_VERSION = 29, sqlitePragmaConfig;
|
|
146034
146045
|
var init_storage_db = __esm(async () => {
|
|
146035
146046
|
init_data_path();
|
|
146036
146047
|
init_logger();
|
|
@@ -146821,6 +146832,38 @@ var init_migrations = __esm(async () => {
|
|
|
146821
146832
|
ON tags(session_id, entry_fingerprint)
|
|
146822
146833
|
WHERE type='message' AND entry_fingerprint IS NOT NULL`);
|
|
146823
146834
|
}
|
|
146835
|
+
},
|
|
146836
|
+
{
|
|
146837
|
+
version: 28,
|
|
146838
|
+
description: "Add git commit sweep coordinator lease/cooldown table",
|
|
146839
|
+
up: (db) => {
|
|
146840
|
+
db.exec(`
|
|
146841
|
+
CREATE TABLE IF NOT EXISTS git_sweep_coordinator (
|
|
146842
|
+
project_path TEXT PRIMARY KEY,
|
|
146843
|
+
lease_holder TEXT,
|
|
146844
|
+
lease_expires_at INTEGER,
|
|
146845
|
+
last_swept_at INTEGER
|
|
146846
|
+
);
|
|
146847
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_lease_expires
|
|
146848
|
+
ON git_sweep_coordinator(lease_expires_at);
|
|
146849
|
+
CREATE INDEX IF NOT EXISTS idx_git_sweep_coordinator_last_swept
|
|
146850
|
+
ON git_sweep_coordinator(last_swept_at);
|
|
146851
|
+
`);
|
|
146852
|
+
}
|
|
146853
|
+
},
|
|
146854
|
+
{
|
|
146855
|
+
version: 29,
|
|
146856
|
+
description: "Add anchor_ordinal to notes (traceback to the conversation tail)",
|
|
146857
|
+
up: (db) => {
|
|
146858
|
+
const notesExists = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='notes'").get();
|
|
146859
|
+
if (!notesExists) {
|
|
146860
|
+
return;
|
|
146861
|
+
}
|
|
146862
|
+
const columns = db.prepare("PRAGMA table_info(notes)").all();
|
|
146863
|
+
if (!columns.some((column) => column.name === "anchor_ordinal")) {
|
|
146864
|
+
db.exec("ALTER TABLE notes ADD COLUMN anchor_ordinal INTEGER");
|
|
146865
|
+
}
|
|
146866
|
+
}
|
|
146824
146867
|
}
|
|
146825
146868
|
];
|
|
146826
146869
|
LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -162149,25 +162192,25 @@ var init_agent_overrides = __esm(() => {
|
|
|
162149
162192
|
external_directory: PermissionValueSchema.optional()
|
|
162150
162193
|
}).optional();
|
|
162151
162194
|
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()
|
|
162195
|
+
model: exports_external.string().optional().describe("Primary model ID (e.g. 'claude-sonnet-4-6')"),
|
|
162196
|
+
temperature: exports_external.number().min(0).max(2).optional().describe("Sampling temperature (0-2)"),
|
|
162197
|
+
top_p: exports_external.number().min(0).max(1).optional().describe("Nucleus sampling top_p (0-1)"),
|
|
162198
|
+
prompt: exports_external.string().optional().describe("Additional system prompt text"),
|
|
162199
|
+
tools: exports_external.record(exports_external.string(), exports_external.boolean()).optional().describe("Tool enable/disable overrides"),
|
|
162200
|
+
disable: exports_external.boolean().optional().describe("Disable this agent"),
|
|
162201
|
+
description: exports_external.string().optional().describe("Agent description"),
|
|
162202
|
+
mode: exports_external.enum(["subagent", "primary", "all"]).optional().describe("Agent mode (subagent, primary, or all)"),
|
|
162203
|
+
color: exports_external.string().regex(/^#[0-9A-Fa-f]{6}$/).optional().describe("Hex color for the agent (e.g. '#a1b2c3')"),
|
|
162204
|
+
maxSteps: exports_external.number().optional().describe("Maximum tool-call steps per invocation"),
|
|
162205
|
+
permission: PermissionSchema.describe("Per-tool permission overrides"),
|
|
162206
|
+
maxTokens: exports_external.number().optional().describe("Maximum output tokens"),
|
|
162207
|
+
variant: exports_external.string().optional().describe("OpenCode reasoning variant (e.g. for extended thinking)"),
|
|
162208
|
+
fallback_models: exports_external.union([exports_external.string(), exports_external.array(exports_external.string())]).optional().describe("Fallback model IDs if primary is unavailable")
|
|
162166
162209
|
});
|
|
162167
162210
|
});
|
|
162168
162211
|
|
|
162169
162212
|
// ../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;
|
|
162213
|
+
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
162214
|
var init_magic_context = __esm(() => {
|
|
162172
162215
|
init_zod();
|
|
162173
162216
|
init_agent_overrides();
|
|
@@ -162187,36 +162230,38 @@ var init_magic_context = __esm(() => {
|
|
|
162187
162230
|
];
|
|
162188
162231
|
PiThinkingLevelSchema = exports_external.enum(["off", "minimal", "low", "medium", "high", "xhigh"]).optional();
|
|
162189
162232
|
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),
|
|
162233
|
+
schedule: exports_external.string().default("02:00-06:00").describe("Scheduled window for overnight dreaming (e.g. '02:00-06:00')"),
|
|
162234
|
+
max_runtime_minutes: exports_external.number().min(10).default(120).describe("Maximum runtime per dream session in minutes"),
|
|
162235
|
+
tasks: exports_external.array(DreamingTaskSchema).default(DEFAULT_DREAMER_TASKS).describe("Tasks to run during dreaming, in order"),
|
|
162236
|
+
task_timeout_minutes: exports_external.number().min(5).default(20).describe("Minutes allocated per task before moving to next"),
|
|
162237
|
+
inject_docs: exports_external.boolean().default(true).describe("Inject ARCHITECTURE.md and STRUCTURE.md into system prompt"),
|
|
162195
162238
|
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 }),
|
|
162239
|
+
enabled: exports_external.boolean().default(true).describe("Enable user memory extraction and promotion (default: true)"),
|
|
162240
|
+
promotion_threshold: exports_external.number().min(2).max(20).default(3).describe("Minimum candidate observations before dreamer considers promotion (default: 3)")
|
|
162241
|
+
}).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
162242
|
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
|
|
162243
|
+
enabled: exports_external.boolean().default(false).describe("Enable key file pinning (default: false)"),
|
|
162244
|
+
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)"),
|
|
162245
|
+
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)")
|
|
162246
|
+
}).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."),
|
|
162247
|
+
thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level for dreamer subagent invocations. See historian.thinking_level.")
|
|
162205
162248
|
}));
|
|
162206
162249
|
SidekickConfigSchema = AgentOverrideConfigSchema.extend({
|
|
162207
|
-
timeout_ms: exports_external.number().default(30000),
|
|
162208
|
-
system_prompt: exports_external.string().optional(),
|
|
162209
|
-
thinking_level: PiThinkingLevelSchema
|
|
162250
|
+
timeout_ms: exports_external.number().default(30000).describe("Timeout for sidekick calls in milliseconds"),
|
|
162251
|
+
system_prompt: exports_external.string().optional().describe("Custom system prompt for sidekick"),
|
|
162252
|
+
thinking_level: PiThinkingLevelSchema.describe("Pi only: explicit thinking level for sidekick subagent invocations. See historian.thinking_level.")
|
|
162210
162253
|
}).optional();
|
|
162211
162254
|
HistorianConfigSchema = AgentOverrideConfigSchema.extend({
|
|
162212
|
-
two_pass: exports_external.boolean().default(false),
|
|
162213
|
-
thinking_level: PiThinkingLevelSchema
|
|
162255
|
+
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)"),
|
|
162256
|
+
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
162257
|
}).optional();
|
|
162215
162258
|
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()
|
|
162259
|
+
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."),
|
|
162260
|
+
model: exports_external.string().optional().describe("Embedding model name. Required for openai-compatible, ignored for local."),
|
|
162261
|
+
endpoint: exports_external.string().optional().describe("API endpoint URL. Required when provider is openai-compatible."),
|
|
162262
|
+
api_key: exports_external.string().optional().describe("API key for remote embedding provider (optional)"),
|
|
162263
|
+
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."),
|
|
162264
|
+
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
162265
|
}).superRefine((data, ctx) => {
|
|
162221
162266
|
if (data.provider === "openai-compatible" && !data.endpoint?.trim()) {
|
|
162222
162267
|
ctx.addIssue({
|
|
@@ -162242,76 +162287,80 @@ var init_magic_context = __esm(() => {
|
|
|
162242
162287
|
}
|
|
162243
162288
|
if (data.provider === "openai-compatible") {
|
|
162244
162289
|
const apiKey = data.api_key?.trim();
|
|
162290
|
+
const inputType = data.input_type?.trim();
|
|
162291
|
+
const truncate = data.truncate?.trim();
|
|
162245
162292
|
return {
|
|
162246
162293
|
provider: "openai-compatible",
|
|
162247
162294
|
model: data.model?.trim() ?? "",
|
|
162248
162295
|
endpoint: data.endpoint?.trim() ?? "",
|
|
162249
|
-
...apiKey ? { api_key: apiKey } : {}
|
|
162296
|
+
...apiKey ? { api_key: apiKey } : {},
|
|
162297
|
+
...inputType ? { input_type: inputType } : {},
|
|
162298
|
+
...truncate ? { truncate } : {}
|
|
162250
162299
|
};
|
|
162251
162300
|
}
|
|
162252
162301
|
return { provider: "off" };
|
|
162253
162302
|
});
|
|
162254
162303
|
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),
|
|
162304
|
+
enabled: exports_external.boolean().default(true).describe("Enable magic context (default: true)"),
|
|
162305
|
+
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."),
|
|
162306
|
+
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)"),
|
|
162307
|
+
historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
|
|
162308
|
+
dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
|
|
162309
|
+
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" })'),
|
|
162310
|
+
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
162311
|
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),
|
|
162312
|
+
exports_external.number().min(20).max(80, EXECUTE_THRESHOLD_CAP_MESSAGE),
|
|
162313
|
+
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))
|
|
162314
|
+
]).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
162315
|
execute_threshold_tokens: exports_external.object({
|
|
162267
162316
|
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),
|
|
162317
|
+
}).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."),
|
|
162318
|
+
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)"),
|
|
162319
|
+
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)"),
|
|
162320
|
+
drop_tool_structure: exports_external.boolean().default(true).describe("When true, dropped tool parts are fully removed instead of truncated in place (default: true)"),
|
|
162321
|
+
clear_reasoning_age: exports_external.number().min(10).default(50).describe("Clear reasoning/thinking blocks older than N tags (default: 50)"),
|
|
162322
|
+
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)"),
|
|
162323
|
+
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)"),
|
|
162324
|
+
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
162325
|
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 }),
|
|
162326
|
+
enabled: exports_external.boolean().default(true).describe("Enable commit-cluster based historian triggering (default: true)"),
|
|
162327
|
+
min_clusters: exports_external.number().min(1).default(3).describe("Minimum commit clusters required to trigger historian (min: 1, default: 3)")
|
|
162328
|
+
}).default({ enabled: true, min_clusters: 3 }).describe("Commit-cluster trigger: fire historian when enough commit clusters accumulate in the unsummarized tail"),
|
|
162280
162329
|
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 -->"])
|
|
162330
|
+
enabled: exports_external.boolean().default(true).describe("When false, NO injection happens for ANY agent — global escape hatch. (default: true)"),
|
|
162331
|
+
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
162332
|
}).default({
|
|
162284
162333
|
enabled: true,
|
|
162285
162334
|
skip_signatures: ["<!-- magic-context: skip -->"]
|
|
162286
|
-
}),
|
|
162335
|
+
}).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
162336
|
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 }),
|
|
162337
|
+
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)"),
|
|
162338
|
+
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)")
|
|
162339
|
+
}).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
162340
|
embedding: EmbeddingConfigSchema.default({
|
|
162292
162341
|
provider: "local",
|
|
162293
162342
|
model: DEFAULT_LOCAL_EMBEDDING_MODEL
|
|
162294
|
-
}),
|
|
162295
|
-
temporal_awareness: exports_external.boolean().default(true),
|
|
162343
|
+
}).describe("Embedding provider configuration"),
|
|
162344
|
+
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
162345
|
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 }),
|
|
162346
|
+
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%)."),
|
|
162347
|
+
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.")
|
|
162348
|
+
}).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
162349
|
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),
|
|
162350
|
+
enabled: exports_external.boolean().default(true).describe("Enable cross-session memory (default: true)"),
|
|
162351
|
+
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)"),
|
|
162352
|
+
auto_promote: exports_external.boolean().default(true).describe("Automatically promote eligible session facts into memory (default: true)"),
|
|
162353
|
+
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
162354
|
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 }),
|
|
162355
|
+
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."),
|
|
162356
|
+
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)"),
|
|
162357
|
+
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)")
|
|
162358
|
+
}).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
162359
|
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 })
|
|
162360
|
+
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."),
|
|
162361
|
+
since_days: exports_external.number().min(7).max(3650).default(365).describe("Days of HEAD history to index (min: 7, max: 3650, default: 365)"),
|
|
162362
|
+
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)")
|
|
162363
|
+
}).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
162364
|
}).default({
|
|
162316
162365
|
enabled: true,
|
|
162317
162366
|
injection_budget_tokens: 4000,
|
|
@@ -162319,8 +162368,8 @@ var init_magic_context = __esm(() => {
|
|
|
162319
162368
|
retrieval_count_promotion_threshold: 3,
|
|
162320
162369
|
auto_search: { enabled: true, score_threshold: 0.6, min_prompt_chars: 20 },
|
|
162321
162370
|
git_commit_indexing: { enabled: false, since_days: 365, max_commits: 2000 }
|
|
162322
|
-
}),
|
|
162323
|
-
sidekick: SidekickConfigSchema
|
|
162371
|
+
}).describe("Cross-session memory configuration"),
|
|
162372
|
+
sidekick: SidekickConfigSchema.describe("Optional sidekick agent configuration for session-start memory retrieval")
|
|
162324
162373
|
}).transform((data) => {
|
|
162325
162374
|
return {
|
|
162326
162375
|
...data,
|
|
@@ -162496,10 +162545,19 @@ function parsePluginConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
|
162496
162545
|
const defaults = MagicContextConfigSchema.parse({});
|
|
162497
162546
|
const warnings = [];
|
|
162498
162547
|
const errorPaths = new Set;
|
|
162548
|
+
const customMessagesByKey = new Map;
|
|
162549
|
+
const GENERIC_ZOD_PREFIXES = ["Too big", "Too small", "Invalid input", "Invalid", "Expected"];
|
|
162499
162550
|
for (const issue2 of parsed.error.issues) {
|
|
162500
162551
|
const topKey = issue2.path[0];
|
|
162501
162552
|
if (topKey !== undefined) {
|
|
162502
|
-
|
|
162553
|
+
const key = String(topKey);
|
|
162554
|
+
errorPaths.add(key);
|
|
162555
|
+
const msg = issue2.message;
|
|
162556
|
+
if (msg && !GENERIC_ZOD_PREFIXES.some((p2) => msg.startsWith(p2))) {
|
|
162557
|
+
if (!customMessagesByKey.has(key)) {
|
|
162558
|
+
customMessagesByKey.set(key, msg);
|
|
162559
|
+
}
|
|
162560
|
+
}
|
|
162503
162561
|
}
|
|
162504
162562
|
}
|
|
162505
162563
|
const patched = { ...rawConfig };
|
|
@@ -162512,7 +162570,8 @@ function parsePluginConfig(rawConfig, recoveredTopLevelKeys = []) {
|
|
|
162512
162570
|
} else {
|
|
162513
162571
|
delete patched[key];
|
|
162514
162572
|
const defaultVal = defaults[key];
|
|
162515
|
-
|
|
162573
|
+
const reason = customMessagesByKey.get(key);
|
|
162574
|
+
warnings.push(`"${key}": invalid value (${redactConfigValue(rawConfig[key])}), using default ${JSON.stringify(defaultVal)}.${reason ? ` ${reason}` : ""}`);
|
|
162516
162575
|
}
|
|
162517
162576
|
}
|
|
162518
162577
|
const retryMigrated = migrateLegacyExperimental(patched, preMigrationWarnings);
|
|
@@ -162671,7 +162730,14 @@ async function probeEmbeddingEndpoint(options) {
|
|
|
162671
162730
|
if (apiKey) {
|
|
162672
162731
|
headers.authorization = `Bearer ${apiKey}`;
|
|
162673
162732
|
}
|
|
162674
|
-
const
|
|
162733
|
+
const inputType = options.inputType?.trim();
|
|
162734
|
+
const truncateMode = options.truncate?.trim();
|
|
162735
|
+
const body = JSON.stringify({
|
|
162736
|
+
model: options.model,
|
|
162737
|
+
input: "magic-context probe",
|
|
162738
|
+
...inputType ? { input_type: inputType } : {},
|
|
162739
|
+
...truncateMode ? { truncate: truncateMode } : {}
|
|
162740
|
+
});
|
|
162675
162741
|
let response;
|
|
162676
162742
|
try {
|
|
162677
162743
|
response = await fetchImpl(url2, {
|
|
@@ -164016,6 +164082,8 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
|
164016
164082
|
const endpoint = typeof embedding?.endpoint === "string" ? embedding.endpoint.trim() : "";
|
|
164017
164083
|
const model = typeof embedding?.model === "string" ? embedding.model.trim() : "";
|
|
164018
164084
|
const apiKey = typeof embedding?.api_key === "string" ? embedding.api_key : undefined;
|
|
164085
|
+
const inputType = typeof embedding?.input_type === "string" ? embedding.input_type.trim() : undefined;
|
|
164086
|
+
const truncateMode = typeof embedding?.truncate === "string" ? embedding.truncate.trim() : undefined;
|
|
164019
164087
|
let localIssues = 0;
|
|
164020
164088
|
if (!endpoint) {
|
|
164021
164089
|
log.error("Embedding provider is openai-compatible but 'endpoint' is missing");
|
|
@@ -164047,6 +164115,8 @@ async function checkEmbeddingConfig(magicContextConfigPath) {
|
|
|
164047
164115
|
endpoint,
|
|
164048
164116
|
model,
|
|
164049
164117
|
apiKey,
|
|
164118
|
+
...inputType ? { inputType } : {},
|
|
164119
|
+
...truncateMode ? { truncate: truncateMode } : {},
|
|
164050
164120
|
timeoutMs: 1e4
|
|
164051
164121
|
});
|
|
164052
164122
|
} catch (error51) {
|
|
@@ -165581,6 +165651,8 @@ async function runHealthChecks(options) {
|
|
|
165581
165651
|
const endpoint = typeof mergedEmbedding.endpoint === "string" ? mergedEmbedding.endpoint.trim() : "";
|
|
165582
165652
|
const model = typeof mergedEmbedding.model === "string" ? mergedEmbedding.model.trim() : "";
|
|
165583
165653
|
const apiKey = typeof mergedEmbedding.api_key === "string" ? mergedEmbedding.api_key : undefined;
|
|
165654
|
+
const inputType = typeof mergedEmbedding.input_type === "string" ? mergedEmbedding.input_type.trim() : undefined;
|
|
165655
|
+
const truncateMode = typeof mergedEmbedding.truncate === "string" ? mergedEmbedding.truncate.trim() : undefined;
|
|
165584
165656
|
if (!endpoint || !model) {
|
|
165585
165657
|
add(results, "fail", "Embedding provider is openai-compatible but endpoint/model is missing");
|
|
165586
165658
|
} else {
|
|
@@ -165589,6 +165661,8 @@ async function runHealthChecks(options) {
|
|
|
165589
165661
|
endpoint,
|
|
165590
165662
|
model,
|
|
165591
165663
|
apiKey,
|
|
165664
|
+
...inputType ? { inputType } : {},
|
|
165665
|
+
...truncateMode ? { truncate: truncateMode } : {},
|
|
165592
165666
|
timeoutMs: 1e4
|
|
165593
165667
|
});
|
|
165594
165668
|
const classified = classifyEmbeddingOutcome(outcome);
|