@wolfx/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/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, 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();
|
|
@@ -15268,6 +15361,7 @@ var init_magic_context = __esm(() => {
|
|
|
15268
15361
|
});
|
|
15269
15362
|
MagicContextConfigSchema = exports_external.object({
|
|
15270
15363
|
enabled: exports_external.boolean().default(true).describe("Enable magic context (default: true)"),
|
|
15364
|
+
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."),
|
|
15271
15365
|
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)"),
|
|
15272
15366
|
historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
|
|
15273
15367
|
dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
|
|
@@ -150998,7 +151092,7 @@ function enforceSchemaFence(db, dbPath, latestSupportedVersion) {
|
|
|
150998
151092
|
return true;
|
|
150999
151093
|
}
|
|
151000
151094
|
lastSchemaFenceRejection = { persistedVersion, supportedVersion: latestSupportedVersion };
|
|
151001
|
-
log(`[magic-context] storage fatal: refusing to open ${dbPath}; database schema v${persistedVersion} is newer than this binary supports (max v${latestSupportedVersion}).
|
|
151095
|
+
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.`);
|
|
151002
151096
|
return false;
|
|
151003
151097
|
}
|
|
151004
151098
|
function setSqlitePragmaConfig(config2) {
|
|
@@ -155731,10 +155825,18 @@ function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, li
|
|
|
155731
155825
|
WHERE session_id = ? AND status = 'active'
|
|
155732
155826
|
ORDER BY tag_number DESC LIMIT 1 OFFSET ?
|
|
155733
155827
|
)` : "";
|
|
155734
|
-
const
|
|
155828
|
+
const excludeStateTools = RECLAIM_HINT_EXCLUDED_LIST ? `AND (tool_name IS NULL OR tool_name NOT IN (${RECLAIM_HINT_EXCLUDED_LIST}))` : "";
|
|
155829
|
+
const valueFloor = `AND (
|
|
155830
|
+
(token_count IS NULL AND input_token_count IS NULL)
|
|
155831
|
+
OR (COALESCE(token_count, 0) + COALESCE(input_token_count, 0)) >= ?
|
|
155832
|
+
)`;
|
|
155833
|
+
const params = protectedTags > 0 ? [sessionId, RECLAIM_HINT_MIN_TOKENS, sessionId, protectedTags - 1, boundedLimit] : [sessionId, RECLAIM_HINT_MIN_TOKENS, boundedLimit];
|
|
155735
155834
|
const rows = db.prepare(`SELECT tag_number, tool_name
|
|
155736
155835
|
FROM tags
|
|
155737
|
-
WHERE session_id = ? AND status = 'active' AND type = 'tool'
|
|
155836
|
+
WHERE session_id = ? AND status = 'active' AND type = 'tool'
|
|
155837
|
+
${excludeStateTools}
|
|
155838
|
+
${valueFloor}
|
|
155839
|
+
${whereProtected}
|
|
155738
155840
|
ORDER BY tag_number ASC, id ASC
|
|
155739
155841
|
LIMIT ?`).all(...params);
|
|
155740
155842
|
return rows.filter((row) => typeof row.tag_number === "number").map((row) => ({
|
|
@@ -156124,7 +156226,7 @@ function deleteToolTagsByOwner(db, sessionId, ownerMsgId) {
|
|
|
156124
156226
|
const result = getDeleteToolTagsByOwnerStatement(db).run(sessionId, ownerMsgId);
|
|
156125
156227
|
return result.changes ?? 0;
|
|
156126
156228
|
}
|
|
156127
|
-
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;
|
|
156229
|
+
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;
|
|
156128
156230
|
var init_storage_tags = __esm(() => {
|
|
156129
156231
|
insertTagStatements = new WeakMap;
|
|
156130
156232
|
updateTagStatusStatements = new WeakMap;
|
|
@@ -156137,6 +156239,8 @@ var init_storage_tags = __esm(() => {
|
|
|
156137
156239
|
updateTagByteSizeStatements = new WeakMap;
|
|
156138
156240
|
updateTagInputByteSizeStatements = new WeakMap;
|
|
156139
156241
|
CONTENT_ID_SUFFIX = /:(?:p|file)\d+$/;
|
|
156242
|
+
RECLAIM_HINT_EXCLUDED_TOOLS = ["todowrite"];
|
|
156243
|
+
RECLAIM_HINT_EXCLUDED_LIST = RECLAIM_HINT_EXCLUDED_TOOLS.map((name2) => `'${name2.replace(/'/g, "''")}'`).join(", ");
|
|
156140
156244
|
updateTagTokenCountStatements = new WeakMap;
|
|
156141
156245
|
updateTagInputTokenCountStatements = new WeakMap;
|
|
156142
156246
|
getOwnerScopedToolTagNumbersStatements = new WeakMap;
|
|
@@ -157804,8 +157908,13 @@ async function sendSchemaFenceWarning(client, directory, detail) {
|
|
|
157804
157908
|
`newer build (OpenCode and Pi share one database). This build only supports`,
|
|
157805
157909
|
`up to v${detail.supportedVersion}, so it has fail-closed to avoid corrupting the cache.`,
|
|
157806
157910
|
"",
|
|
157807
|
-
"
|
|
157808
|
-
"
|
|
157911
|
+
"This usually means a pinned or stale plugin is sharing the database with a",
|
|
157912
|
+
"newer instance. Update or unpin Magic Context on this harness (or update",
|
|
157913
|
+
"OpenCode/Pi) to the latest version, then restart. The fastest fix is:",
|
|
157914
|
+
"",
|
|
157915
|
+
" npx @cortexkit/magic-context@latest doctor --force",
|
|
157916
|
+
"",
|
|
157917
|
+
"Your data is safe; nothing is disabled permanently."
|
|
157809
157918
|
].join(`
|
|
157810
157919
|
`);
|
|
157811
157920
|
try {
|
|
@@ -158075,7 +158184,7 @@ __export(exports_task_config, {
|
|
|
158075
158184
|
dreamTaskScheduled: () => dreamTaskScheduled,
|
|
158076
158185
|
buildDreamTaskRuntimeConfigs: () => buildDreamTaskRuntimeConfigs
|
|
158077
158186
|
});
|
|
158078
|
-
function buildDreamTaskRuntimeConfigs(dreamer) {
|
|
158187
|
+
function buildDreamTaskRuntimeConfigs(dreamer, language) {
|
|
158079
158188
|
const tasks = dreamer.tasks ?? {};
|
|
158080
158189
|
return CANONICAL_DREAM_TASKS.map((task) => {
|
|
158081
158190
|
const t = tasks[task] ?? {
|
|
@@ -158091,6 +158200,7 @@ function buildDreamTaskRuntimeConfigs(dreamer) {
|
|
|
158091
158200
|
model,
|
|
158092
158201
|
fallbackModels,
|
|
158093
158202
|
thinkingLevel,
|
|
158203
|
+
language,
|
|
158094
158204
|
timeoutMinutes: t.timeout_minutes ?? 20,
|
|
158095
158205
|
promotionThreshold: t.promotion_threshold
|
|
158096
158206
|
};
|
|
@@ -169057,8 +169167,8 @@ function buildHistorianFailureNotice(failureCount, lastError) {
|
|
|
169057
169167
|
].join(`
|
|
169058
169168
|
`);
|
|
169059
169169
|
}
|
|
169060
|
-
function buildHistorianRepairPrompt(originalPrompt, previousOutput, validationError) {
|
|
169061
|
-
|
|
169170
|
+
function buildHistorianRepairPrompt(originalPrompt, previousOutput, validationError, language) {
|
|
169171
|
+
const prompt = [
|
|
169062
169172
|
originalPrompt,
|
|
169063
169173
|
"",
|
|
169064
169174
|
"Your previous XML response was invalid and cannot be persisted.",
|
|
@@ -169071,6 +169181,7 @@ function buildHistorianRepairPrompt(originalPrompt, previousOutput, validationEr
|
|
|
169071
169181
|
previousOutput
|
|
169072
169182
|
].join(`
|
|
169073
169183
|
`);
|
|
169184
|
+
return withContentLanguageDirective(prompt, language, { preserveUserQuotes: true });
|
|
169074
169185
|
}
|
|
169075
169186
|
function validateStoredCompartments(compartments) {
|
|
169076
169187
|
if (compartments.length === 0) {
|
|
@@ -169147,6 +169258,7 @@ function getReducedRecompTokenBudget(currentBudget) {
|
|
|
169147
169258
|
}
|
|
169148
169259
|
var MIN_RECOMP_CHUNK_TOKEN_BUDGET = 20, HISTORIAN_PERSISTENT_FAILURE_THRESHOLD = 3;
|
|
169149
169260
|
var init_compartment_runner_validation = __esm(async () => {
|
|
169261
|
+
init_language_directive();
|
|
169150
169262
|
init_compartment_parser();
|
|
169151
169263
|
await init_compartment_runner_mapping();
|
|
169152
169264
|
});
|
|
@@ -169184,7 +169296,7 @@ async function runValidatedHistorianPass(args) {
|
|
|
169184
169296
|
return finalResult;
|
|
169185
169297
|
}
|
|
169186
169298
|
await args.callbacks?.onRepairRetry?.(firstValidation.error ?? "invalid compartment output");
|
|
169187
|
-
const repairPrompt = buildHistorianRepairPrompt(args.prompt, firstRun.result, firstValidation.error ?? "invalid compartment output");
|
|
169299
|
+
const repairPrompt = buildHistorianRepairPrompt(args.prompt, firstRun.result, firstValidation.error ?? "invalid compartment output", args.language);
|
|
169188
169300
|
const repairRun = await runHistorianPrompt({
|
|
169189
169301
|
...args,
|
|
169190
169302
|
prompt: repairPrompt,
|
|
@@ -174569,7 +174681,8 @@ ${chunkText}`,
|
|
|
174569
174681
|
timeoutMs: historianTimeoutMs,
|
|
174570
174682
|
fallbackModelId: deps.fallbackModelId,
|
|
174571
174683
|
fallbackModels: deps.fallbackModels,
|
|
174572
|
-
twoPass: deps.historianTwoPass
|
|
174684
|
+
twoPass: deps.historianTwoPass,
|
|
174685
|
+
language: deps.language
|
|
174573
174686
|
});
|
|
174574
174687
|
if (!validatedPass.ok) {
|
|
174575
174688
|
sessionLog(sessionId, `historian failure: source=validation reason="${validatedPass.error}" chunkRange=${chunk.startIndex}-${chunk.endIndex} fallbackModel=${deps.fallbackModelId ?? "<none>"} twoPass=${deps.historianTwoPass ? "true" : "false"}`);
|
|
@@ -175045,6 +175158,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
175045
175158
|
twoPass: deps.historianTwoPass,
|
|
175046
175159
|
subagentKind: "recomp",
|
|
175047
175160
|
agentId: HISTORIAN_RECOMP_AGENT,
|
|
175161
|
+
language: deps.language,
|
|
175048
175162
|
callbacks: {
|
|
175049
175163
|
onRepairRetry: async (error51) => {
|
|
175050
175164
|
emitProgress(`Repair retry (pass ${passCount + 1})…`);
|
|
@@ -175487,6 +175601,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
175487
175601
|
twoPass: deps.historianTwoPass,
|
|
175488
175602
|
subagentKind: "recomp",
|
|
175489
175603
|
agentId: HISTORIAN_RECOMP_AGENT,
|
|
175604
|
+
language: deps.language,
|
|
175490
175605
|
callbacks: {
|
|
175491
175606
|
onRepairRetry: async (error51) => {
|
|
175492
175607
|
await sendIgnoredMessage(client, sessionId, `## Magic Recomp — Partial
|
|
@@ -177847,7 +177962,7 @@ async function runMemoryMigration(deps) {
|
|
|
177847
177962
|
query: { directory },
|
|
177848
177963
|
body: {
|
|
177849
177964
|
agent: HISTORIAN_AGENT,
|
|
177850
|
-
system: MIGRATION_SYSTEM_PROMPT,
|
|
177965
|
+
system: withMigrationLanguageDirective(MIGRATION_SYSTEM_PROMPT, deps.language),
|
|
177851
177966
|
...modelOverride ? { model: modelOverride } : {},
|
|
177852
177967
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
177853
177968
|
}
|
|
@@ -177926,6 +178041,7 @@ async function runMemoryMigration(deps) {
|
|
|
177926
178041
|
}
|
|
177927
178042
|
var V2_CATEGORIES, MIGRATED_BLOCK_RE, USER_OBS_BLOCK_RE, CATEGORY_BLOCK_RE = (cat) => new RegExp(`<${cat}>([\\s\\S]*?)</${cat}>`), MIGRATION_SYSTEM_PROMPT;
|
|
177928
178043
|
var init_memory_migration = __esm(async () => {
|
|
178044
|
+
init_language_directive();
|
|
177929
178045
|
init_shared();
|
|
177930
178046
|
init_assistant_message_extractor();
|
|
177931
178047
|
init_logger();
|
|
@@ -178042,6 +178158,7 @@ function buildRecompDeps(ctx, sessionId) {
|
|
|
178042
178158
|
memoryEnabled: ctx.memoryEnabled,
|
|
178043
178159
|
autoPromote: ctx.autoPromote,
|
|
178044
178160
|
fallbackModels: ctx.fallbackModels,
|
|
178161
|
+
language: ctx.language,
|
|
178045
178162
|
fallbackModelId: ctx.fallbackModelId ?? resolveLiveModelKey(ctx.liveSessionState, sessionId),
|
|
178046
178163
|
historianTwoPass: ctx.historianTwoPass,
|
|
178047
178164
|
ensureProjectRegistered: ctx.ensureProjectRegistered,
|
|
@@ -178173,7 +178290,8 @@ async function runUpgradeMemoryMigration(ctx, sessionId, migrationDirectory) {
|
|
|
178173
178290
|
primaryModelId: ctx.fallbackModelId ?? resolveLiveModelKey(ctx.liveSessionState, sessionId),
|
|
178174
178291
|
fallbackModels: ctx.fallbackModels,
|
|
178175
178292
|
timeoutMs: ctx.historianTimeoutMs,
|
|
178176
|
-
userMemoriesEnabled: ctx.userMemoriesEnabled
|
|
178293
|
+
userMemoriesEnabled: ctx.userMemoriesEnabled,
|
|
178294
|
+
language: ctx.language
|
|
178177
178295
|
});
|
|
178178
178296
|
return outcome.summary;
|
|
178179
178297
|
} catch (error51) {
|
|
@@ -178258,15 +178376,12 @@ function shouldShowAnnouncement() {
|
|
|
178258
178376
|
}
|
|
178259
178377
|
return ordering > 0;
|
|
178260
178378
|
}
|
|
178261
|
-
var ANNOUNCEMENT_VERSION = "0.
|
|
178379
|
+
var ANNOUNCEMENT_VERSION = "0.28.0", ANNOUNCEMENT_FEATURES, ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/F2uWxjGnU", STATE_FILENAME = "last_announced_version";
|
|
178262
178380
|
var init_announcement = __esm(() => {
|
|
178263
178381
|
init_data_path();
|
|
178264
178382
|
ANNOUNCEMENT_FEATURES = [
|
|
178265
|
-
|
|
178266
|
-
"
|
|
178267
|
-
"New Primers: durable answers to the questions that keep coming up about your project, kept current by the dreamer investigating the actual code.",
|
|
178268
|
-
"Embedding storage no longer wipes your vectors when you change model or endpoint. Different models now coexist, so switching providers keeps your existing vectors.",
|
|
178269
|
-
"Config moved to a shared CortexKit location (~/.config/cortexkit/ and <project>/.cortexkit/). This happens automatically on first run; your old file is preserved."
|
|
178383
|
+
`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.`,
|
|
178384
|
+
"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."
|
|
178270
178385
|
];
|
|
178271
178386
|
});
|
|
178272
178387
|
|
|
@@ -178441,6 +178556,9 @@ function buildHiddenAgentConfig(prompt, allowedTools, maxSteps, overrides, agent
|
|
|
178441
178556
|
};
|
|
178442
178557
|
}
|
|
178443
178558
|
|
|
178559
|
+
// src/index.ts
|
|
178560
|
+
init_language_directive();
|
|
178561
|
+
|
|
178444
178562
|
// src/config/index.ts
|
|
178445
178563
|
init_jsonc_parser();
|
|
178446
178564
|
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "node:fs";
|
|
@@ -179189,6 +179307,10 @@ function stripUnsafeProjectConfigFields(projectRaw) {
|
|
|
179189
179307
|
delete projectRaw.auto_update;
|
|
179190
179308
|
warnings.push("Ignoring auto_update from project config (security: this setting only honors user-level config).");
|
|
179191
179309
|
}
|
|
179310
|
+
if ("language" in projectRaw) {
|
|
179311
|
+
delete projectRaw.language;
|
|
179312
|
+
warnings.push("Ignoring language from project config (security: output language is a user-level setting).");
|
|
179313
|
+
}
|
|
179192
179314
|
if ("sqlite" in projectRaw) {
|
|
179193
179315
|
delete projectRaw.sqlite;
|
|
179194
179316
|
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).");
|
|
@@ -180021,6 +180143,9 @@ function buildDreamTaskPrompt(task, args) {
|
|
|
180021
180143
|
// src/index.ts
|
|
180022
180144
|
init_project_identity();
|
|
180023
180145
|
|
|
180146
|
+
// src/features/magic-context/sidekick/agent.ts
|
|
180147
|
+
init_language_directive();
|
|
180148
|
+
|
|
180024
180149
|
// src/agents/sidekick.ts
|
|
180025
180150
|
var SIDEKICK_AGENT = "sidekick";
|
|
180026
180151
|
|
|
@@ -180088,12 +180213,13 @@ async function runSidekick(deps) {
|
|
|
180088
180213
|
throw error51;
|
|
180089
180214
|
}
|
|
180090
180215
|
const childSessionId = agentSessionId;
|
|
180216
|
+
const systemPrompt = withContentLanguageDirective(deps.config.system_prompt?.trim() || deps.config.prompt?.trim() || SIDEKICK_SYSTEM_PROMPT, deps.language);
|
|
180091
180217
|
const sidekickRun = await promptSyncWithValidatedOutputRetry(deps.client, {
|
|
180092
180218
|
path: { id: childSessionId },
|
|
180093
180219
|
query: { directory: deps.sessionDirectory ?? deps.projectPath },
|
|
180094
180220
|
body: {
|
|
180095
180221
|
agent: SIDEKICK_AGENT,
|
|
180096
|
-
system:
|
|
180222
|
+
system: systemPrompt,
|
|
180097
180223
|
parts: [{ type: "text", text: deps.userMessage, synthetic: true }]
|
|
180098
180224
|
}
|
|
180099
180225
|
}, {
|
|
@@ -181066,6 +181192,7 @@ var DREAMER_DOCS_AGENT = "dreamer-docs";
|
|
|
181066
181192
|
var DREAMER_REVIEWER_AGENT = "dreamer-reviewer";
|
|
181067
181193
|
|
|
181068
181194
|
// src/features/magic-context/dreamer/task-executor.ts
|
|
181195
|
+
init_language_directive();
|
|
181069
181196
|
init_shared();
|
|
181070
181197
|
init_assistant_message_extractor();
|
|
181071
181198
|
init_logger();
|
|
@@ -181074,6 +181201,7 @@ init_memory();
|
|
|
181074
181201
|
init_subagent_token_capture();
|
|
181075
181202
|
|
|
181076
181203
|
// src/features/magic-context/user-memory/review-user-memories.ts
|
|
181204
|
+
init_language_directive();
|
|
181077
181205
|
init_shared();
|
|
181078
181206
|
init_assistant_message_extractor();
|
|
181079
181207
|
init_logger();
|
|
@@ -181188,7 +181316,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
181188
181316
|
query: { directory: args.sessionDirectory },
|
|
181189
181317
|
body: {
|
|
181190
181318
|
agent: DREAMER_REVIEWER_AGENT,
|
|
181191
|
-
system: REVIEW_USER_MEMORIES_SYSTEM_PROMPT,
|
|
181319
|
+
system: withContentLanguageDirective(REVIEW_USER_MEMORIES_SYSTEM_PROMPT, args.language),
|
|
181192
181320
|
...modelBodyField(args.model),
|
|
181193
181321
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
181194
181322
|
}
|
|
@@ -183772,6 +183900,7 @@ async function promotePrimers(args) {
|
|
|
183772
183900
|
}
|
|
183773
183901
|
|
|
183774
183902
|
// src/features/magic-context/dreamer/refresh-primers.ts
|
|
183903
|
+
init_language_directive();
|
|
183775
183904
|
init_read_session_formatting();
|
|
183776
183905
|
init_shared();
|
|
183777
183906
|
init_assistant_message_extractor();
|
|
@@ -184010,7 +184139,7 @@ async function refreshOnePrimer(args, primer, sliceMs, signal) {
|
|
|
184010
184139
|
query: { directory: args.sessionDirectory },
|
|
184011
184140
|
body: {
|
|
184012
184141
|
agent: DREAMER_PRIMER_INVESTIGATOR_AGENT,
|
|
184013
|
-
system: PRIMER_INVESTIGATOR_SYSTEM_PROMPT,
|
|
184142
|
+
system: withContentLanguageDirective(PRIMER_INVESTIGATOR_SYSTEM_PROMPT, args.language),
|
|
184014
184143
|
...modelBodyField(args.model),
|
|
184015
184144
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
184016
184145
|
}
|
|
@@ -184246,6 +184375,7 @@ function insertDreamRun(db, run) {
|
|
|
184246
184375
|
init_task_registry();
|
|
184247
184376
|
|
|
184248
184377
|
// src/features/magic-context/dreamer/verify.ts
|
|
184378
|
+
init_language_directive();
|
|
184249
184379
|
init_shared();
|
|
184250
184380
|
init_assistant_message_extractor();
|
|
184251
184381
|
init_logger();
|
|
@@ -184473,7 +184603,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
184473
184603
|
query: { directory: args.sessionDirectory },
|
|
184474
184604
|
body: {
|
|
184475
184605
|
agent: DREAMER_MEMORY_MAPPER_AGENT,
|
|
184476
|
-
system: VERIFY_SYSTEM_PROMPT,
|
|
184606
|
+
system: withContentLanguageDirective(VERIFY_SYSTEM_PROMPT, args.language),
|
|
184477
184607
|
...modelBodyField(args.model),
|
|
184478
184608
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
184479
184609
|
}
|
|
@@ -184753,7 +184883,8 @@ function createDreamTaskExecutor(deps) {
|
|
|
184753
184883
|
deadline,
|
|
184754
184884
|
promotionThreshold: config2.promotionThreshold ?? 3,
|
|
184755
184885
|
model: config2.model,
|
|
184756
|
-
fallbackModels: config2.fallbackModels
|
|
184886
|
+
fallbackModels: config2.fallbackModels,
|
|
184887
|
+
language: config2.language ?? deps.language
|
|
184757
184888
|
});
|
|
184758
184889
|
recordRun("completed", null);
|
|
184759
184890
|
log(`[dreamer] review-user-memories: promoted=${result.promoted} merged=${result.merged} dismissed=${result.dismissed}`);
|
|
@@ -184789,7 +184920,8 @@ function createDreamTaskExecutor(deps) {
|
|
|
184789
184920
|
deadline,
|
|
184790
184921
|
forceBroad: config2.task === "verify-broad",
|
|
184791
184922
|
model: config2.model,
|
|
184792
|
-
fallbackModels: config2.fallbackModels
|
|
184923
|
+
fallbackModels: config2.fallbackModels,
|
|
184924
|
+
language: config2.language ?? deps.language
|
|
184793
184925
|
});
|
|
184794
184926
|
recordRun("completed", null, {
|
|
184795
184927
|
memoryChanges: computeMemoryDelta(memoryBefore)
|
|
@@ -184841,6 +184973,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
184841
184973
|
deadline,
|
|
184842
184974
|
model: config2.model,
|
|
184843
184975
|
fallbackModels: config2.fallbackModels,
|
|
184976
|
+
language: config2.language ?? deps.language,
|
|
184844
184977
|
rawProviderFactory: deps.primerRawProviderFactory
|
|
184845
184978
|
});
|
|
184846
184979
|
recordRun("completed", null);
|
|
@@ -184958,6 +185091,7 @@ function retrospectiveEventsForSessions(db, sessionIds) {
|
|
|
184958
185091
|
try {
|
|
184959
185092
|
for (const event of getCompartmentEvents(db, sessionId)) {
|
|
184960
185093
|
if (event.kind !== "causal_incident" && event.kind !== "trajectory_correction") {
|
|
185094
|
+
log(`[dreamer] dropping event: unknown kind="${event.kind}"`);
|
|
184961
185095
|
continue;
|
|
184962
185096
|
}
|
|
184963
185097
|
events.push({
|
|
@@ -185082,7 +185216,9 @@ async function runRetrospectiveTask(config2, ctx, helpers) {
|
|
|
185082
185216
|
const frictionWindow = renderFrictionWindow(messages, flagged.map((message) => message.ordinal));
|
|
185083
185217
|
const eventSessionIds = new Set(messages.map((message) => message.sessionId));
|
|
185084
185218
|
const events = retrospectiveEventsForSessions(db, eventSessionIds);
|
|
185085
|
-
const deepenRun = await runChildTurn(RETROSPECTIVE_SYSTEM_PROMPT,
|
|
185219
|
+
const deepenRun = await runChildTurn(withContentLanguageDirective(RETROSPECTIVE_SYSTEM_PROMPT, config2.language ?? deps.language, {
|
|
185220
|
+
retrospective: true
|
|
185221
|
+
}), buildRetrospectivePrompt({ projectPath: projectIdentity, frictionWindow, events }));
|
|
185086
185222
|
if (leaseLost)
|
|
185087
185223
|
throw new Error("Dream lease lost during retrospective");
|
|
185088
185224
|
const sourceSessionId = flagged[0]?.sessionId ?? userMessages[0]?.sessionId ?? "retrospective";
|
|
@@ -185168,7 +185304,7 @@ async function runAgenticTask(config2, ctx, helpers) {
|
|
|
185168
185304
|
query: { directory: docsDir },
|
|
185169
185305
|
body: {
|
|
185170
185306
|
agent: task === "maintain-docs" ? DREAMER_DOCS_AGENT : DREAMER_AGENT,
|
|
185171
|
-
system: task === "maintain-docs" ? MAINTAIN_DOCS_SYSTEM_PROMPT : CURATE_SYSTEM_PROMPT,
|
|
185307
|
+
system: task === "maintain-docs" ? MAINTAIN_DOCS_SYSTEM_PROMPT : withContentLanguageDirective(CURATE_SYSTEM_PROMPT, config2.language ?? deps.language),
|
|
185172
185308
|
...modelBodyField(config2.model),
|
|
185173
185309
|
parts: [{ type: "text", text: taskPrompt, synthetic: true }]
|
|
185174
185310
|
}
|
|
@@ -185990,7 +186126,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
|
|
|
185990
186126
|
}
|
|
185991
186127
|
try {
|
|
185992
186128
|
await runCompiledSmartNoteSweep(reg, db);
|
|
185993
|
-
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreamerConfig);
|
|
186129
|
+
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreamerConfig, reg.language);
|
|
185994
186130
|
const executor = createDreamTaskExecutor({
|
|
185995
186131
|
client: reg.client,
|
|
185996
186132
|
sessionDirectory: reg.directory,
|
|
@@ -185998,7 +186134,8 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
|
|
|
185998
186134
|
retrospectiveRawProvider: reg.retrospectiveRawProvider ?? ((db2) => new OpenCodeRetrospectiveRawProvider({ contextDb: db2, openOpenCodeDb })),
|
|
185999
186135
|
primerRawProviderFactory: reg.primerRawProviderFactory,
|
|
186000
186136
|
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreamerConfig),
|
|
186001
|
-
ensureProjectRegistered: reg.ensureRegistered
|
|
186137
|
+
ensureProjectRegistered: reg.ensureRegistered,
|
|
186138
|
+
language: reg.language
|
|
186002
186139
|
});
|
|
186003
186140
|
const ran = await runDueTasksForProject({
|
|
186004
186141
|
db,
|
|
@@ -187361,7 +187498,8 @@ Provide a prompt to augment with project memory context.`, {});
|
|
|
187361
187498
|
projectPath: deps.sidekick.projectPath,
|
|
187362
187499
|
sessionDirectory: deps.sidekick.sessionDirectory,
|
|
187363
187500
|
userMessage: prompt,
|
|
187364
|
-
config: deps.sidekick.config
|
|
187501
|
+
config: deps.sidekick.config,
|
|
187502
|
+
language: deps.sidekick.language
|
|
187365
187503
|
});
|
|
187366
187504
|
let augmentedPrompt;
|
|
187367
187505
|
if (sidekickResult) {
|
|
@@ -187839,6 +187977,7 @@ var pendingPiDecisionBySession = new Map;
|
|
|
187839
187977
|
var lastBoundMessageIdBySession = new Map;
|
|
187840
187978
|
var scheduledWriteTokensBySession = new Map;
|
|
187841
187979
|
var writerOverrideForTests = null;
|
|
187980
|
+
var retentionOverrideForTests = null;
|
|
187842
187981
|
function normalizeMaterializeReason(harness, reason, rematerialized) {
|
|
187843
187982
|
const raw = typeof reason === "string" ? reason.trim() : "";
|
|
187844
187983
|
if (raw.length > 0) {
|
|
@@ -187939,7 +188078,7 @@ function writeTransformDecisionRow(dbPath, row) {
|
|
|
187939
188078
|
WHERE session_id = ? AND harness = ?
|
|
187940
188079
|
ORDER BY ts_ms DESC, rowid DESC
|
|
187941
188080
|
LIMIT ?
|
|
187942
|
-
)`).run(row.sessionId, row.harness, row.sessionId, row.harness, TRANSFORM_DECISIONS_RETENTION);
|
|
188081
|
+
)`).run(row.sessionId, row.harness, row.sessionId, row.harness, retentionOverrideForTests ?? TRANSFORM_DECISIONS_RETENTION);
|
|
187943
188082
|
} finally {
|
|
187944
188083
|
closeQuietly(db);
|
|
187945
188084
|
}
|
|
@@ -187967,6 +188106,7 @@ function channel1RefireTokens(workingWindowTokens) {
|
|
|
187967
188106
|
var S_GENTLE = 0.2;
|
|
187968
188107
|
var S_FIRM = 0.4;
|
|
187969
188108
|
var S_URGENT = 0.65;
|
|
188109
|
+
var CHANNEL1_PRESSURE_FLOOR = 0.8;
|
|
187970
188110
|
var LEVEL_RANK = { gentle: 1, firm: 2, urgent: 3 };
|
|
187971
188111
|
var DROP_SENTINELS = ["[dropped", "[truncated"];
|
|
187972
188112
|
function isDroppedToolOutput(output) {
|
|
@@ -188031,7 +188171,8 @@ function computeTailTokenEstimate(messages) {
|
|
|
188031
188171
|
};
|
|
188032
188172
|
}
|
|
188033
188173
|
function decideChannel1(input) {
|
|
188034
|
-
const { undroppedTokens,
|
|
188174
|
+
const { undroppedTokens, workingWindowTokens, hasRecentReduce } = input;
|
|
188175
|
+
const pressure = Math.min(1, Math.max(0, input.pressure));
|
|
188035
188176
|
const resetCycle = hasRecentReduce || undroppedTokens < input.lastNudgeUndropped;
|
|
188036
188177
|
const lastNudge = resetCycle ? 0 : input.lastNudgeUndropped;
|
|
188037
188178
|
const lastLevel = resetCycle ? "" : input.lastNudgeLevel;
|
|
@@ -188046,8 +188187,10 @@ function decideChannel1(input) {
|
|
|
188046
188187
|
return quiet();
|
|
188047
188188
|
if (undroppedTokens < CHANNEL1_FLOOR_TOKENS)
|
|
188048
188189
|
return quiet();
|
|
188049
|
-
|
|
188050
|
-
|
|
188190
|
+
if (pressure < CHANNEL1_PRESSURE_FLOOR)
|
|
188191
|
+
return quiet();
|
|
188192
|
+
const denom = Math.max(input.estimatedInputTokens, 1);
|
|
188193
|
+
const severity = Math.min(1, undroppedTokens / denom);
|
|
188051
188194
|
if (severity < S_GENTLE)
|
|
188052
188195
|
return quiet();
|
|
188053
188196
|
let level;
|
|
@@ -188348,6 +188491,7 @@ init_session_project_storage();
|
|
|
188348
188491
|
init_storage_meta_persisted();
|
|
188349
188492
|
await init_storage();
|
|
188350
188493
|
init_logger();
|
|
188494
|
+
init_models_dev_cache();
|
|
188351
188495
|
|
|
188352
188496
|
// src/hooks/magic-context/boundary-execution.ts
|
|
188353
188497
|
var FORCE_MATERIALIZE_PERCENTAGE2 = 85;
|
|
@@ -192487,6 +192631,18 @@ function findLastAssistantModel2(messages) {
|
|
|
192487
192631
|
}
|
|
192488
192632
|
return null;
|
|
192489
192633
|
}
|
|
192634
|
+
function findNewestUserModel(messages) {
|
|
192635
|
+
for (let i = messages.length - 1;i >= 0; i--) {
|
|
192636
|
+
const info = messages[i].info;
|
|
192637
|
+
if (info.role !== "user")
|
|
192638
|
+
continue;
|
|
192639
|
+
if (info.model?.providerID && info.model.modelID) {
|
|
192640
|
+
return { providerID: info.model.providerID, modelID: info.model.modelID };
|
|
192641
|
+
}
|
|
192642
|
+
return null;
|
|
192643
|
+
}
|
|
192644
|
+
return null;
|
|
192645
|
+
}
|
|
192490
192646
|
function createTransform(deps) {
|
|
192491
192647
|
const loadedSessions = new Set;
|
|
192492
192648
|
const lastEmergencyNotificationCount = new Map;
|
|
@@ -192547,15 +192703,15 @@ function createTransform(deps) {
|
|
|
192547
192703
|
const canRunCompartments = fullFeatureMode && historianRunnable && deps.client !== undefined && compartmentDirectory.length > 0;
|
|
192548
192704
|
const fallbackModelId = deps.getFallbackModelId?.(sessionId);
|
|
192549
192705
|
const tModelDetect = performance.now();
|
|
192706
|
+
const persistedUsageBeforeResets = loadPersistedUsage(db, sessionId);
|
|
192550
192707
|
if (deps.liveModelBySession) {
|
|
192551
|
-
const
|
|
192552
|
-
if (
|
|
192553
|
-
|
|
192554
|
-
|
|
192555
|
-
|
|
192556
|
-
|
|
192557
|
-
sessionLog(sessionId, `transform: model change
|
|
192558
|
-
deps.liveModelBySession.set(sessionId, lastAssistantModel);
|
|
192708
|
+
const currentOutgoingModel = findNewestUserModel(messages) ?? deps.liveModelBySession.get(sessionId) ?? findLastAssistantModel2(messages);
|
|
192709
|
+
if (currentOutgoingModel) {
|
|
192710
|
+
deps.liveModelBySession.set(sessionId, currentOutgoingModel);
|
|
192711
|
+
const outgoingModelKey = resolveModelKey(currentOutgoingModel.providerID, currentOutgoingModel.modelID);
|
|
192712
|
+
const lastUsageModelKey = persistedUsageBeforeResets?.lastObservedModelKey ?? null;
|
|
192713
|
+
if (lastUsageModelKey != null && outgoingModelKey != null && lastUsageModelKey !== outgoingModelKey) {
|
|
192714
|
+
sessionLog(sessionId, `transform: model change since last usage (${lastUsageModelKey} -> ${outgoingModelKey}), clearing stale per-model state`);
|
|
192559
192715
|
updateSessionMeta(db, sessionId, {
|
|
192560
192716
|
lastContextPercentage: 0,
|
|
192561
192717
|
lastInputTokens: 0,
|
|
@@ -192585,7 +192741,6 @@ function createTransform(deps) {
|
|
|
192585
192741
|
const tFirstPass = performance.now();
|
|
192586
192742
|
const isFirstTransformPassForSession = !loadedSessions.has(sessionId);
|
|
192587
192743
|
loadedSessions.add(sessionId);
|
|
192588
|
-
const persistedUsageBeforeFirstPassReset = loadPersistedUsage(db, sessionId);
|
|
192589
192744
|
const historianFailureState = getHistorianFailureState(db, sessionId);
|
|
192590
192745
|
if (isFirstTransformPassForSession && sessionMeta) {
|
|
192591
192746
|
const persistedPct = sessionMeta.lastContextPercentage ?? 0;
|
|
@@ -192604,6 +192759,17 @@ function createTransform(deps) {
|
|
|
192604
192759
|
let emergencyRecoveryArmed = false;
|
|
192605
192760
|
if (fullFeatureMode) {
|
|
192606
192761
|
try {
|
|
192762
|
+
const armModel = deps.liveModelBySession?.get(sessionId);
|
|
192763
|
+
const armModelKey = deps.getModelKey?.(sessionId);
|
|
192764
|
+
const armSnapshot = persistedUsageBeforeResets;
|
|
192765
|
+
const lastMeasuredInput = armSnapshot?.usage.inputTokens ?? sessionMeta?.lastInputTokens ?? 0;
|
|
192766
|
+
const lastMeasuredModelKey = armSnapshot?.lastObservedModelKey ?? null;
|
|
192767
|
+
const armCatalogLimit = armModel ? getSdkContextLimit(armModel.providerID, armModel.modelID) : undefined;
|
|
192768
|
+
if (!sessionMeta?.isSubagent && armModel && typeof armCatalogLimit === "number" && armCatalogLimit > 0 && lastMeasuredInput > armCatalogLimit && lastMeasuredModelKey != null && armModelKey != null && lastMeasuredModelKey !== armModelKey && !getOverflowState(db, sessionId).needsEmergencyRecovery) {
|
|
192769
|
+
sessionLog(sessionId, `transform: last input ${lastMeasuredInput} (model ${lastMeasuredModelKey}) exceeds new model ${armModelKey} catalog limit ${armCatalogLimit}; arming overflow recovery proactively for the shrinking switch`);
|
|
192770
|
+
recordOverflowDetected(db, sessionId, undefined, armModelKey);
|
|
192771
|
+
resetProtectedTailNoEligibleHead(db, sessionId);
|
|
192772
|
+
}
|
|
192607
192773
|
const overflowState = getOverflowState(db, sessionId);
|
|
192608
192774
|
emergencyRecoveryArmed = overflowState.needsEmergencyRecovery;
|
|
192609
192775
|
if (contextUsageEarly.percentage < 80 && !overflowState.needsEmergencyRecovery) {
|
|
@@ -192640,7 +192806,7 @@ function createTransform(deps) {
|
|
|
192640
192806
|
sessionID: sessionId
|
|
192641
192807
|
}) : undefined;
|
|
192642
192808
|
const currentModelKeyForBoundary = deps.getModelKey?.(sessionId);
|
|
192643
|
-
const persistedUsageFreshForBoundary =
|
|
192809
|
+
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;
|
|
192644
192810
|
const boundaryUsageForProtectedTail = persistedUsageFreshForBoundary ?? contextUsageEarly;
|
|
192645
192811
|
const boundaryUsageSource = persistedUsageFreshForBoundary ? "persisted" : "live";
|
|
192646
192812
|
const historyBudgetTokens = resolveHistoryBudgetTokens(deps.historyBudgetPercentage, contextUsageEarly, deps.executeThresholdPercentage, deps.getModelKey?.(sessionId), deps.executeThresholdTokens, resolvedContextLimit);
|
|
@@ -193901,6 +194067,7 @@ function maybeInjectChannel1Nudge(args, sessionId, tool, output) {
|
|
|
193901
194067
|
const decision = decideChannel1({
|
|
193902
194068
|
undroppedTokens,
|
|
193903
194069
|
pressure,
|
|
194070
|
+
estimatedInputTokens: state.lastInputTokens + state.turnToolTokens,
|
|
193904
194071
|
workingWindowTokens,
|
|
193905
194072
|
lastNudgeUndropped: getLastNudgeUndropped(args.db, sessionId),
|
|
193906
194073
|
lastNudgeLevel: getLastNudgeLevel(args.db, sessionId),
|
|
@@ -193966,6 +194133,7 @@ init_send_session_notification();
|
|
|
193966
194133
|
import { createHash as createHash13 } from "node:crypto";
|
|
193967
194134
|
|
|
193968
194135
|
// src/agents/magic-context-prompt.ts
|
|
194136
|
+
init_language_directive();
|
|
193969
194137
|
var LONG_TERM_PARTNER_FRAME = `### You are the user's long-term partner on this project — not a one-off hire
|
|
193970
194138
|
|
|
193971
194139
|
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.
|
|
@@ -194044,7 +194212,7 @@ Drop silently — do not narrate it. NEVER drop large ranges blindly (e.g., "1-5
|
|
|
194044
194212
|
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.`;
|
|
194045
194213
|
var CAVEMAN_COMPRESSION_WARNING = `
|
|
194046
194214
|
**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.`;
|
|
194047
|
-
function buildMagicContextSection(_agent, protectedTags, ctxReduceEnabled = true, dreamerEnabled = false, temporalAwarenessEnabled = false, cavemanTextCompressionEnabled = false, subagentMode = false) {
|
|
194215
|
+
function buildMagicContextSection(_agent, protectedTags, ctxReduceEnabled = true, dreamerEnabled = false, temporalAwarenessEnabled = false, cavemanTextCompressionEnabled = false, subagentMode = false, language) {
|
|
194048
194216
|
if (subagentMode) {
|
|
194049
194217
|
return `## Magic Context
|
|
194050
194218
|
|
|
@@ -194056,13 +194224,17 @@ The dreamer evaluates smart note conditions during nightly runs and surfaces the
|
|
|
194056
194224
|
Example: \`ctx_note(action="write", content="Implement X because Y", surface_condition="When PR #42 is merged in this repo")\`` : "";
|
|
194057
194225
|
const temporalGuidance = temporalAwarenessEnabled ? TEMPORAL_AWARENESS_GUIDANCE : "";
|
|
194058
194226
|
const cavemanWarning = cavemanTextCompressionEnabled && !ctxReduceEnabled ? CAVEMAN_COMPRESSION_WARNING : "";
|
|
194227
|
+
const languageDirective = buildPrimaryLanguageDirective(language);
|
|
194228
|
+
const languageGuidance = languageDirective ? `
|
|
194229
|
+
|
|
194230
|
+
${languageDirective}` : "";
|
|
194059
194231
|
if (!ctxReduceEnabled) {
|
|
194060
194232
|
return `## Magic Context
|
|
194061
194233
|
|
|
194062
194234
|
${LONG_TERM_PARTNER_FRAME}
|
|
194063
194235
|
${PARTNER_FRAME_CLOSER_NO_REDUCE}
|
|
194064
194236
|
|
|
194065
|
-
${BASE_INTRO_NO_REDUCE()}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}`;
|
|
194237
|
+
${BASE_INTRO_NO_REDUCE()}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
|
|
194066
194238
|
}
|
|
194067
194239
|
return `## Magic Context
|
|
194068
194240
|
|
|
@@ -194072,7 +194244,7 @@ ${PARTNER_FRAME_CLOSER_REDUCE}
|
|
|
194072
194244
|
${BASE_INTRO(protectedTags)}${smartNoteGuidance}${temporalGuidance}
|
|
194073
194245
|
${GENERIC_SECTION}
|
|
194074
194246
|
|
|
194075
|
-
Prefer many small targeted operations over one large blanket operation, and keep the working set tidy as routine maintenance
|
|
194247
|
+
Prefer many small targeted operations over one large blanket operation, and keep the working set tidy as routine maintenance.${languageGuidance}`;
|
|
194076
194248
|
}
|
|
194077
194249
|
|
|
194078
194250
|
// src/hooks/magic-context/system-prompt-hash.ts
|
|
@@ -194130,7 +194302,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
194130
194302
|
const fullPrompt = output.system.join(`
|
|
194131
194303
|
`);
|
|
194132
194304
|
if (fullPrompt.length > 0 && !fullPrompt.includes(MAGIC_CONTEXT_MARKER) && !skipGuidanceForDisabledSubagent) {
|
|
194133
|
-
const guidance = buildMagicContextSection(null, deps.protectedTags, effectiveCtxReduceEnabled, deps.dreamerEnabled, deps.experimentalTemporalAwareness, deps.experimentalCavemanTextCompression, subagentReduceMode);
|
|
194305
|
+
const guidance = buildMagicContextSection(null, deps.protectedTags, effectiveCtxReduceEnabled, deps.dreamerEnabled, deps.experimentalTemporalAwareness, deps.experimentalCavemanTextCompression, subagentReduceMode, deps.language);
|
|
194134
194306
|
output.system.push(guidance);
|
|
194135
194307
|
sessionLog(sessionId, `injected generic guidance into system prompt (ctxReduce=${effectiveCtxReduceEnabled}, subagent=${isSubagentSession}, subagentReduceMode=${subagentReduceMode})`);
|
|
194136
194308
|
}
|
|
@@ -194418,6 +194590,7 @@ function createMagicContextHook(deps) {
|
|
|
194418
194590
|
memoryEnabled: deps.config.memory?.enabled ?? true,
|
|
194419
194591
|
autoPromote: deps.config.memory?.auto_promote ?? true,
|
|
194420
194592
|
fallbackModels: historianFallbackModels,
|
|
194593
|
+
language: deps.config.language,
|
|
194421
194594
|
fallbackModelId: (() => {
|
|
194422
194595
|
const model = resolveLiveModel(sessionId);
|
|
194423
194596
|
return model ? `${model.providerID}/${model.modelID}` : undefined;
|
|
@@ -194456,7 +194629,7 @@ function createMagicContextHook(deps) {
|
|
|
194456
194629
|
signal,
|
|
194457
194630
|
onProgress: ({ embedded, total }) => {
|
|
194458
194631
|
const cur = recompProgressBySession.get(sessionId);
|
|
194459
|
-
if (
|
|
194632
|
+
if (cur?.phase !== "recomp")
|
|
194460
194633
|
return;
|
|
194461
194634
|
recompProgressBySession.set(sessionId, {
|
|
194462
194635
|
...cur,
|
|
@@ -194659,7 +194832,7 @@ function createMagicContextHook(deps) {
|
|
|
194659
194832
|
return;
|
|
194660
194833
|
}
|
|
194661
194834
|
lastScheduleCheckMs = now;
|
|
194662
|
-
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreaming);
|
|
194835
|
+
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreaming, deps.config.language);
|
|
194663
194836
|
const executor = createDreamTaskExecutor({
|
|
194664
194837
|
client: deps.client,
|
|
194665
194838
|
sessionDirectory: deps.directory,
|
|
@@ -194668,7 +194841,8 @@ function createMagicContextHook(deps) {
|
|
|
194668
194841
|
contextDb: providerDb,
|
|
194669
194842
|
openOpenCodeDb
|
|
194670
194843
|
}),
|
|
194671
|
-
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreaming)
|
|
194844
|
+
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreaming),
|
|
194845
|
+
language: deps.config.language
|
|
194672
194846
|
});
|
|
194673
194847
|
runDueTasksForProject({
|
|
194674
194848
|
db,
|
|
@@ -194717,7 +194891,8 @@ function createMagicContextHook(deps) {
|
|
|
194717
194891
|
config: sidekickConfig,
|
|
194718
194892
|
projectPath,
|
|
194719
194893
|
sessionDirectory: deps.directory,
|
|
194720
|
-
client: deps.client
|
|
194894
|
+
client: deps.client,
|
|
194895
|
+
language: deps.config.language
|
|
194721
194896
|
} : undefined,
|
|
194722
194897
|
dreamer: dreamerConfig ? {
|
|
194723
194898
|
config: dreamerConfig,
|
|
@@ -194725,7 +194900,7 @@ function createMagicContextHook(deps) {
|
|
|
194725
194900
|
runManual: (task) => runManualDream({
|
|
194726
194901
|
db,
|
|
194727
194902
|
projectIdentity: projectPath,
|
|
194728
|
-
tasks: buildDreamTaskRuntimeConfigs(dreamerConfig),
|
|
194903
|
+
tasks: buildDreamTaskRuntimeConfigs(dreamerConfig, deps.config.language),
|
|
194729
194904
|
executor: createDreamTaskExecutor({
|
|
194730
194905
|
client: deps.client,
|
|
194731
194906
|
sessionDirectory: deps.directory,
|
|
@@ -194734,7 +194909,8 @@ function createMagicContextHook(deps) {
|
|
|
194734
194909
|
contextDb: providerDb,
|
|
194735
194910
|
openOpenCodeDb
|
|
194736
194911
|
}),
|
|
194737
|
-
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreamerConfig)
|
|
194912
|
+
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreamerConfig),
|
|
194913
|
+
language: deps.config.language
|
|
194738
194914
|
}),
|
|
194739
194915
|
task
|
|
194740
194916
|
})
|
|
@@ -194745,6 +194921,7 @@ function createMagicContextHook(deps) {
|
|
|
194745
194921
|
protectedTags: deps.config.protected_tags,
|
|
194746
194922
|
ctxReduceEnabled,
|
|
194747
194923
|
dreamerEnabled: dreamerRunnable,
|
|
194924
|
+
language: deps.config.language,
|
|
194748
194925
|
injectDocs: deps.config.dreamer?.inject_docs !== false,
|
|
194749
194926
|
directory: deps.directory,
|
|
194750
194927
|
historyRefreshSessions,
|
|
@@ -197472,6 +197649,7 @@ var server2 = async (ctx) => {
|
|
|
197472
197649
|
projectIdentity: resolveProjectIdentity(ctx.directory),
|
|
197473
197650
|
client: ctx.client,
|
|
197474
197651
|
dreamerConfig: dreamerRunnable ? pluginConfig.dreamer : undefined,
|
|
197652
|
+
language: pluginConfig.language,
|
|
197475
197653
|
embeddingConfig: pluginConfig.embedding,
|
|
197476
197654
|
memoryEnabled: pluginConfig.memory?.enabled === true,
|
|
197477
197655
|
gitCommitIndexing: pluginConfig.memory.git_commit_indexing?.enabled ? {
|
|
@@ -197623,9 +197801,9 @@ var server2 = async (ctx) => {
|
|
|
197623
197801
|
const registrations = buildHiddenAgentRegistrations({
|
|
197624
197802
|
dreamerPrompt: DREAMER_SYSTEM_PROMPT,
|
|
197625
197803
|
smartNoteCompilerPrompt: SMART_NOTE_COMPILER_SYSTEM_PROMPT,
|
|
197626
|
-
historianPrompt: COMPARTMENT_AGENT_SYSTEM_PROMPT,
|
|
197627
|
-
historianRecompPrompt: COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT,
|
|
197628
|
-
historianEditorPrompt: HISTORIAN_EDITOR_SYSTEM_PROMPT,
|
|
197804
|
+
historianPrompt: withContentLanguageDirective(COMPARTMENT_AGENT_SYSTEM_PROMPT, pluginConfig.language, { preserveUserQuotes: true }),
|
|
197805
|
+
historianRecompPrompt: withContentLanguageDirective(COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, pluginConfig.language, { preserveUserQuotes: true }),
|
|
197806
|
+
historianEditorPrompt: withContentLanguageDirective(HISTORIAN_EDITOR_SYSTEM_PROMPT, pluginConfig.language, { preserveUserQuotes: true }),
|
|
197629
197807
|
sidekickPrompt: SIDEKICK_SYSTEM_PROMPT,
|
|
197630
197808
|
dreamerOverrides: dreamerAgentOverrides,
|
|
197631
197809
|
historianOverrides: historianAgentOverrides,
|