@cortexkit/opencode-magic-context 0.27.2 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -7
- package/dist/agents/language-directive.d.ts +27 -0
- package/dist/agents/language-directive.d.ts.map +1 -0
- package/dist/agents/magic-context-prompt.d.ts +1 -1
- package/dist/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +1 -0
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +4 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/refresh-primers.d.ts +1 -0
- package/dist/features/magic-context/dreamer/refresh-primers.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-config.d.ts +1 -1
- package/dist/features/magic-context/dreamer/task-config.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts +1 -0
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts +1 -0
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts +1 -0
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/memory/memory-migration.d.ts +1 -0
- package/dist/features/magic-context/memory/memory-migration.d.ts.map +1 -1
- package/dist/features/magic-context/sidekick/agent.d.ts +1 -0
- package/dist/features/magic-context/sidekick/agent.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +0 -5
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts +1 -0
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts +1 -0
- package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +1 -0
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +1 -0
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +1 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +13 -3
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +1 -0
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts +1 -0
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +2 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +235 -57
- package/dist/plugin/conflict-warning-hook.d.ts.map +1 -1
- package/dist/plugin/dream-timer.d.ts +1 -0
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/shared/announcement.d.ts +1 -1
- package/dist/shared/announcement.d.ts.map +1 -1
- package/dist/shared/tui-preferences.d.ts +1 -1
- package/dist/tui/badge-contrast.d.ts +31 -0
- package/dist/tui/badge-contrast.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/shared/announcement.ts +3 -6
- package/src/shared/tui-preferences.ts +2 -2
- package/src/tui/badge-contrast.test.ts +45 -0
- package/src/tui/badge-contrast.ts +46 -0
- package/src/tui/slots/sidebar-content.tsx +2 -1
package/dist/index.js
CHANGED
|
@@ -169,6 +169,98 @@ var init_logger = __esm(() => {
|
|
|
169
169
|
}
|
|
170
170
|
});
|
|
171
171
|
|
|
172
|
+
// src/agents/language-directive.ts
|
|
173
|
+
function resolveLanguageName(language) {
|
|
174
|
+
const code = typeof language === "string" ? language.trim().toLowerCase() : "";
|
|
175
|
+
if (!/^[a-z]{2}$/.test(code))
|
|
176
|
+
return "";
|
|
177
|
+
let english;
|
|
178
|
+
try {
|
|
179
|
+
english = ENGLISH_LANGUAGE_NAMES.of(code) ?? undefined;
|
|
180
|
+
} catch {
|
|
181
|
+
return "";
|
|
182
|
+
}
|
|
183
|
+
if (!english)
|
|
184
|
+
return "";
|
|
185
|
+
let endonym;
|
|
186
|
+
try {
|
|
187
|
+
endonym = new Intl.DisplayNames([code], { type: "language", fallback: "none" }).of(code) ?? undefined;
|
|
188
|
+
} catch {
|
|
189
|
+
endonym = undefined;
|
|
190
|
+
}
|
|
191
|
+
return endonym && endonym !== english ? `${english} (${endonym})` : english;
|
|
192
|
+
}
|
|
193
|
+
function isValidLanguageCode(language) {
|
|
194
|
+
return resolveLanguageName(language) !== "";
|
|
195
|
+
}
|
|
196
|
+
function buildContentLanguageDirective(language, options = {}) {
|
|
197
|
+
const target = resolveLanguageName(language);
|
|
198
|
+
if (!target)
|
|
199
|
+
return "";
|
|
200
|
+
const lines = [
|
|
201
|
+
"## Output language",
|
|
202
|
+
"",
|
|
203
|
+
`Write human-readable prose you author in: ${target}.`,
|
|
204
|
+
"",
|
|
205
|
+
"Do not translate or rename structural tokens. Copy required output schemas exactly:",
|
|
206
|
+
"- XML tag names, XML attribute names, JSON keys, tool names, tool-call argument keys, enum values, booleans/null, and required sentinel strings stay in English exactly as shown.",
|
|
207
|
+
"- Keep code identifiers, file paths, commands, config keys, CLI flags, URLs, commit hashes, model/provider IDs, stack traces, diagnostics, and transcript role markers such as U:, A:, and TC: verbatim.",
|
|
208
|
+
"- Localize only free-text prose values/content: summaries, memory text, explanations, titles, observations, and answers — unless the prompt says to preserve original wording.",
|
|
209
|
+
"",
|
|
210
|
+
"These literal values must remain English when used:",
|
|
211
|
+
"PROJECT_RULES, ARCHITECTURE, CONSTRAINTS, CONFIG_VALUES, NAMING;",
|
|
212
|
+
"causal_incident, trajectory_correction;",
|
|
213
|
+
"feature, design, docs, release, investigation, bug, refactor, infra;",
|
|
214
|
+
"memory, observation; true, false; No relevant memories found.",
|
|
215
|
+
"",
|
|
216
|
+
"Preserve the required output shape. Do not add commentary outside the requested XML/JSON/tool output."
|
|
217
|
+
];
|
|
218
|
+
if (options.preserveUserQuotes) {
|
|
219
|
+
lines.push("", `Preserve U: lines and directly quoted user text in their original source language; write the surrounding summary prose in ${target}.`);
|
|
220
|
+
}
|
|
221
|
+
if (options.retrospective) {
|
|
222
|
+
lines.push("", `Write the lesson text in ${target}; paraphrase source text and never quote the user.`);
|
|
223
|
+
}
|
|
224
|
+
return lines.join(`
|
|
225
|
+
`);
|
|
226
|
+
}
|
|
227
|
+
function withContentLanguageDirective(systemPrompt, language, options = {}) {
|
|
228
|
+
const directive = buildContentLanguageDirective(language, options);
|
|
229
|
+
return directive ? `${systemPrompt}
|
|
230
|
+
|
|
231
|
+
${directive}` : systemPrompt;
|
|
232
|
+
}
|
|
233
|
+
function buildMigrationLanguageDirective(language) {
|
|
234
|
+
const target = resolveLanguageName(language);
|
|
235
|
+
if (!target)
|
|
236
|
+
return "";
|
|
237
|
+
return [
|
|
238
|
+
"## Output language",
|
|
239
|
+
"",
|
|
240
|
+
"Preserve each migrated memory's existing language — do NOT translate a memory just because an output language is set. When merging memories written in different languages, use the language of the clearest / source-majority memory; otherwise keep the source phrasing. Only the category re-mapping changes."
|
|
241
|
+
].join(`
|
|
242
|
+
`);
|
|
243
|
+
}
|
|
244
|
+
function withMigrationLanguageDirective(systemPrompt, language) {
|
|
245
|
+
const directive = buildMigrationLanguageDirective(language);
|
|
246
|
+
return directive ? `${systemPrompt}
|
|
247
|
+
|
|
248
|
+
${directive}` : systemPrompt;
|
|
249
|
+
}
|
|
250
|
+
function buildPrimaryLanguageDirective(language) {
|
|
251
|
+
const target = resolveLanguageName(language);
|
|
252
|
+
if (!target)
|
|
253
|
+
return "";
|
|
254
|
+
return `Use ${target} for your natural-language replies to the user unless the user explicitly asks for another language. Keep code, identifiers, file paths, commands, logs, and quoted text verbatim.`;
|
|
255
|
+
}
|
|
256
|
+
var ENGLISH_LANGUAGE_NAMES;
|
|
257
|
+
var init_language_directive = __esm(() => {
|
|
258
|
+
ENGLISH_LANGUAGE_NAMES = new Intl.DisplayNames(["en"], {
|
|
259
|
+
type: "language",
|
|
260
|
+
fallback: "none"
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
|
|
172
264
|
// src/shared/jsonc-parser.ts
|
|
173
265
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
174
266
|
function stripJsonComments(content) {
|
|
@@ -15155,6 +15247,7 @@ function defaultTaskConfig(task) {
|
|
|
15155
15247
|
var 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", DreamingTaskSchema, PiThinkingLevelSchema, CronScheduleSchema, DreamTaskBaseConfigSchema, PromotionThresholdSchema, PrimerPromotionThresholdSchema, DreamTaskConfigSchema, ReviewUserMemoriesTaskConfigSchema, PromotePrimersTaskConfigSchema, DEFAULT_TASK_SCHEDULES, DreamTasksSchema, DreamerConfigSchema, SidekickConfigSchema, HistorianConfigSchema, BaseEmbeddingConfigSchema, EmbeddingConfigSchema, MagicContextConfigSchema;
|
|
15156
15248
|
var init_magic_context = __esm(() => {
|
|
15157
15249
|
init_zod();
|
|
15250
|
+
init_language_directive();
|
|
15158
15251
|
init_cron();
|
|
15159
15252
|
init_task_registry();
|
|
15160
15253
|
init_agent_overrides();
|
|
@@ -15276,6 +15369,7 @@ var init_magic_context = __esm(() => {
|
|
|
15276
15369
|
MagicContextConfigSchema = exports_external.object({
|
|
15277
15370
|
enabled: exports_external.boolean().default(true).describe("Enable magic context (default: true)"),
|
|
15278
15371
|
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."),
|
|
15372
|
+
language: exports_external.string().trim().toLowerCase().refine((s) => isValidLanguageCode(s), 'language must be a 2-letter ISO 639-1 code (e.g. "tr", "es", "de")').optional().describe("Output language for Magic Context's generated content and guidance, as a " + '2-letter ISO 639-1 code (e.g. "tr", "es", "de", "ja", "pt"). When set, the ' + "historian, dreamer, sidekick, and the agent-guidance block instruct the model to " + "write its PROSE in this language while keeping all structural tokens (XML tags, " + "the five memory category names, code identifiers, file paths) in English. " + "USER-LEVEL ONLY (ignored in project config for security). Unset = today's " + "behavior (model mirrors the conversation; English scaffolding). Changing it " + "triggers one cache re-materialization; existing compartments/memories keep their " + "original language until naturally rewritten."),
|
|
15279
15373
|
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)"),
|
|
15280
15374
|
historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
|
|
15281
15375
|
dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
|
|
@@ -151003,7 +151097,7 @@ function enforceSchemaFence(db, dbPath, latestSupportedVersion) {
|
|
|
151003
151097
|
return true;
|
|
151004
151098
|
}
|
|
151005
151099
|
lastSchemaFenceRejection = { persistedVersion, supportedVersion: latestSupportedVersion };
|
|
151006
|
-
log(`[magic-context] storage fatal: refusing to open ${dbPath}; database schema v${persistedVersion} is newer than this binary supports (max v${latestSupportedVersion}).
|
|
151100
|
+
log(`[magic-context] storage fatal: refusing to open ${dbPath}; database schema v${persistedVersion} is newer than this binary supports (max v${latestSupportedVersion}). A pinned or stale plugin is likely sharing this database with a newer instance; update or unpin Magic Context with 'npx @cortexkit/magic-context@latest doctor --force', then restart.`);
|
|
151007
151101
|
return false;
|
|
151008
151102
|
}
|
|
151009
151103
|
function setSqlitePragmaConfig(config2) {
|
|
@@ -155736,10 +155830,18 @@ function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, li
|
|
|
155736
155830
|
WHERE session_id = ? AND status = 'active'
|
|
155737
155831
|
ORDER BY tag_number DESC LIMIT 1 OFFSET ?
|
|
155738
155832
|
)` : "";
|
|
155739
|
-
const
|
|
155833
|
+
const excludeStateTools = RECLAIM_HINT_EXCLUDED_LIST ? `AND (tool_name IS NULL OR tool_name NOT IN (${RECLAIM_HINT_EXCLUDED_LIST}))` : "";
|
|
155834
|
+
const valueFloor = `AND (
|
|
155835
|
+
(token_count IS NULL AND input_token_count IS NULL)
|
|
155836
|
+
OR (COALESCE(token_count, 0) + COALESCE(input_token_count, 0)) >= ?
|
|
155837
|
+
)`;
|
|
155838
|
+
const params = protectedTags > 0 ? [sessionId, RECLAIM_HINT_MIN_TOKENS, sessionId, protectedTags - 1, boundedLimit] : [sessionId, RECLAIM_HINT_MIN_TOKENS, boundedLimit];
|
|
155740
155839
|
const rows = db.prepare(`SELECT tag_number, tool_name
|
|
155741
155840
|
FROM tags
|
|
155742
|
-
WHERE session_id = ? AND status = 'active' AND type = 'tool'
|
|
155841
|
+
WHERE session_id = ? AND status = 'active' AND type = 'tool'
|
|
155842
|
+
${excludeStateTools}
|
|
155843
|
+
${valueFloor}
|
|
155844
|
+
${whereProtected}
|
|
155743
155845
|
ORDER BY tag_number ASC, id ASC
|
|
155744
155846
|
LIMIT ?`).all(...params);
|
|
155745
155847
|
return rows.filter((row) => typeof row.tag_number === "number").map((row) => ({
|
|
@@ -156129,7 +156231,7 @@ function deleteToolTagsByOwner(db, sessionId, ownerMsgId) {
|
|
|
156129
156231
|
const result = getDeleteToolTagsByOwnerStatement(db).run(sessionId, ownerMsgId);
|
|
156130
156232
|
return result.changes ?? 0;
|
|
156131
156233
|
}
|
|
156132
|
-
var insertTagStatements, updateTagStatusStatements, updateTagDropModeStatements, updateTagMessageIdStatements, getTagNumbersByMessageIdStatements, deleteTagsByMessageIdStatements, getMaxTagNumberBySessionStatements, getTagNumberByMessageIdStatements, updateTagByteSizeStatements, updateTagInputByteSizeStatements, CONTENT_ID_SUFFIX, updateTagTokenCountStatements, updateTagInputTokenCountStatements, getOwnerScopedToolTagNumbersStatements, getMinMessageTagNumberForRawIdStatements, TAGGER_FLOOR_SCAN_MESSAGES = 8, TAGGER_FLOOR_MAX_PROBES = 64, TAGGER_FLOOR_SAFETY_MARGIN = 256, TAGGER_FLOOR_PER_SKIP_MARGIN = 64, TAG_SELECT_COLUMNS = "id, message_id, type, status, drop_mode, tool_name, input_byte_size, byte_size, reasoning_byte_size, session_id, tag_number, caveman_depth, tool_owner_message_id", getActiveTagsBySessionStatements, getMaxDroppedTagNumberStatements, getToolTagNumberByOwnerStatements, getNullOwnerToolTagStatements, adoptNullOwnerToolTagStatements, deleteToolTagsByOwnerStatements;
|
|
156234
|
+
var insertTagStatements, updateTagStatusStatements, updateTagDropModeStatements, updateTagMessageIdStatements, getTagNumbersByMessageIdStatements, deleteTagsByMessageIdStatements, getMaxTagNumberBySessionStatements, getTagNumberByMessageIdStatements, updateTagByteSizeStatements, updateTagInputByteSizeStatements, CONTENT_ID_SUFFIX, RECLAIM_HINT_EXCLUDED_TOOLS, RECLAIM_HINT_MIN_TOKENS = 250, RECLAIM_HINT_EXCLUDED_LIST, updateTagTokenCountStatements, updateTagInputTokenCountStatements, getOwnerScopedToolTagNumbersStatements, getMinMessageTagNumberForRawIdStatements, TAGGER_FLOOR_SCAN_MESSAGES = 8, TAGGER_FLOOR_MAX_PROBES = 64, TAGGER_FLOOR_SAFETY_MARGIN = 256, TAGGER_FLOOR_PER_SKIP_MARGIN = 64, TAG_SELECT_COLUMNS = "id, message_id, type, status, drop_mode, tool_name, input_byte_size, byte_size, reasoning_byte_size, session_id, tag_number, caveman_depth, tool_owner_message_id", getActiveTagsBySessionStatements, getMaxDroppedTagNumberStatements, getToolTagNumberByOwnerStatements, getNullOwnerToolTagStatements, adoptNullOwnerToolTagStatements, deleteToolTagsByOwnerStatements;
|
|
156133
156235
|
var init_storage_tags = __esm(() => {
|
|
156134
156236
|
insertTagStatements = new WeakMap;
|
|
156135
156237
|
updateTagStatusStatements = new WeakMap;
|
|
@@ -156142,6 +156244,8 @@ var init_storage_tags = __esm(() => {
|
|
|
156142
156244
|
updateTagByteSizeStatements = new WeakMap;
|
|
156143
156245
|
updateTagInputByteSizeStatements = new WeakMap;
|
|
156144
156246
|
CONTENT_ID_SUFFIX = /:(?:p|file)\d+$/;
|
|
156247
|
+
RECLAIM_HINT_EXCLUDED_TOOLS = ["todowrite"];
|
|
156248
|
+
RECLAIM_HINT_EXCLUDED_LIST = RECLAIM_HINT_EXCLUDED_TOOLS.map((name2) => `'${name2.replace(/'/g, "''")}'`).join(", ");
|
|
156145
156249
|
updateTagTokenCountStatements = new WeakMap;
|
|
156146
156250
|
updateTagInputTokenCountStatements = new WeakMap;
|
|
156147
156251
|
getOwnerScopedToolTagNumbersStatements = new WeakMap;
|
|
@@ -165579,8 +165683,13 @@ async function sendSchemaFenceWarning(client, directory, detail) {
|
|
|
165579
165683
|
`newer build (OpenCode and Pi share one database). This build only supports`,
|
|
165580
165684
|
`up to v${detail.supportedVersion}, so it has fail-closed to avoid corrupting the cache.`,
|
|
165581
165685
|
"",
|
|
165582
|
-
"
|
|
165583
|
-
"
|
|
165686
|
+
"This usually means a pinned or stale plugin is sharing the database with a",
|
|
165687
|
+
"newer instance. Update or unpin Magic Context on this harness (or update",
|
|
165688
|
+
"OpenCode/Pi) to the latest version, then restart. The fastest fix is:",
|
|
165689
|
+
"",
|
|
165690
|
+
" npx @cortexkit/magic-context@latest doctor --force",
|
|
165691
|
+
"",
|
|
165692
|
+
"Your data is safe; nothing is disabled permanently."
|
|
165584
165693
|
].join(`
|
|
165585
165694
|
`);
|
|
165586
165695
|
try {
|
|
@@ -165850,7 +165959,7 @@ __export(exports_task_config, {
|
|
|
165850
165959
|
dreamTaskScheduled: () => dreamTaskScheduled,
|
|
165851
165960
|
buildDreamTaskRuntimeConfigs: () => buildDreamTaskRuntimeConfigs
|
|
165852
165961
|
});
|
|
165853
|
-
function buildDreamTaskRuntimeConfigs(dreamer) {
|
|
165962
|
+
function buildDreamTaskRuntimeConfigs(dreamer, language) {
|
|
165854
165963
|
const tasks = dreamer.tasks ?? {};
|
|
165855
165964
|
return CANONICAL_DREAM_TASKS.map((task) => {
|
|
165856
165965
|
const t = tasks[task] ?? {
|
|
@@ -165866,6 +165975,7 @@ function buildDreamTaskRuntimeConfigs(dreamer) {
|
|
|
165866
165975
|
model,
|
|
165867
165976
|
fallbackModels,
|
|
165868
165977
|
thinkingLevel,
|
|
165978
|
+
language,
|
|
165869
165979
|
timeoutMinutes: t.timeout_minutes ?? 20,
|
|
165870
165980
|
promotionThreshold: t.promotion_threshold
|
|
165871
165981
|
};
|
|
@@ -177218,8 +177328,8 @@ function buildHistorianFailureNotice(failureCount, lastError) {
|
|
|
177218
177328
|
].join(`
|
|
177219
177329
|
`);
|
|
177220
177330
|
}
|
|
177221
|
-
function buildHistorianRepairPrompt(originalPrompt, previousOutput, validationError) {
|
|
177222
|
-
|
|
177331
|
+
function buildHistorianRepairPrompt(originalPrompt, previousOutput, validationError, language) {
|
|
177332
|
+
const prompt = [
|
|
177223
177333
|
originalPrompt,
|
|
177224
177334
|
"",
|
|
177225
177335
|
"Your previous XML response was invalid and cannot be persisted.",
|
|
@@ -177232,6 +177342,7 @@ function buildHistorianRepairPrompt(originalPrompt, previousOutput, validationEr
|
|
|
177232
177342
|
previousOutput
|
|
177233
177343
|
].join(`
|
|
177234
177344
|
`);
|
|
177345
|
+
return withContentLanguageDirective(prompt, language, { preserveUserQuotes: true });
|
|
177235
177346
|
}
|
|
177236
177347
|
function validateStoredCompartments(compartments) {
|
|
177237
177348
|
if (compartments.length === 0) {
|
|
@@ -177308,6 +177419,7 @@ function getReducedRecompTokenBudget(currentBudget) {
|
|
|
177308
177419
|
}
|
|
177309
177420
|
var MIN_RECOMP_CHUNK_TOKEN_BUDGET = 20, HISTORIAN_PERSISTENT_FAILURE_THRESHOLD = 3;
|
|
177310
177421
|
var init_compartment_runner_validation = __esm(async () => {
|
|
177422
|
+
init_language_directive();
|
|
177311
177423
|
init_compartment_parser();
|
|
177312
177424
|
await init_compartment_runner_mapping();
|
|
177313
177425
|
});
|
|
@@ -177345,7 +177457,7 @@ async function runValidatedHistorianPass(args) {
|
|
|
177345
177457
|
return finalResult;
|
|
177346
177458
|
}
|
|
177347
177459
|
await args.callbacks?.onRepairRetry?.(firstValidation.error ?? "invalid compartment output");
|
|
177348
|
-
const repairPrompt = buildHistorianRepairPrompt(args.prompt, firstRun.result, firstValidation.error ?? "invalid compartment output");
|
|
177460
|
+
const repairPrompt = buildHistorianRepairPrompt(args.prompt, firstRun.result, firstValidation.error ?? "invalid compartment output", args.language);
|
|
177349
177461
|
const repairRun = await runHistorianPrompt({
|
|
177350
177462
|
...args,
|
|
177351
177463
|
prompt: repairPrompt,
|
|
@@ -182730,7 +182842,8 @@ ${chunkText}`,
|
|
|
182730
182842
|
timeoutMs: historianTimeoutMs,
|
|
182731
182843
|
fallbackModelId: deps.fallbackModelId,
|
|
182732
182844
|
fallbackModels: deps.fallbackModels,
|
|
182733
|
-
twoPass: deps.historianTwoPass
|
|
182845
|
+
twoPass: deps.historianTwoPass,
|
|
182846
|
+
language: deps.language
|
|
182734
182847
|
});
|
|
182735
182848
|
if (!validatedPass.ok) {
|
|
182736
182849
|
sessionLog(sessionId, `historian failure: source=validation reason="${validatedPass.error}" chunkRange=${chunk.startIndex}-${chunk.endIndex} fallbackModel=${deps.fallbackModelId ?? "<none>"} twoPass=${deps.historianTwoPass ? "true" : "false"}`);
|
|
@@ -183206,6 +183319,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
183206
183319
|
twoPass: deps.historianTwoPass,
|
|
183207
183320
|
subagentKind: "recomp",
|
|
183208
183321
|
agentId: HISTORIAN_RECOMP_AGENT,
|
|
183322
|
+
language: deps.language,
|
|
183209
183323
|
callbacks: {
|
|
183210
183324
|
onRepairRetry: async (error51) => {
|
|
183211
183325
|
emitProgress(`Repair retry (pass ${passCount + 1})…`);
|
|
@@ -183648,6 +183762,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
183648
183762
|
twoPass: deps.historianTwoPass,
|
|
183649
183763
|
subagentKind: "recomp",
|
|
183650
183764
|
agentId: HISTORIAN_RECOMP_AGENT,
|
|
183765
|
+
language: deps.language,
|
|
183651
183766
|
callbacks: {
|
|
183652
183767
|
onRepairRetry: async (error51) => {
|
|
183653
183768
|
await sendIgnoredMessage(client, sessionId, `## Magic Recomp — Partial
|
|
@@ -186008,7 +186123,7 @@ async function runMemoryMigration(deps) {
|
|
|
186008
186123
|
query: { directory },
|
|
186009
186124
|
body: {
|
|
186010
186125
|
agent: HISTORIAN_AGENT,
|
|
186011
|
-
system: MIGRATION_SYSTEM_PROMPT,
|
|
186126
|
+
system: withMigrationLanguageDirective(MIGRATION_SYSTEM_PROMPT, deps.language),
|
|
186012
186127
|
...modelOverride ? { model: modelOverride } : {},
|
|
186013
186128
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
186014
186129
|
}
|
|
@@ -186087,6 +186202,7 @@ async function runMemoryMigration(deps) {
|
|
|
186087
186202
|
}
|
|
186088
186203
|
var V2_CATEGORIES, MIGRATED_BLOCK_RE, USER_OBS_BLOCK_RE, CATEGORY_BLOCK_RE = (cat) => new RegExp(`<${cat}>([\\s\\S]*?)</${cat}>`), MIGRATION_SYSTEM_PROMPT;
|
|
186089
186204
|
var init_memory_migration = __esm(async () => {
|
|
186205
|
+
init_language_directive();
|
|
186090
186206
|
init_shared();
|
|
186091
186207
|
init_assistant_message_extractor();
|
|
186092
186208
|
init_logger();
|
|
@@ -186203,6 +186319,7 @@ function buildRecompDeps(ctx, sessionId) {
|
|
|
186203
186319
|
memoryEnabled: ctx.memoryEnabled,
|
|
186204
186320
|
autoPromote: ctx.autoPromote,
|
|
186205
186321
|
fallbackModels: ctx.fallbackModels,
|
|
186322
|
+
language: ctx.language,
|
|
186206
186323
|
fallbackModelId: ctx.fallbackModelId ?? resolveLiveModelKey(ctx.liveSessionState, sessionId),
|
|
186207
186324
|
historianTwoPass: ctx.historianTwoPass,
|
|
186208
186325
|
ensureProjectRegistered: ctx.ensureProjectRegistered,
|
|
@@ -186334,7 +186451,8 @@ async function runUpgradeMemoryMigration(ctx, sessionId, migrationDirectory) {
|
|
|
186334
186451
|
primaryModelId: ctx.fallbackModelId ?? resolveLiveModelKey(ctx.liveSessionState, sessionId),
|
|
186335
186452
|
fallbackModels: ctx.fallbackModels,
|
|
186336
186453
|
timeoutMs: ctx.historianTimeoutMs,
|
|
186337
|
-
userMemoriesEnabled: ctx.userMemoriesEnabled
|
|
186454
|
+
userMemoriesEnabled: ctx.userMemoriesEnabled,
|
|
186455
|
+
language: ctx.language
|
|
186338
186456
|
});
|
|
186339
186457
|
return outcome.summary;
|
|
186340
186458
|
} catch (error51) {
|
|
@@ -186410,15 +186528,12 @@ function shouldShowAnnouncement() {
|
|
|
186410
186528
|
}
|
|
186411
186529
|
return ordering > 0;
|
|
186412
186530
|
}
|
|
186413
|
-
var ANNOUNCEMENT_VERSION = "0.
|
|
186531
|
+
var ANNOUNCEMENT_VERSION = "0.28.0", ANNOUNCEMENT_FEATURES, ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/F2uWxjGnU", STATE_FILENAME = "last_announced_version";
|
|
186414
186532
|
var init_announcement = __esm(() => {
|
|
186415
186533
|
init_data_path();
|
|
186416
186534
|
ANNOUNCEMENT_FEATURES = [
|
|
186417
|
-
|
|
186418
|
-
"
|
|
186419
|
-
"New Primers: durable answers to the questions that keep coming up about your project, kept current by the dreamer investigating the actual code.",
|
|
186420
|
-
"Embedding storage no longer wipes your vectors when you change model or endpoint. Different models now coexist, so switching providers keeps your existing vectors.",
|
|
186421
|
-
"Config moved to a shared CortexKit location (~/.config/cortexkit/ and <project>/.cortexkit/). This happens automatically on first run; your old file is preserved."
|
|
186535
|
+
`New 'language' option: set a top-level 2-letter language code (e.g. "tr" or "es") and Magic Context writes its summaries, memories, and guidance in that language, while keeping all structure (tags, categories, code, paths) in English. User-level only, off by default.`,
|
|
186536
|
+
"The ctx_reduce reminder now reflects how much tool output is actually reclaimable, instead of escalating to 'urgent' just because you're near compaction. It also no longer suggests dropping the agent's task list or tiny status outputs."
|
|
186422
186537
|
];
|
|
186423
186538
|
});
|
|
186424
186539
|
|
|
@@ -186712,6 +186827,9 @@ function buildHiddenAgentConfig(prompt, allowedTools, maxSteps, overrides, agent
|
|
|
186712
186827
|
};
|
|
186713
186828
|
}
|
|
186714
186829
|
|
|
186830
|
+
// src/index.ts
|
|
186831
|
+
init_language_directive();
|
|
186832
|
+
|
|
186715
186833
|
// src/config/index.ts
|
|
186716
186834
|
init_jsonc_parser();
|
|
186717
186835
|
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "node:fs";
|
|
@@ -187456,6 +187574,10 @@ function stripUnsafeProjectConfigFields(projectRaw) {
|
|
|
187456
187574
|
delete projectRaw.auto_update;
|
|
187457
187575
|
warnings.push("Ignoring auto_update from project config (security: this setting only honors user-level config).");
|
|
187458
187576
|
}
|
|
187577
|
+
if ("language" in projectRaw) {
|
|
187578
|
+
delete projectRaw.language;
|
|
187579
|
+
warnings.push("Ignoring language from project config (security: output language is a user-level setting).");
|
|
187580
|
+
}
|
|
187459
187581
|
if ("sqlite" in projectRaw) {
|
|
187460
187582
|
delete projectRaw.sqlite;
|
|
187461
187583
|
warnings.push("Ignoring sqlite.* from project config (security: SQLite cache/mmap PRAGMAs apply to the " + "process-global shared database handle; only user-level config may set them).");
|
|
@@ -188288,6 +188410,9 @@ function buildDreamTaskPrompt(task, args) {
|
|
|
188288
188410
|
// src/index.ts
|
|
188289
188411
|
init_project_identity();
|
|
188290
188412
|
|
|
188413
|
+
// src/features/magic-context/sidekick/agent.ts
|
|
188414
|
+
init_language_directive();
|
|
188415
|
+
|
|
188291
188416
|
// src/agents/sidekick.ts
|
|
188292
188417
|
var SIDEKICK_AGENT = "sidekick";
|
|
188293
188418
|
|
|
@@ -188355,12 +188480,13 @@ async function runSidekick(deps) {
|
|
|
188355
188480
|
throw error51;
|
|
188356
188481
|
}
|
|
188357
188482
|
const childSessionId = agentSessionId;
|
|
188483
|
+
const systemPrompt = withContentLanguageDirective(deps.config.system_prompt?.trim() || deps.config.prompt?.trim() || SIDEKICK_SYSTEM_PROMPT, deps.language);
|
|
188358
188484
|
const sidekickRun = await promptSyncWithValidatedOutputRetry(deps.client, {
|
|
188359
188485
|
path: { id: childSessionId },
|
|
188360
188486
|
query: { directory: deps.sessionDirectory ?? deps.projectPath },
|
|
188361
188487
|
body: {
|
|
188362
188488
|
agent: SIDEKICK_AGENT,
|
|
188363
|
-
system:
|
|
188489
|
+
system: systemPrompt,
|
|
188364
188490
|
parts: [{ type: "text", text: deps.userMessage, synthetic: true }]
|
|
188365
188491
|
}
|
|
188366
188492
|
}, {
|
|
@@ -189923,6 +190049,7 @@ var DREAMER_DOCS_AGENT = "dreamer-docs";
|
|
|
189923
190049
|
var DREAMER_REVIEWER_AGENT = "dreamer-reviewer";
|
|
189924
190050
|
|
|
189925
190051
|
// src/features/magic-context/dreamer/task-executor.ts
|
|
190052
|
+
init_language_directive();
|
|
189926
190053
|
init_shared();
|
|
189927
190054
|
init_assistant_message_extractor();
|
|
189928
190055
|
init_logger();
|
|
@@ -189931,6 +190058,7 @@ init_memory();
|
|
|
189931
190058
|
init_subagent_token_capture();
|
|
189932
190059
|
|
|
189933
190060
|
// src/features/magic-context/user-memory/review-user-memories.ts
|
|
190061
|
+
init_language_directive();
|
|
189934
190062
|
init_shared();
|
|
189935
190063
|
init_assistant_message_extractor();
|
|
189936
190064
|
init_logger();
|
|
@@ -190045,7 +190173,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
190045
190173
|
query: { directory: args.sessionDirectory },
|
|
190046
190174
|
body: {
|
|
190047
190175
|
agent: DREAMER_REVIEWER_AGENT,
|
|
190048
|
-
system: REVIEW_USER_MEMORIES_SYSTEM_PROMPT,
|
|
190176
|
+
system: withContentLanguageDirective(REVIEW_USER_MEMORIES_SYSTEM_PROMPT, args.language),
|
|
190049
190177
|
...modelBodyField(args.model),
|
|
190050
190178
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
190051
190179
|
}
|
|
@@ -192629,6 +192757,7 @@ async function promotePrimers(args) {
|
|
|
192629
192757
|
}
|
|
192630
192758
|
|
|
192631
192759
|
// src/features/magic-context/dreamer/refresh-primers.ts
|
|
192760
|
+
init_language_directive();
|
|
192632
192761
|
init_read_session_formatting();
|
|
192633
192762
|
init_shared();
|
|
192634
192763
|
init_assistant_message_extractor();
|
|
@@ -192867,7 +192996,7 @@ async function refreshOnePrimer(args, primer, sliceMs, signal) {
|
|
|
192867
192996
|
query: { directory: args.sessionDirectory },
|
|
192868
192997
|
body: {
|
|
192869
192998
|
agent: DREAMER_PRIMER_INVESTIGATOR_AGENT,
|
|
192870
|
-
system: PRIMER_INVESTIGATOR_SYSTEM_PROMPT,
|
|
192999
|
+
system: withContentLanguageDirective(PRIMER_INVESTIGATOR_SYSTEM_PROMPT, args.language),
|
|
192871
193000
|
...modelBodyField(args.model),
|
|
192872
193001
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
192873
193002
|
}
|
|
@@ -193103,6 +193232,7 @@ function insertDreamRun(db, run) {
|
|
|
193103
193232
|
init_task_registry();
|
|
193104
193233
|
|
|
193105
193234
|
// src/features/magic-context/dreamer/verify.ts
|
|
193235
|
+
init_language_directive();
|
|
193106
193236
|
init_shared();
|
|
193107
193237
|
init_assistant_message_extractor();
|
|
193108
193238
|
init_logger();
|
|
@@ -193330,7 +193460,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
193330
193460
|
query: { directory: args.sessionDirectory },
|
|
193331
193461
|
body: {
|
|
193332
193462
|
agent: DREAMER_MEMORY_MAPPER_AGENT,
|
|
193333
|
-
system: VERIFY_SYSTEM_PROMPT,
|
|
193463
|
+
system: withContentLanguageDirective(VERIFY_SYSTEM_PROMPT, args.language),
|
|
193334
193464
|
...modelBodyField(args.model),
|
|
193335
193465
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
193336
193466
|
}
|
|
@@ -193610,7 +193740,8 @@ function createDreamTaskExecutor(deps) {
|
|
|
193610
193740
|
deadline,
|
|
193611
193741
|
promotionThreshold: config2.promotionThreshold ?? 3,
|
|
193612
193742
|
model: config2.model,
|
|
193613
|
-
fallbackModels: config2.fallbackModels
|
|
193743
|
+
fallbackModels: config2.fallbackModels,
|
|
193744
|
+
language: config2.language ?? deps.language
|
|
193614
193745
|
});
|
|
193615
193746
|
recordRun("completed", null);
|
|
193616
193747
|
log(`[dreamer] review-user-memories: promoted=${result.promoted} merged=${result.merged} dismissed=${result.dismissed}`);
|
|
@@ -193646,7 +193777,8 @@ function createDreamTaskExecutor(deps) {
|
|
|
193646
193777
|
deadline,
|
|
193647
193778
|
forceBroad: config2.task === "verify-broad",
|
|
193648
193779
|
model: config2.model,
|
|
193649
|
-
fallbackModels: config2.fallbackModels
|
|
193780
|
+
fallbackModels: config2.fallbackModels,
|
|
193781
|
+
language: config2.language ?? deps.language
|
|
193650
193782
|
});
|
|
193651
193783
|
recordRun("completed", null, {
|
|
193652
193784
|
memoryChanges: computeMemoryDelta(memoryBefore)
|
|
@@ -193698,6 +193830,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
193698
193830
|
deadline,
|
|
193699
193831
|
model: config2.model,
|
|
193700
193832
|
fallbackModels: config2.fallbackModels,
|
|
193833
|
+
language: config2.language ?? deps.language,
|
|
193701
193834
|
rawProviderFactory: deps.primerRawProviderFactory
|
|
193702
193835
|
});
|
|
193703
193836
|
recordRun("completed", null);
|
|
@@ -193815,6 +193948,7 @@ function retrospectiveEventsForSessions(db, sessionIds) {
|
|
|
193815
193948
|
try {
|
|
193816
193949
|
for (const event of getCompartmentEvents(db, sessionId)) {
|
|
193817
193950
|
if (event.kind !== "causal_incident" && event.kind !== "trajectory_correction") {
|
|
193951
|
+
log(`[dreamer] dropping event: unknown kind="${event.kind}"`);
|
|
193818
193952
|
continue;
|
|
193819
193953
|
}
|
|
193820
193954
|
events.push({
|
|
@@ -193939,7 +194073,9 @@ async function runRetrospectiveTask(config2, ctx, helpers) {
|
|
|
193939
194073
|
const frictionWindow = renderFrictionWindow(messages, flagged.map((message) => message.ordinal));
|
|
193940
194074
|
const eventSessionIds = new Set(messages.map((message) => message.sessionId));
|
|
193941
194075
|
const events = retrospectiveEventsForSessions(db, eventSessionIds);
|
|
193942
|
-
const deepenRun = await runChildTurn(RETROSPECTIVE_SYSTEM_PROMPT,
|
|
194076
|
+
const deepenRun = await runChildTurn(withContentLanguageDirective(RETROSPECTIVE_SYSTEM_PROMPT, config2.language ?? deps.language, {
|
|
194077
|
+
retrospective: true
|
|
194078
|
+
}), buildRetrospectivePrompt({ projectPath: projectIdentity, frictionWindow, events }));
|
|
193943
194079
|
if (leaseLost)
|
|
193944
194080
|
throw new Error("Dream lease lost during retrospective");
|
|
193945
194081
|
const sourceSessionId = flagged[0]?.sessionId ?? userMessages[0]?.sessionId ?? "retrospective";
|
|
@@ -194025,7 +194161,7 @@ async function runAgenticTask(config2, ctx, helpers) {
|
|
|
194025
194161
|
query: { directory: docsDir },
|
|
194026
194162
|
body: {
|
|
194027
194163
|
agent: task === "maintain-docs" ? DREAMER_DOCS_AGENT : DREAMER_AGENT,
|
|
194028
|
-
system: task === "maintain-docs" ? MAINTAIN_DOCS_SYSTEM_PROMPT : CURATE_SYSTEM_PROMPT,
|
|
194164
|
+
system: task === "maintain-docs" ? MAINTAIN_DOCS_SYSTEM_PROMPT : withContentLanguageDirective(CURATE_SYSTEM_PROMPT, config2.language ?? deps.language),
|
|
194029
194165
|
...modelBodyField(config2.model),
|
|
194030
194166
|
parts: [{ type: "text", text: taskPrompt, synthetic: true }]
|
|
194031
194167
|
}
|
|
@@ -194847,7 +194983,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
|
|
|
194847
194983
|
}
|
|
194848
194984
|
try {
|
|
194849
194985
|
await runCompiledSmartNoteSweep(reg, db);
|
|
194850
|
-
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreamerConfig);
|
|
194986
|
+
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreamerConfig, reg.language);
|
|
194851
194987
|
const executor = createDreamTaskExecutor({
|
|
194852
194988
|
client: reg.client,
|
|
194853
194989
|
sessionDirectory: reg.directory,
|
|
@@ -194855,7 +194991,8 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
|
|
|
194855
194991
|
retrospectiveRawProvider: reg.retrospectiveRawProvider ?? ((db2) => new OpenCodeRetrospectiveRawProvider({ contextDb: db2, openOpenCodeDb })),
|
|
194856
194992
|
primerRawProviderFactory: reg.primerRawProviderFactory,
|
|
194857
194993
|
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreamerConfig),
|
|
194858
|
-
ensureProjectRegistered: reg.ensureRegistered
|
|
194994
|
+
ensureProjectRegistered: reg.ensureRegistered,
|
|
194995
|
+
language: reg.language
|
|
194859
194996
|
});
|
|
194860
194997
|
const ran = await runDueTasksForProject({
|
|
194861
194998
|
db,
|
|
@@ -196219,7 +196356,8 @@ Provide a prompt to augment with project memory context.`, {});
|
|
|
196219
196356
|
projectPath: deps.sidekick.projectPath,
|
|
196220
196357
|
sessionDirectory: deps.sidekick.sessionDirectory,
|
|
196221
196358
|
userMessage: prompt,
|
|
196222
|
-
config: deps.sidekick.config
|
|
196359
|
+
config: deps.sidekick.config,
|
|
196360
|
+
language: deps.sidekick.language
|
|
196223
196361
|
});
|
|
196224
196362
|
let augmentedPrompt;
|
|
196225
196363
|
if (sidekickResult) {
|
|
@@ -196697,6 +196835,7 @@ var pendingPiDecisionBySession = new Map;
|
|
|
196697
196835
|
var lastBoundMessageIdBySession = new Map;
|
|
196698
196836
|
var scheduledWriteTokensBySession = new Map;
|
|
196699
196837
|
var writerOverrideForTests = null;
|
|
196838
|
+
var retentionOverrideForTests = null;
|
|
196700
196839
|
function normalizeMaterializeReason(harness, reason, rematerialized) {
|
|
196701
196840
|
const raw = typeof reason === "string" ? reason.trim() : "";
|
|
196702
196841
|
if (raw.length > 0) {
|
|
@@ -196797,7 +196936,7 @@ function writeTransformDecisionRow(dbPath, row) {
|
|
|
196797
196936
|
WHERE session_id = ? AND harness = ?
|
|
196798
196937
|
ORDER BY ts_ms DESC, rowid DESC
|
|
196799
196938
|
LIMIT ?
|
|
196800
|
-
)`).run(row.sessionId, row.harness, row.sessionId, row.harness, TRANSFORM_DECISIONS_RETENTION);
|
|
196939
|
+
)`).run(row.sessionId, row.harness, row.sessionId, row.harness, retentionOverrideForTests ?? TRANSFORM_DECISIONS_RETENTION);
|
|
196801
196940
|
} finally {
|
|
196802
196941
|
closeQuietly(db);
|
|
196803
196942
|
}
|
|
@@ -196825,6 +196964,7 @@ function channel1RefireTokens(workingWindowTokens) {
|
|
|
196825
196964
|
var S_GENTLE = 0.2;
|
|
196826
196965
|
var S_FIRM = 0.4;
|
|
196827
196966
|
var S_URGENT = 0.65;
|
|
196967
|
+
var CHANNEL1_PRESSURE_FLOOR = 0.8;
|
|
196828
196968
|
var LEVEL_RANK = { gentle: 1, firm: 2, urgent: 3 };
|
|
196829
196969
|
var DROP_SENTINELS = ["[dropped", "[truncated"];
|
|
196830
196970
|
function isDroppedToolOutput(output) {
|
|
@@ -196889,7 +197029,8 @@ function computeTailTokenEstimate(messages) {
|
|
|
196889
197029
|
};
|
|
196890
197030
|
}
|
|
196891
197031
|
function decideChannel1(input) {
|
|
196892
|
-
const { undroppedTokens,
|
|
197032
|
+
const { undroppedTokens, workingWindowTokens, hasRecentReduce } = input;
|
|
197033
|
+
const pressure = Math.min(1, Math.max(0, input.pressure));
|
|
196893
197034
|
const resetCycle = hasRecentReduce || undroppedTokens < input.lastNudgeUndropped;
|
|
196894
197035
|
const lastNudge = resetCycle ? 0 : input.lastNudgeUndropped;
|
|
196895
197036
|
const lastLevel = resetCycle ? "" : input.lastNudgeLevel;
|
|
@@ -196904,8 +197045,10 @@ function decideChannel1(input) {
|
|
|
196904
197045
|
return quiet();
|
|
196905
197046
|
if (undroppedTokens < CHANNEL1_FLOOR_TOKENS)
|
|
196906
197047
|
return quiet();
|
|
196907
|
-
|
|
196908
|
-
|
|
197048
|
+
if (pressure < CHANNEL1_PRESSURE_FLOOR)
|
|
197049
|
+
return quiet();
|
|
197050
|
+
const denom = Math.max(input.estimatedInputTokens, 1);
|
|
197051
|
+
const severity = Math.min(1, undroppedTokens / denom);
|
|
196909
197052
|
if (severity < S_GENTLE)
|
|
196910
197053
|
return quiet();
|
|
196911
197054
|
let level;
|
|
@@ -197206,6 +197349,7 @@ init_session_project_storage();
|
|
|
197206
197349
|
init_storage_meta_persisted();
|
|
197207
197350
|
await init_storage();
|
|
197208
197351
|
init_logger();
|
|
197352
|
+
init_models_dev_cache();
|
|
197209
197353
|
|
|
197210
197354
|
// src/hooks/magic-context/boundary-execution.ts
|
|
197211
197355
|
var FORCE_MATERIALIZE_PERCENTAGE2 = 85;
|
|
@@ -201345,6 +201489,18 @@ function findLastAssistantModel2(messages) {
|
|
|
201345
201489
|
}
|
|
201346
201490
|
return null;
|
|
201347
201491
|
}
|
|
201492
|
+
function findNewestUserModel(messages) {
|
|
201493
|
+
for (let i = messages.length - 1;i >= 0; i--) {
|
|
201494
|
+
const info = messages[i].info;
|
|
201495
|
+
if (info.role !== "user")
|
|
201496
|
+
continue;
|
|
201497
|
+
if (info.model?.providerID && info.model.modelID) {
|
|
201498
|
+
return { providerID: info.model.providerID, modelID: info.model.modelID };
|
|
201499
|
+
}
|
|
201500
|
+
return null;
|
|
201501
|
+
}
|
|
201502
|
+
return null;
|
|
201503
|
+
}
|
|
201348
201504
|
function createTransform(deps) {
|
|
201349
201505
|
const loadedSessions = new Set;
|
|
201350
201506
|
const lastEmergencyNotificationCount = new Map;
|
|
@@ -201405,15 +201561,15 @@ function createTransform(deps) {
|
|
|
201405
201561
|
const canRunCompartments = fullFeatureMode && historianRunnable && deps.client !== undefined && compartmentDirectory.length > 0;
|
|
201406
201562
|
const fallbackModelId = deps.getFallbackModelId?.(sessionId);
|
|
201407
201563
|
const tModelDetect = performance.now();
|
|
201564
|
+
const persistedUsageBeforeResets = loadPersistedUsage(db, sessionId);
|
|
201408
201565
|
if (deps.liveModelBySession) {
|
|
201409
|
-
const
|
|
201410
|
-
if (
|
|
201411
|
-
|
|
201412
|
-
|
|
201413
|
-
|
|
201414
|
-
|
|
201415
|
-
sessionLog(sessionId, `transform: model change
|
|
201416
|
-
deps.liveModelBySession.set(sessionId, lastAssistantModel);
|
|
201566
|
+
const currentOutgoingModel = findNewestUserModel(messages) ?? deps.liveModelBySession.get(sessionId) ?? findLastAssistantModel2(messages);
|
|
201567
|
+
if (currentOutgoingModel) {
|
|
201568
|
+
deps.liveModelBySession.set(sessionId, currentOutgoingModel);
|
|
201569
|
+
const outgoingModelKey = resolveModelKey(currentOutgoingModel.providerID, currentOutgoingModel.modelID);
|
|
201570
|
+
const lastUsageModelKey = persistedUsageBeforeResets?.lastObservedModelKey ?? null;
|
|
201571
|
+
if (lastUsageModelKey != null && outgoingModelKey != null && lastUsageModelKey !== outgoingModelKey) {
|
|
201572
|
+
sessionLog(sessionId, `transform: model change since last usage (${lastUsageModelKey} -> ${outgoingModelKey}), clearing stale per-model state`);
|
|
201417
201573
|
updateSessionMeta(db, sessionId, {
|
|
201418
201574
|
lastContextPercentage: 0,
|
|
201419
201575
|
lastInputTokens: 0,
|
|
@@ -201443,7 +201599,6 @@ function createTransform(deps) {
|
|
|
201443
201599
|
const tFirstPass = performance.now();
|
|
201444
201600
|
const isFirstTransformPassForSession = !loadedSessions.has(sessionId);
|
|
201445
201601
|
loadedSessions.add(sessionId);
|
|
201446
|
-
const persistedUsageBeforeFirstPassReset = loadPersistedUsage(db, sessionId);
|
|
201447
201602
|
const historianFailureState = getHistorianFailureState(db, sessionId);
|
|
201448
201603
|
if (isFirstTransformPassForSession && sessionMeta) {
|
|
201449
201604
|
const persistedPct = sessionMeta.lastContextPercentage ?? 0;
|
|
@@ -201462,6 +201617,17 @@ function createTransform(deps) {
|
|
|
201462
201617
|
let emergencyRecoveryArmed = false;
|
|
201463
201618
|
if (fullFeatureMode) {
|
|
201464
201619
|
try {
|
|
201620
|
+
const armModel = deps.liveModelBySession?.get(sessionId);
|
|
201621
|
+
const armModelKey = deps.getModelKey?.(sessionId);
|
|
201622
|
+
const armSnapshot = persistedUsageBeforeResets;
|
|
201623
|
+
const lastMeasuredInput = armSnapshot?.usage.inputTokens ?? sessionMeta?.lastInputTokens ?? 0;
|
|
201624
|
+
const lastMeasuredModelKey = armSnapshot?.lastObservedModelKey ?? null;
|
|
201625
|
+
const armCatalogLimit = armModel ? getSdkContextLimit(armModel.providerID, armModel.modelID) : undefined;
|
|
201626
|
+
if (!sessionMeta?.isSubagent && armModel && typeof armCatalogLimit === "number" && armCatalogLimit > 0 && lastMeasuredInput > armCatalogLimit && lastMeasuredModelKey != null && armModelKey != null && lastMeasuredModelKey !== armModelKey && !getOverflowState(db, sessionId).needsEmergencyRecovery) {
|
|
201627
|
+
sessionLog(sessionId, `transform: last input ${lastMeasuredInput} (model ${lastMeasuredModelKey}) exceeds new model ${armModelKey} catalog limit ${armCatalogLimit}; arming overflow recovery proactively for the shrinking switch`);
|
|
201628
|
+
recordOverflowDetected(db, sessionId, undefined, armModelKey);
|
|
201629
|
+
resetProtectedTailNoEligibleHead(db, sessionId);
|
|
201630
|
+
}
|
|
201465
201631
|
const overflowState = getOverflowState(db, sessionId);
|
|
201466
201632
|
emergencyRecoveryArmed = overflowState.needsEmergencyRecovery;
|
|
201467
201633
|
if (contextUsageEarly.percentage < 80 && !overflowState.needsEmergencyRecovery) {
|
|
@@ -201498,7 +201664,7 @@ function createTransform(deps) {
|
|
|
201498
201664
|
sessionID: sessionId
|
|
201499
201665
|
}) : undefined;
|
|
201500
201666
|
const currentModelKeyForBoundary = deps.getModelKey?.(sessionId);
|
|
201501
|
-
const persistedUsageFreshForBoundary =
|
|
201667
|
+
const persistedUsageFreshForBoundary = persistedUsageBeforeResets && Date.now() - persistedUsageBeforeResets.updatedAt <= 10 * 60 * 1000 && (persistedUsageBeforeResets.lastObservedModelKey === null || currentModelKeyForBoundary === undefined || persistedUsageBeforeResets.lastObservedModelKey === currentModelKeyForBoundary) && (resolvedContextLimit === undefined || persistedUsageBeforeResets.lastUsageContextLimit === 0 || persistedUsageBeforeResets.lastUsageContextLimit === resolvedContextLimit) ? persistedUsageBeforeResets.usage : null;
|
|
201502
201668
|
const boundaryUsageForProtectedTail = persistedUsageFreshForBoundary ?? contextUsageEarly;
|
|
201503
201669
|
const boundaryUsageSource = persistedUsageFreshForBoundary ? "persisted" : "live";
|
|
201504
201670
|
const historyBudgetTokens = resolveHistoryBudgetTokens(deps.historyBudgetPercentage, contextUsageEarly, deps.executeThresholdPercentage, deps.getModelKey?.(sessionId), deps.executeThresholdTokens, resolvedContextLimit);
|
|
@@ -202735,6 +202901,7 @@ function maybeInjectChannel1Nudge(args, sessionId, tool, output) {
|
|
|
202735
202901
|
const decision = decideChannel1({
|
|
202736
202902
|
undroppedTokens,
|
|
202737
202903
|
pressure,
|
|
202904
|
+
estimatedInputTokens: state.lastInputTokens + state.turnToolTokens,
|
|
202738
202905
|
workingWindowTokens,
|
|
202739
202906
|
lastNudgeUndropped: getLastNudgeUndropped(args.db, sessionId),
|
|
202740
202907
|
lastNudgeLevel: getLastNudgeLevel(args.db, sessionId),
|
|
@@ -202800,6 +202967,7 @@ init_send_session_notification();
|
|
|
202800
202967
|
import { createHash as createHash13 } from "node:crypto";
|
|
202801
202968
|
|
|
202802
202969
|
// src/agents/magic-context-prompt.ts
|
|
202970
|
+
init_language_directive();
|
|
202803
202971
|
var LONG_TERM_PARTNER_FRAME = `### You are the user's long-term partner on this project — not a one-off hire
|
|
202804
202972
|
|
|
202805
202973
|
Most AI sessions are disposable: one session per task, discarded when it's done — like hiring a developer for a single bug fix and letting them go the moment they finish. Magic Context changes this completely. This session is a durable working relationship: you carry the full history and accumulated knowledge of this project, and you continue across many tasks, bugs, and features — with memory that persists across restarts. This session may continue for weeks, months, or even years.
|
|
@@ -202878,7 +203046,7 @@ Drop silently — do not narrate it. NEVER drop large ranges blindly (e.g., "1-5
|
|
|
202878
203046
|
Older tool calls may show \`[dropped §N§]\` sentinels; that is normal context management, not a pattern to copy. ALWAYS make fresh real tool calls when you need data again; never fabricate or inline tool output.`;
|
|
202879
203047
|
var CAVEMAN_COMPRESSION_WARNING = `
|
|
202880
203048
|
**BEWARE**: History compression is on; older user AND assistant text — including your own earlier responses — has been deterministically rewritten in a terse caveman style (dropped articles, missing auxiliaries, \`//\` instead of connectives like \`because\`). This is automatic context compression that runs after the fact, not your actual prior wording or the user's. **DO NOT mimic this style in new turns.** Write fresh responses in normal prose. If you notice your output drifting into caveman cadence, that drift is in-context-learning bleeding from the compressed history — consciously revert to full sentences.`;
|
|
202881
|
-
function buildMagicContextSection(_agent, protectedTags, ctxReduceEnabled = true, dreamerEnabled = false, temporalAwarenessEnabled = false, cavemanTextCompressionEnabled = false, subagentMode = false) {
|
|
203049
|
+
function buildMagicContextSection(_agent, protectedTags, ctxReduceEnabled = true, dreamerEnabled = false, temporalAwarenessEnabled = false, cavemanTextCompressionEnabled = false, subagentMode = false, language) {
|
|
202882
203050
|
if (subagentMode) {
|
|
202883
203051
|
return `## Magic Context
|
|
202884
203052
|
|
|
@@ -202890,13 +203058,17 @@ The dreamer evaluates smart note conditions during nightly runs and surfaces the
|
|
|
202890
203058
|
Example: \`ctx_note(action="write", content="Implement X because Y", surface_condition="When PR #42 is merged in this repo")\`` : "";
|
|
202891
203059
|
const temporalGuidance = temporalAwarenessEnabled ? TEMPORAL_AWARENESS_GUIDANCE : "";
|
|
202892
203060
|
const cavemanWarning = cavemanTextCompressionEnabled && !ctxReduceEnabled ? CAVEMAN_COMPRESSION_WARNING : "";
|
|
203061
|
+
const languageDirective = buildPrimaryLanguageDirective(language);
|
|
203062
|
+
const languageGuidance = languageDirective ? `
|
|
203063
|
+
|
|
203064
|
+
${languageDirective}` : "";
|
|
202893
203065
|
if (!ctxReduceEnabled) {
|
|
202894
203066
|
return `## Magic Context
|
|
202895
203067
|
|
|
202896
203068
|
${LONG_TERM_PARTNER_FRAME}
|
|
202897
203069
|
${PARTNER_FRAME_CLOSER_NO_REDUCE}
|
|
202898
203070
|
|
|
202899
|
-
${BASE_INTRO_NO_REDUCE()}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}`;
|
|
203071
|
+
${BASE_INTRO_NO_REDUCE()}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
|
|
202900
203072
|
}
|
|
202901
203073
|
return `## Magic Context
|
|
202902
203074
|
|
|
@@ -202906,7 +203078,7 @@ ${PARTNER_FRAME_CLOSER_REDUCE}
|
|
|
202906
203078
|
${BASE_INTRO(protectedTags)}${smartNoteGuidance}${temporalGuidance}
|
|
202907
203079
|
${GENERIC_SECTION}
|
|
202908
203080
|
|
|
202909
|
-
Prefer many small targeted operations over one large blanket operation, and keep the working set tidy as routine maintenance
|
|
203081
|
+
Prefer many small targeted operations over one large blanket operation, and keep the working set tidy as routine maintenance.${languageGuidance}`;
|
|
202910
203082
|
}
|
|
202911
203083
|
|
|
202912
203084
|
// src/hooks/magic-context/system-prompt-hash.ts
|
|
@@ -202964,7 +203136,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
202964
203136
|
const fullPrompt = output.system.join(`
|
|
202965
203137
|
`);
|
|
202966
203138
|
if (fullPrompt.length > 0 && !fullPrompt.includes(MAGIC_CONTEXT_MARKER) && !skipGuidanceForDisabledSubagent) {
|
|
202967
|
-
const guidance = buildMagicContextSection(null, deps.protectedTags, effectiveCtxReduceEnabled, deps.dreamerEnabled, deps.experimentalTemporalAwareness, deps.experimentalCavemanTextCompression, subagentReduceMode);
|
|
203139
|
+
const guidance = buildMagicContextSection(null, deps.protectedTags, effectiveCtxReduceEnabled, deps.dreamerEnabled, deps.experimentalTemporalAwareness, deps.experimentalCavemanTextCompression, subagentReduceMode, deps.language);
|
|
202968
203140
|
output.system.push(guidance);
|
|
202969
203141
|
sessionLog(sessionId, `injected generic guidance into system prompt (ctxReduce=${effectiveCtxReduceEnabled}, subagent=${isSubagentSession}, subagentReduceMode=${subagentReduceMode})`);
|
|
202970
203142
|
}
|
|
@@ -203252,6 +203424,7 @@ function createMagicContextHook(deps) {
|
|
|
203252
203424
|
memoryEnabled: deps.config.memory?.enabled ?? true,
|
|
203253
203425
|
autoPromote: deps.config.memory?.auto_promote ?? true,
|
|
203254
203426
|
fallbackModels: historianFallbackModels,
|
|
203427
|
+
language: deps.config.language,
|
|
203255
203428
|
fallbackModelId: (() => {
|
|
203256
203429
|
const model = resolveLiveModel(sessionId);
|
|
203257
203430
|
return model ? `${model.providerID}/${model.modelID}` : undefined;
|
|
@@ -203290,7 +203463,7 @@ function createMagicContextHook(deps) {
|
|
|
203290
203463
|
signal,
|
|
203291
203464
|
onProgress: ({ embedded, total }) => {
|
|
203292
203465
|
const cur = recompProgressBySession.get(sessionId);
|
|
203293
|
-
if (
|
|
203466
|
+
if (cur?.phase !== "recomp")
|
|
203294
203467
|
return;
|
|
203295
203468
|
recompProgressBySession.set(sessionId, {
|
|
203296
203469
|
...cur,
|
|
@@ -203493,7 +203666,7 @@ function createMagicContextHook(deps) {
|
|
|
203493
203666
|
return;
|
|
203494
203667
|
}
|
|
203495
203668
|
lastScheduleCheckMs = now;
|
|
203496
|
-
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreaming);
|
|
203669
|
+
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreaming, deps.config.language);
|
|
203497
203670
|
const executor = createDreamTaskExecutor({
|
|
203498
203671
|
client: deps.client,
|
|
203499
203672
|
sessionDirectory: deps.directory,
|
|
@@ -203502,7 +203675,8 @@ function createMagicContextHook(deps) {
|
|
|
203502
203675
|
contextDb: providerDb,
|
|
203503
203676
|
openOpenCodeDb
|
|
203504
203677
|
}),
|
|
203505
|
-
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreaming)
|
|
203678
|
+
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreaming),
|
|
203679
|
+
language: deps.config.language
|
|
203506
203680
|
});
|
|
203507
203681
|
runDueTasksForProject({
|
|
203508
203682
|
db,
|
|
@@ -203551,7 +203725,8 @@ function createMagicContextHook(deps) {
|
|
|
203551
203725
|
config: sidekickConfig,
|
|
203552
203726
|
projectPath,
|
|
203553
203727
|
sessionDirectory: deps.directory,
|
|
203554
|
-
client: deps.client
|
|
203728
|
+
client: deps.client,
|
|
203729
|
+
language: deps.config.language
|
|
203555
203730
|
} : undefined,
|
|
203556
203731
|
dreamer: dreamerConfig ? {
|
|
203557
203732
|
config: dreamerConfig,
|
|
@@ -203559,7 +203734,7 @@ function createMagicContextHook(deps) {
|
|
|
203559
203734
|
runManual: (task) => runManualDream({
|
|
203560
203735
|
db,
|
|
203561
203736
|
projectIdentity: projectPath,
|
|
203562
|
-
tasks: buildDreamTaskRuntimeConfigs(dreamerConfig),
|
|
203737
|
+
tasks: buildDreamTaskRuntimeConfigs(dreamerConfig, deps.config.language),
|
|
203563
203738
|
executor: createDreamTaskExecutor({
|
|
203564
203739
|
client: deps.client,
|
|
203565
203740
|
sessionDirectory: deps.directory,
|
|
@@ -203568,7 +203743,8 @@ function createMagicContextHook(deps) {
|
|
|
203568
203743
|
contextDb: providerDb,
|
|
203569
203744
|
openOpenCodeDb
|
|
203570
203745
|
}),
|
|
203571
|
-
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreamerConfig)
|
|
203746
|
+
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreamerConfig),
|
|
203747
|
+
language: deps.config.language
|
|
203572
203748
|
}),
|
|
203573
203749
|
task
|
|
203574
203750
|
})
|
|
@@ -203579,6 +203755,7 @@ function createMagicContextHook(deps) {
|
|
|
203579
203755
|
protectedTags: deps.config.protected_tags,
|
|
203580
203756
|
ctxReduceEnabled,
|
|
203581
203757
|
dreamerEnabled: dreamerRunnable,
|
|
203758
|
+
language: deps.config.language,
|
|
203582
203759
|
injectDocs: deps.config.dreamer?.inject_docs !== false,
|
|
203583
203760
|
directory: deps.directory,
|
|
203584
203761
|
historyRefreshSessions,
|
|
@@ -206310,6 +206487,7 @@ var server2 = async (ctx) => {
|
|
|
206310
206487
|
projectIdentity: resolveProjectIdentity(ctx.directory),
|
|
206311
206488
|
client: ctx.client,
|
|
206312
206489
|
dreamerConfig: dreamerRunnable ? pluginConfig.dreamer : undefined,
|
|
206490
|
+
language: pluginConfig.language,
|
|
206313
206491
|
embeddingConfig: pluginConfig.embedding,
|
|
206314
206492
|
memoryEnabled: pluginConfig.memory?.enabled === true,
|
|
206315
206493
|
gitCommitIndexing: pluginConfig.memory.git_commit_indexing?.enabled ? {
|
|
@@ -206481,9 +206659,9 @@ var server2 = async (ctx) => {
|
|
|
206481
206659
|
const registrations = buildHiddenAgentRegistrations({
|
|
206482
206660
|
dreamerPrompt: DREAMER_SYSTEM_PROMPT,
|
|
206483
206661
|
smartNoteCompilerPrompt: SMART_NOTE_COMPILER_SYSTEM_PROMPT,
|
|
206484
|
-
historianPrompt: COMPARTMENT_AGENT_SYSTEM_PROMPT,
|
|
206485
|
-
historianRecompPrompt: COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT,
|
|
206486
|
-
historianEditorPrompt: HISTORIAN_EDITOR_SYSTEM_PROMPT,
|
|
206662
|
+
historianPrompt: withContentLanguageDirective(COMPARTMENT_AGENT_SYSTEM_PROMPT, pluginConfig.language, { preserveUserQuotes: true }),
|
|
206663
|
+
historianRecompPrompt: withContentLanguageDirective(COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, pluginConfig.language, { preserveUserQuotes: true }),
|
|
206664
|
+
historianEditorPrompt: withContentLanguageDirective(HISTORIAN_EDITOR_SYSTEM_PROMPT, pluginConfig.language, { preserveUserQuotes: true }),
|
|
206487
206665
|
sidekickPrompt: SIDEKICK_SYSTEM_PROMPT,
|
|
206488
206666
|
dreamerOverrides: dreamerAgentOverrides,
|
|
206489
206667
|
historianOverrides: historianAgentOverrides,
|