@cortexkit/pi-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/index.js +185 -47
- package/dist/subagent-entry.js +108 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15568,7 +15568,7 @@ function compareTaskOrder(a, b) {
|
|
|
15568
15568
|
}
|
|
15569
15569
|
|
|
15570
15570
|
// ../plugin/src/features/magic-context/dreamer/task-config.ts
|
|
15571
|
-
function buildDreamTaskRuntimeConfigs(dreamer) {
|
|
15571
|
+
function buildDreamTaskRuntimeConfigs(dreamer, language) {
|
|
15572
15572
|
const tasks = dreamer.tasks ?? {};
|
|
15573
15573
|
return CANONICAL_DREAM_TASKS.map((task) => {
|
|
15574
15574
|
const t = tasks[task] ?? {
|
|
@@ -15584,6 +15584,7 @@ function buildDreamTaskRuntimeConfigs(dreamer) {
|
|
|
15584
15584
|
model,
|
|
15585
15585
|
fallbackModels,
|
|
15586
15586
|
thinkingLevel,
|
|
15587
|
+
language,
|
|
15587
15588
|
timeoutMinutes: t.timeout_minutes ?? 20,
|
|
15588
15589
|
promotionThreshold: t.promotion_threshold
|
|
15589
15590
|
};
|
|
@@ -150534,7 +150535,7 @@ function enforceSchemaFence(db, dbPath, latestSupportedVersion) {
|
|
|
150534
150535
|
return true;
|
|
150535
150536
|
}
|
|
150536
150537
|
lastSchemaFenceRejection = { persistedVersion, supportedVersion: latestSupportedVersion };
|
|
150537
|
-
log(`[magic-context] storage fatal: refusing to open ${dbPath}; database schema v${persistedVersion} is newer than this binary supports (max v${latestSupportedVersion}).
|
|
150538
|
+
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.`);
|
|
150538
150539
|
return false;
|
|
150539
150540
|
}
|
|
150540
150541
|
var sqlitePragmaConfig = {
|
|
@@ -155056,6 +155057,9 @@ function getActiveTagTokenAggregate(db, sessionId, protectedTags = 0) {
|
|
|
155056
155057
|
nullCount: row?.null_count ?? 0
|
|
155057
155058
|
};
|
|
155058
155059
|
}
|
|
155060
|
+
var RECLAIM_HINT_EXCLUDED_TOOLS = ["todowrite"];
|
|
155061
|
+
var RECLAIM_HINT_MIN_TOKENS = 250;
|
|
155062
|
+
var RECLAIM_HINT_EXCLUDED_LIST = RECLAIM_HINT_EXCLUDED_TOOLS.map((name2) => `'${name2.replace(/'/g, "''")}'`).join(", ");
|
|
155059
155063
|
function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, limit = 4) {
|
|
155060
155064
|
if (limit <= 0)
|
|
155061
155065
|
return [];
|
|
@@ -155065,10 +155069,18 @@ function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, li
|
|
|
155065
155069
|
WHERE session_id = ? AND status = 'active'
|
|
155066
155070
|
ORDER BY tag_number DESC LIMIT 1 OFFSET ?
|
|
155067
155071
|
)` : "";
|
|
155068
|
-
const
|
|
155072
|
+
const excludeStateTools = RECLAIM_HINT_EXCLUDED_LIST ? `AND (tool_name IS NULL OR tool_name NOT IN (${RECLAIM_HINT_EXCLUDED_LIST}))` : "";
|
|
155073
|
+
const valueFloor = `AND (
|
|
155074
|
+
(token_count IS NULL AND input_token_count IS NULL)
|
|
155075
|
+
OR (COALESCE(token_count, 0) + COALESCE(input_token_count, 0)) >= ?
|
|
155076
|
+
)`;
|
|
155077
|
+
const params = protectedTags > 0 ? [sessionId, RECLAIM_HINT_MIN_TOKENS, sessionId, protectedTags - 1, boundedLimit] : [sessionId, RECLAIM_HINT_MIN_TOKENS, boundedLimit];
|
|
155069
155078
|
const rows = db.prepare(`SELECT tag_number, tool_name
|
|
155070
155079
|
FROM tags
|
|
155071
|
-
WHERE session_id = ? AND status = 'active' AND type = 'tool'
|
|
155080
|
+
WHERE session_id = ? AND status = 'active' AND type = 'tool'
|
|
155081
|
+
${excludeStateTools}
|
|
155082
|
+
${valueFloor}
|
|
155083
|
+
${whereProtected}
|
|
155072
155084
|
ORDER BY tag_number ASC, id ASC
|
|
155073
155085
|
LIMIT ?`).all(...params);
|
|
155074
155086
|
return rows.filter((row) => typeof row.tag_number === "number").map((row) => ({
|
|
@@ -156335,13 +156347,10 @@ function compareSemverCore(a, b) {
|
|
|
156335
156347
|
|
|
156336
156348
|
// ../plugin/src/shared/announcement.ts
|
|
156337
156349
|
init_data_path();
|
|
156338
|
-
var ANNOUNCEMENT_VERSION = "0.
|
|
156350
|
+
var ANNOUNCEMENT_VERSION = "0.28.0";
|
|
156339
156351
|
var ANNOUNCEMENT_FEATURES = [
|
|
156340
|
-
|
|
156341
|
-
"
|
|
156342
|
-
"New Primers: durable answers to the questions that keep coming up about your project, kept current by the dreamer investigating the actual code.",
|
|
156343
|
-
"Embedding storage no longer wipes your vectors when you change model or endpoint. Different models now coexist, so switching providers keeps your existing vectors.",
|
|
156344
|
-
"Config moved to a shared CortexKit location (~/.config/cortexkit/ and <project>/.cortexkit/). This happens automatically on first run; your old file is preserved."
|
|
156352
|
+
`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.`,
|
|
156353
|
+
"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."
|
|
156345
156354
|
];
|
|
156346
156355
|
var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/F2uWxjGnU";
|
|
156347
156356
|
var STATE_FILENAME = "last_announced_version";
|
|
@@ -156403,6 +156412,95 @@ function shouldKeepSubagents() {
|
|
|
156403
156412
|
// src/index.ts
|
|
156404
156413
|
init_logger();
|
|
156405
156414
|
|
|
156415
|
+
// ../plugin/src/agents/language-directive.ts
|
|
156416
|
+
var ENGLISH_LANGUAGE_NAMES = new Intl.DisplayNames(["en"], {
|
|
156417
|
+
type: "language",
|
|
156418
|
+
fallback: "none"
|
|
156419
|
+
});
|
|
156420
|
+
function resolveLanguageName(language) {
|
|
156421
|
+
const code = typeof language === "string" ? language.trim().toLowerCase() : "";
|
|
156422
|
+
if (!/^[a-z]{2}$/.test(code))
|
|
156423
|
+
return "";
|
|
156424
|
+
let english;
|
|
156425
|
+
try {
|
|
156426
|
+
english = ENGLISH_LANGUAGE_NAMES.of(code) ?? undefined;
|
|
156427
|
+
} catch {
|
|
156428
|
+
return "";
|
|
156429
|
+
}
|
|
156430
|
+
if (!english)
|
|
156431
|
+
return "";
|
|
156432
|
+
let endonym;
|
|
156433
|
+
try {
|
|
156434
|
+
endonym = new Intl.DisplayNames([code], { type: "language", fallback: "none" }).of(code) ?? undefined;
|
|
156435
|
+
} catch {
|
|
156436
|
+
endonym = undefined;
|
|
156437
|
+
}
|
|
156438
|
+
return endonym && endonym !== english ? `${english} (${endonym})` : english;
|
|
156439
|
+
}
|
|
156440
|
+
function isValidLanguageCode(language) {
|
|
156441
|
+
return resolveLanguageName(language) !== "";
|
|
156442
|
+
}
|
|
156443
|
+
function buildContentLanguageDirective(language, options = {}) {
|
|
156444
|
+
const target = resolveLanguageName(language);
|
|
156445
|
+
if (!target)
|
|
156446
|
+
return "";
|
|
156447
|
+
const lines = [
|
|
156448
|
+
"## Output language",
|
|
156449
|
+
"",
|
|
156450
|
+
`Write human-readable prose you author in: ${target}.`,
|
|
156451
|
+
"",
|
|
156452
|
+
"Do not translate or rename structural tokens. Copy required output schemas exactly:",
|
|
156453
|
+
"- 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.",
|
|
156454
|
+
"- 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.",
|
|
156455
|
+
"- Localize only free-text prose values/content: summaries, memory text, explanations, titles, observations, and answers — unless the prompt says to preserve original wording.",
|
|
156456
|
+
"",
|
|
156457
|
+
"These literal values must remain English when used:",
|
|
156458
|
+
"PROJECT_RULES, ARCHITECTURE, CONSTRAINTS, CONFIG_VALUES, NAMING;",
|
|
156459
|
+
"causal_incident, trajectory_correction;",
|
|
156460
|
+
"feature, design, docs, release, investigation, bug, refactor, infra;",
|
|
156461
|
+
"memory, observation; true, false; No relevant memories found.",
|
|
156462
|
+
"",
|
|
156463
|
+
"Preserve the required output shape. Do not add commentary outside the requested XML/JSON/tool output."
|
|
156464
|
+
];
|
|
156465
|
+
if (options.preserveUserQuotes) {
|
|
156466
|
+
lines.push("", `Preserve U: lines and directly quoted user text in their original source language; write the surrounding summary prose in ${target}.`);
|
|
156467
|
+
}
|
|
156468
|
+
if (options.retrospective) {
|
|
156469
|
+
lines.push("", `Write the lesson text in ${target}; paraphrase source text and never quote the user.`);
|
|
156470
|
+
}
|
|
156471
|
+
return lines.join(`
|
|
156472
|
+
`);
|
|
156473
|
+
}
|
|
156474
|
+
function withContentLanguageDirective(systemPrompt, language, options = {}) {
|
|
156475
|
+
const directive = buildContentLanguageDirective(language, options);
|
|
156476
|
+
return directive ? `${systemPrompt}
|
|
156477
|
+
|
|
156478
|
+
${directive}` : systemPrompt;
|
|
156479
|
+
}
|
|
156480
|
+
function buildMigrationLanguageDirective(language) {
|
|
156481
|
+
const target = resolveLanguageName(language);
|
|
156482
|
+
if (!target)
|
|
156483
|
+
return "";
|
|
156484
|
+
return [
|
|
156485
|
+
"## Output language",
|
|
156486
|
+
"",
|
|
156487
|
+
"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."
|
|
156488
|
+
].join(`
|
|
156489
|
+
`);
|
|
156490
|
+
}
|
|
156491
|
+
function withMigrationLanguageDirective(systemPrompt, language) {
|
|
156492
|
+
const directive = buildMigrationLanguageDirective(language);
|
|
156493
|
+
return directive ? `${systemPrompt}
|
|
156494
|
+
|
|
156495
|
+
${directive}` : systemPrompt;
|
|
156496
|
+
}
|
|
156497
|
+
function buildPrimaryLanguageDirective(language) {
|
|
156498
|
+
const target = resolveLanguageName(language);
|
|
156499
|
+
if (!target)
|
|
156500
|
+
return "";
|
|
156501
|
+
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.`;
|
|
156502
|
+
}
|
|
156503
|
+
|
|
156406
156504
|
// ../plugin/src/features/magic-context/sidekick/core.ts
|
|
156407
156505
|
var SIDEKICK_SYSTEM_PROMPT = `You are Sidekick, a focused memory-retrieval subagent for an AI coding assistant.
|
|
156408
156506
|
|
|
@@ -157123,7 +157221,7 @@ function registerCtxAugCommand(pi, config) {
|
|
|
157123
157221
|
sessionLog(sessionLabel, "/ctx-aug: project identity", projectIdentity);
|
|
157124
157222
|
const result = await runner.run({
|
|
157125
157223
|
agent: "sidekick",
|
|
157126
|
-
systemPrompt: config.systemPrompt ?? SIDEKICK_SYSTEM_PROMPT,
|
|
157224
|
+
systemPrompt: withContentLanguageDirective(config.systemPrompt ?? SIDEKICK_SYSTEM_PROMPT, config.language),
|
|
157127
157225
|
userMessage: prompt,
|
|
157128
157226
|
model: config.model,
|
|
157129
157227
|
fallbackModels: config.fallbackModels,
|
|
@@ -172319,6 +172417,7 @@ var EmbeddingConfigSchema = BaseEmbeddingConfigSchema.transform((data) => {
|
|
|
172319
172417
|
var MagicContextConfigSchema = exports_external.object({
|
|
172320
172418
|
enabled: exports_external.boolean().default(true).describe("Enable magic context (default: true)"),
|
|
172321
172419
|
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."),
|
|
172420
|
+
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."),
|
|
172322
172421
|
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)"),
|
|
172323
172422
|
historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
|
|
172324
172423
|
dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
|
|
@@ -176616,7 +176715,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
176616
176715
|
query: { directory: args.sessionDirectory },
|
|
176617
176716
|
body: {
|
|
176618
176717
|
agent: DREAMER_REVIEWER_AGENT,
|
|
176619
|
-
system: REVIEW_USER_MEMORIES_SYSTEM_PROMPT,
|
|
176718
|
+
system: withContentLanguageDirective(REVIEW_USER_MEMORIES_SYSTEM_PROMPT, args.language),
|
|
176620
176719
|
...modelBodyField(args.model),
|
|
176621
176720
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
176622
176721
|
}
|
|
@@ -179430,7 +179529,7 @@ async function refreshOnePrimer(args, primer, sliceMs, signal) {
|
|
|
179430
179529
|
query: { directory: args.sessionDirectory },
|
|
179431
179530
|
body: {
|
|
179432
179531
|
agent: DREAMER_PRIMER_INVESTIGATOR_AGENT,
|
|
179433
|
-
system: PRIMER_INVESTIGATOR_SYSTEM_PROMPT,
|
|
179532
|
+
system: withContentLanguageDirective(PRIMER_INVESTIGATOR_SYSTEM_PROMPT, args.language),
|
|
179434
179533
|
...modelBodyField(args.model),
|
|
179435
179534
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
179436
179535
|
}
|
|
@@ -180211,7 +180310,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
180211
180310
|
query: { directory: args.sessionDirectory },
|
|
180212
180311
|
body: {
|
|
180213
180312
|
agent: DREAMER_MEMORY_MAPPER_AGENT,
|
|
180214
|
-
system: VERIFY_SYSTEM_PROMPT,
|
|
180313
|
+
system: withContentLanguageDirective(VERIFY_SYSTEM_PROMPT, args.language),
|
|
180215
180314
|
...modelBodyField(args.model),
|
|
180216
180315
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
180217
180316
|
}
|
|
@@ -180491,7 +180590,8 @@ function createDreamTaskExecutor(deps) {
|
|
|
180491
180590
|
deadline,
|
|
180492
180591
|
promotionThreshold: config2.promotionThreshold ?? 3,
|
|
180493
180592
|
model: config2.model,
|
|
180494
|
-
fallbackModels: config2.fallbackModels
|
|
180593
|
+
fallbackModels: config2.fallbackModels,
|
|
180594
|
+
language: config2.language ?? deps.language
|
|
180495
180595
|
});
|
|
180496
180596
|
recordRun("completed", null);
|
|
180497
180597
|
log(`[dreamer] review-user-memories: promoted=${result.promoted} merged=${result.merged} dismissed=${result.dismissed}`);
|
|
@@ -180527,7 +180627,8 @@ function createDreamTaskExecutor(deps) {
|
|
|
180527
180627
|
deadline,
|
|
180528
180628
|
forceBroad: config2.task === "verify-broad",
|
|
180529
180629
|
model: config2.model,
|
|
180530
|
-
fallbackModels: config2.fallbackModels
|
|
180630
|
+
fallbackModels: config2.fallbackModels,
|
|
180631
|
+
language: config2.language ?? deps.language
|
|
180531
180632
|
});
|
|
180532
180633
|
recordRun("completed", null, {
|
|
180533
180634
|
memoryChanges: computeMemoryDelta(memoryBefore)
|
|
@@ -180579,6 +180680,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
180579
180680
|
deadline,
|
|
180580
180681
|
model: config2.model,
|
|
180581
180682
|
fallbackModels: config2.fallbackModels,
|
|
180683
|
+
language: config2.language ?? deps.language,
|
|
180582
180684
|
rawProviderFactory: deps.primerRawProviderFactory
|
|
180583
180685
|
});
|
|
180584
180686
|
recordRun("completed", null);
|
|
@@ -180696,6 +180798,7 @@ function retrospectiveEventsForSessions(db, sessionIds) {
|
|
|
180696
180798
|
try {
|
|
180697
180799
|
for (const event of getCompartmentEvents(db, sessionId)) {
|
|
180698
180800
|
if (event.kind !== "causal_incident" && event.kind !== "trajectory_correction") {
|
|
180801
|
+
log(`[dreamer] dropping event: unknown kind="${event.kind}"`);
|
|
180699
180802
|
continue;
|
|
180700
180803
|
}
|
|
180701
180804
|
events.push({
|
|
@@ -180820,7 +180923,9 @@ async function runRetrospectiveTask(config2, ctx, helpers) {
|
|
|
180820
180923
|
const frictionWindow = renderFrictionWindow(messages, flagged.map((message) => message.ordinal));
|
|
180821
180924
|
const eventSessionIds = new Set(messages.map((message) => message.sessionId));
|
|
180822
180925
|
const events = retrospectiveEventsForSessions(db, eventSessionIds);
|
|
180823
|
-
const deepenRun = await runChildTurn(RETROSPECTIVE_SYSTEM_PROMPT,
|
|
180926
|
+
const deepenRun = await runChildTurn(withContentLanguageDirective(RETROSPECTIVE_SYSTEM_PROMPT, config2.language ?? deps.language, {
|
|
180927
|
+
retrospective: true
|
|
180928
|
+
}), buildRetrospectivePrompt({ projectPath: projectIdentity, frictionWindow, events }));
|
|
180824
180929
|
if (leaseLost)
|
|
180825
180930
|
throw new Error("Dream lease lost during retrospective");
|
|
180826
180931
|
const sourceSessionId = flagged[0]?.sessionId ?? userMessages[0]?.sessionId ?? "retrospective";
|
|
@@ -180906,7 +181011,7 @@ async function runAgenticTask(config2, ctx, helpers) {
|
|
|
180906
181011
|
query: { directory: docsDir },
|
|
180907
181012
|
body: {
|
|
180908
181013
|
agent: task === "maintain-docs" ? DREAMER_DOCS_AGENT : DREAMER_AGENT,
|
|
180909
|
-
system: task === "maintain-docs" ? MAINTAIN_DOCS_SYSTEM_PROMPT : CURATE_SYSTEM_PROMPT,
|
|
181014
|
+
system: task === "maintain-docs" ? MAINTAIN_DOCS_SYSTEM_PROMPT : withContentLanguageDirective(CURATE_SYSTEM_PROMPT, config2.language ?? deps.language),
|
|
180910
181015
|
...modelBodyField(config2.model),
|
|
180911
181016
|
parts: [{ type: "text", text: taskPrompt, synthetic: true }]
|
|
180912
181017
|
}
|
|
@@ -181788,7 +181893,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
|
|
|
181788
181893
|
}
|
|
181789
181894
|
try {
|
|
181790
181895
|
await runCompiledSmartNoteSweep(reg, db);
|
|
181791
|
-
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreamerConfig);
|
|
181896
|
+
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreamerConfig, reg.language);
|
|
181792
181897
|
const executor = createDreamTaskExecutor({
|
|
181793
181898
|
client: reg.client,
|
|
181794
181899
|
sessionDirectory: reg.directory,
|
|
@@ -181796,7 +181901,8 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
|
|
|
181796
181901
|
retrospectiveRawProvider: reg.retrospectiveRawProvider ?? ((db2) => new OpenCodeRetrospectiveRawProvider({ contextDb: db2, openOpenCodeDb })),
|
|
181797
181902
|
primerRawProviderFactory: reg.primerRawProviderFactory,
|
|
181798
181903
|
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreamerConfig),
|
|
181799
|
-
ensureProjectRegistered: reg.ensureRegistered
|
|
181904
|
+
ensureProjectRegistered: reg.ensureRegistered,
|
|
181905
|
+
language: reg.language
|
|
181800
181906
|
});
|
|
181801
181907
|
const ran = await runDueTasksForProject({
|
|
181802
181908
|
db,
|
|
@@ -182349,6 +182455,10 @@ function stripUnsafeProjectConfigFields(projectRaw) {
|
|
|
182349
182455
|
delete projectRaw.auto_update;
|
|
182350
182456
|
warnings.push("Ignoring auto_update from project config (security: this setting only honors user-level config).");
|
|
182351
182457
|
}
|
|
182458
|
+
if ("language" in projectRaw) {
|
|
182459
|
+
delete projectRaw.language;
|
|
182460
|
+
warnings.push("Ignoring language from project config (security: output language is a user-level setting).");
|
|
182461
|
+
}
|
|
182352
182462
|
if ("sqlite" in projectRaw) {
|
|
182353
182463
|
delete projectRaw.sqlite;
|
|
182354
182464
|
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).");
|
|
@@ -183404,6 +183514,7 @@ function registerPiDreamerProject(opts) {
|
|
|
183404
183514
|
projectIdentity: opts.projectIdentity,
|
|
183405
183515
|
client,
|
|
183406
183516
|
dreamerConfig: opts.config,
|
|
183517
|
+
language: opts.language,
|
|
183407
183518
|
gitCommitIndexing: opts.gitCommitIndexing,
|
|
183408
183519
|
ensureRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
183409
183520
|
retrospectiveRawProvider: () => new PiRetrospectiveRawProvider({ projectCwd: opts.projectDir }),
|
|
@@ -183418,7 +183529,7 @@ function registerPiDreamerProject(opts) {
|
|
|
183418
183529
|
const runManual = async (task) => runManualDream({
|
|
183419
183530
|
db: opts.db,
|
|
183420
183531
|
projectIdentity: opts.projectIdentity,
|
|
183421
|
-
tasks: buildDreamTaskRuntimeConfigs(opts.config),
|
|
183532
|
+
tasks: buildDreamTaskRuntimeConfigs(opts.config, opts.language),
|
|
183422
183533
|
executor: createDreamTaskExecutor({
|
|
183423
183534
|
client,
|
|
183424
183535
|
sessionDirectory: opts.projectDir,
|
|
@@ -183428,7 +183539,8 @@ function registerPiDreamerProject(opts) {
|
|
|
183428
183539
|
}),
|
|
183429
183540
|
primerRawProviderFactory: createPiPrimerRawProviderFactory(),
|
|
183430
183541
|
userMemoryCollectionEnabled: userMemoryCollectionEnabled(opts.config),
|
|
183431
|
-
ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory
|
|
183542
|
+
ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
183543
|
+
language: opts.language
|
|
183432
183544
|
}),
|
|
183433
183545
|
task
|
|
183434
183546
|
});
|
|
@@ -184337,6 +184449,7 @@ var pendingPiDecisionBySession = new Map;
|
|
|
184337
184449
|
var lastBoundMessageIdBySession = new Map;
|
|
184338
184450
|
var scheduledWriteTokensBySession = new Map;
|
|
184339
184451
|
var writerOverrideForTests = null;
|
|
184452
|
+
var retentionOverrideForTests = null;
|
|
184340
184453
|
function normalizeMaterializeReason(harness, reason, rematerialized) {
|
|
184341
184454
|
const raw = typeof reason === "string" ? reason.trim() : "";
|
|
184342
184455
|
if (raw.length > 0) {
|
|
@@ -184477,7 +184590,7 @@ function writeTransformDecisionRow(dbPath, row) {
|
|
|
184477
184590
|
WHERE session_id = ? AND harness = ?
|
|
184478
184591
|
ORDER BY ts_ms DESC, rowid DESC
|
|
184479
184592
|
LIMIT ?
|
|
184480
|
-
)`).run(row.sessionId, row.harness, row.sessionId, row.harness, TRANSFORM_DECISIONS_RETENTION);
|
|
184593
|
+
)`).run(row.sessionId, row.harness, row.sessionId, row.harness, retentionOverrideForTests ?? TRANSFORM_DECISIONS_RETENTION);
|
|
184481
184594
|
} finally {
|
|
184482
184595
|
closeQuietly(db);
|
|
184483
184596
|
}
|
|
@@ -186212,6 +186325,7 @@ function channel1RefireTokens(workingWindowTokens) {
|
|
|
186212
186325
|
var S_GENTLE = 0.2;
|
|
186213
186326
|
var S_FIRM = 0.4;
|
|
186214
186327
|
var S_URGENT = 0.65;
|
|
186328
|
+
var CHANNEL1_PRESSURE_FLOOR = 0.8;
|
|
186215
186329
|
var LEVEL_RANK = { gentle: 1, firm: 2, urgent: 3 };
|
|
186216
186330
|
var DROP_SENTINELS = ["[dropped", "[truncated"];
|
|
186217
186331
|
function isDroppedToolOutput(output) {
|
|
@@ -186222,7 +186336,8 @@ function toolOutputTokens(output) {
|
|
|
186222
186336
|
return Math.round(byteSize(output) * TOKENS_PER_BYTE);
|
|
186223
186337
|
}
|
|
186224
186338
|
function decideChannel1(input) {
|
|
186225
|
-
const { undroppedTokens,
|
|
186339
|
+
const { undroppedTokens, workingWindowTokens, hasRecentReduce } = input;
|
|
186340
|
+
const pressure = Math.min(1, Math.max(0, input.pressure));
|
|
186226
186341
|
const resetCycle = hasRecentReduce || undroppedTokens < input.lastNudgeUndropped;
|
|
186227
186342
|
const lastNudge = resetCycle ? 0 : input.lastNudgeUndropped;
|
|
186228
186343
|
const lastLevel = resetCycle ? "" : input.lastNudgeLevel;
|
|
@@ -186237,8 +186352,10 @@ function decideChannel1(input) {
|
|
|
186237
186352
|
return quiet();
|
|
186238
186353
|
if (undroppedTokens < CHANNEL1_FLOOR_TOKENS)
|
|
186239
186354
|
return quiet();
|
|
186240
|
-
|
|
186241
|
-
|
|
186355
|
+
if (pressure < CHANNEL1_PRESSURE_FLOOR)
|
|
186356
|
+
return quiet();
|
|
186357
|
+
const denom = Math.max(input.estimatedInputTokens, 1);
|
|
186358
|
+
const severity = Math.min(1, undroppedTokens / denom);
|
|
186242
186359
|
if (severity < S_GENTLE)
|
|
186243
186360
|
return quiet();
|
|
186244
186361
|
let level;
|
|
@@ -188554,6 +188671,7 @@ function maybeChannel1ReminderForToolResult(args) {
|
|
|
188554
188671
|
const decision = decideChannel1({
|
|
188555
188672
|
undroppedTokens,
|
|
188556
188673
|
pressure,
|
|
188674
|
+
estimatedInputTokens: state.lastInputTokens + state.turnToolTokens,
|
|
188557
188675
|
workingWindowTokens,
|
|
188558
188676
|
lastNudgeUndropped: getLastNudgeUndropped(db, sessionId),
|
|
188559
188677
|
lastNudgeLevel: getLastNudgeLevel(db, sessionId),
|
|
@@ -191361,8 +191479,8 @@ function buildHistorianFailureNotice(failureCount, lastError) {
|
|
|
191361
191479
|
].join(`
|
|
191362
191480
|
`);
|
|
191363
191481
|
}
|
|
191364
|
-
function buildHistorianRepairPrompt(originalPrompt, previousOutput, validationError) {
|
|
191365
|
-
|
|
191482
|
+
function buildHistorianRepairPrompt(originalPrompt, previousOutput, validationError, language) {
|
|
191483
|
+
const prompt = [
|
|
191366
191484
|
originalPrompt,
|
|
191367
191485
|
"",
|
|
191368
191486
|
"Your previous XML response was invalid and cannot be persisted.",
|
|
@@ -191375,6 +191493,7 @@ function buildHistorianRepairPrompt(originalPrompt, previousOutput, validationEr
|
|
|
191375
191493
|
previousOutput
|
|
191376
191494
|
].join(`
|
|
191377
191495
|
`);
|
|
191496
|
+
return withContentLanguageDirective(prompt, language, { preserveUserQuotes: true });
|
|
191378
191497
|
}
|
|
191379
191498
|
function validateStoredCompartments(compartments) {
|
|
191380
191499
|
if (compartments.length === 0) {
|
|
@@ -193498,9 +193617,11 @@ ${chunkText}`,
|
|
|
193498
193617
|
};
|
|
193499
193618
|
};
|
|
193500
193619
|
retainDrainReservationForRetryThrottle = true;
|
|
193620
|
+
const historianSystemPrompt = withContentLanguageDirective(COMPARTMENT_AGENT_SYSTEM_PROMPT, deps.language, { preserveUserQuotes: true });
|
|
193621
|
+
const historianEditorSystemPrompt = withContentLanguageDirective(HISTORIAN_EDITOR_SYSTEM_PROMPT, deps.language, { preserveUserQuotes: true });
|
|
193501
193622
|
const firstResult = await runner.run({
|
|
193502
193623
|
agent: HISTORIAN_AGENT_NAME,
|
|
193503
|
-
systemPrompt:
|
|
193624
|
+
systemPrompt: historianSystemPrompt,
|
|
193504
193625
|
userMessage: prompt,
|
|
193505
193626
|
model: historianModel,
|
|
193506
193627
|
fallbackModels,
|
|
@@ -193515,10 +193636,10 @@ ${chunkText}`,
|
|
|
193515
193636
|
let validatedDraftText = firstResult.ok ? firstResult.assistantText : null;
|
|
193516
193637
|
if (validatedPass.kind === "validation-failed") {
|
|
193517
193638
|
sessionLog(sessionId, `historian: first pass validation failed, retrying with repair prompt: ${validatedPass.error}`);
|
|
193518
|
-
const repairPrompt = buildHistorianRepairPrompt(prompt, validatedPass.rawText, validatedPass.error);
|
|
193639
|
+
const repairPrompt = buildHistorianRepairPrompt(prompt, validatedPass.rawText, validatedPass.error, deps.language);
|
|
193519
193640
|
const repairResult = await runner.run({
|
|
193520
193641
|
agent: HISTORIAN_AGENT_NAME,
|
|
193521
|
-
systemPrompt:
|
|
193642
|
+
systemPrompt: historianSystemPrompt,
|
|
193522
193643
|
userMessage: repairPrompt,
|
|
193523
193644
|
model: historianModel,
|
|
193524
193645
|
fallbackModels,
|
|
@@ -193543,7 +193664,7 @@ ${chunkText}`,
|
|
|
193543
193664
|
sessionLog(sessionId, `historian: escalating to configured fallback model ${candidate}`);
|
|
193544
193665
|
const fbResult = await runner.run({
|
|
193545
193666
|
agent: HISTORIAN_AGENT_NAME,
|
|
193546
|
-
systemPrompt:
|
|
193667
|
+
systemPrompt: historianSystemPrompt,
|
|
193547
193668
|
userMessage: prompt,
|
|
193548
193669
|
model: candidate,
|
|
193549
193670
|
fallbackModels: undefined,
|
|
@@ -193579,7 +193700,7 @@ ${chunkText}`,
|
|
|
193579
193700
|
sessionLog(sessionId, "historian two-pass: running editor on draft");
|
|
193580
193701
|
const editorResult = await runner.run({
|
|
193581
193702
|
agent: HISTORIAN_AGENT_NAME,
|
|
193582
|
-
systemPrompt:
|
|
193703
|
+
systemPrompt: historianEditorSystemPrompt,
|
|
193583
193704
|
userMessage: buildHistorianEditorPrompt(draftAssistantText),
|
|
193584
193705
|
model: historianModel,
|
|
193585
193706
|
timeoutMs: historianTimeoutMs,
|
|
@@ -194400,7 +194521,7 @@ Drop silently — do not narrate it. NEVER drop large ranges blindly (e.g., "1-5
|
|
|
194400
194521
|
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.`;
|
|
194401
194522
|
var CAVEMAN_COMPRESSION_WARNING = `
|
|
194402
194523
|
**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.`;
|
|
194403
|
-
function buildMagicContextSection(_agent, protectedTags, ctxReduceEnabled = true, dreamerEnabled = false, temporalAwarenessEnabled = false, cavemanTextCompressionEnabled = false, subagentMode = false) {
|
|
194524
|
+
function buildMagicContextSection(_agent, protectedTags, ctxReduceEnabled = true, dreamerEnabled = false, temporalAwarenessEnabled = false, cavemanTextCompressionEnabled = false, subagentMode = false, language) {
|
|
194404
194525
|
if (subagentMode) {
|
|
194405
194526
|
return `## Magic Context
|
|
194406
194527
|
|
|
@@ -194412,13 +194533,17 @@ The dreamer evaluates smart note conditions during nightly runs and surfaces the
|
|
|
194412
194533
|
Example: \`ctx_note(action="write", content="Implement X because Y", surface_condition="When PR #42 is merged in this repo")\`` : "";
|
|
194413
194534
|
const temporalGuidance = temporalAwarenessEnabled ? TEMPORAL_AWARENESS_GUIDANCE : "";
|
|
194414
194535
|
const cavemanWarning = cavemanTextCompressionEnabled && !ctxReduceEnabled ? CAVEMAN_COMPRESSION_WARNING : "";
|
|
194536
|
+
const languageDirective = buildPrimaryLanguageDirective(language);
|
|
194537
|
+
const languageGuidance = languageDirective ? `
|
|
194538
|
+
|
|
194539
|
+
${languageDirective}` : "";
|
|
194415
194540
|
if (!ctxReduceEnabled) {
|
|
194416
194541
|
return `## Magic Context
|
|
194417
194542
|
|
|
194418
194543
|
${LONG_TERM_PARTNER_FRAME}
|
|
194419
194544
|
${PARTNER_FRAME_CLOSER_NO_REDUCE}
|
|
194420
194545
|
|
|
194421
|
-
${BASE_INTRO_NO_REDUCE()}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}`;
|
|
194546
|
+
${BASE_INTRO_NO_REDUCE()}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
|
|
194422
194547
|
}
|
|
194423
194548
|
return `## Magic Context
|
|
194424
194549
|
|
|
@@ -194428,7 +194553,7 @@ ${PARTNER_FRAME_CLOSER_REDUCE}
|
|
|
194428
194553
|
${BASE_INTRO(protectedTags)}${smartNoteGuidance}${temporalGuidance}
|
|
194429
194554
|
${GENERIC_SECTION}
|
|
194430
194555
|
|
|
194431
|
-
Prefer many small targeted operations over one large blanket operation, and keep the working set tidy as routine maintenance
|
|
194556
|
+
Prefer many small targeted operations over one large blanket operation, and keep the working set tidy as routine maintenance.${languageGuidance}`;
|
|
194432
194557
|
}
|
|
194433
194558
|
|
|
194434
194559
|
// src/system-prompt.ts
|
|
@@ -194440,7 +194565,7 @@ function buildMagicContextBlock(opts) {
|
|
|
194440
194565
|
const includeGuidance = (opts.includeGuidance ?? true) && !existing.includes(MAGIC_CONTEXT_MARKER);
|
|
194441
194566
|
if (!includeGuidance)
|
|
194442
194567
|
return null;
|
|
194443
|
-
return buildMagicContextSection(null, opts.protectedTags ?? 20, opts.ctxReduceEnabled ?? true, opts.dreamerEnabled ?? false, opts.temporalAwarenessEnabled ?? false, opts.cavemanTextCompressionEnabled ?? false);
|
|
194568
|
+
return buildMagicContextSection(null, opts.protectedTags ?? 20, opts.ctxReduceEnabled ?? true, opts.dreamerEnabled ?? false, opts.temporalAwarenessEnabled ?? false, opts.cavemanTextCompressionEnabled ?? false, false, opts.language);
|
|
194444
194569
|
}
|
|
194445
194570
|
var DATE_PATTERN = /Today's date: .+/;
|
|
194446
194571
|
function processSystemPromptForCache(args) {
|
|
@@ -196132,6 +196257,7 @@ function spawnPiHistorianRun(args) {
|
|
|
196132
196257
|
memoryEnabled: historian.memoryEnabled,
|
|
196133
196258
|
autoPromote: historian.autoPromote,
|
|
196134
196259
|
userMemoriesEnabled: historian.userMemoriesEnabled,
|
|
196260
|
+
language: historian.language,
|
|
196135
196261
|
compartmentLeaseHolderId: holderId,
|
|
196136
196262
|
onPublished: () => {
|
|
196137
196263
|
const sessionStillActive = isContextHandlerSessionActive(sessionId);
|
|
@@ -197081,7 +197207,7 @@ async function runValidatedHistorianPass(args) {
|
|
|
197081
197207
|
return finalResult;
|
|
197082
197208
|
}
|
|
197083
197209
|
await args.callbacks?.onRepairRetry?.(firstValidation.error ?? "invalid compartment output");
|
|
197084
|
-
const repairPrompt = buildHistorianRepairPrompt(args.prompt, firstRun.result, firstValidation.error ?? "invalid compartment output");
|
|
197210
|
+
const repairPrompt = buildHistorianRepairPrompt(args.prompt, firstRun.result, firstValidation.error ?? "invalid compartment output", args.language);
|
|
197085
197211
|
const repairRun = await runHistorianPrompt({
|
|
197086
197212
|
...args,
|
|
197087
197213
|
prompt: repairPrompt,
|
|
@@ -197723,6 +197849,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
197723
197849
|
twoPass: deps.historianTwoPass,
|
|
197724
197850
|
subagentKind: "recomp",
|
|
197725
197851
|
agentId: HISTORIAN_RECOMP_AGENT,
|
|
197852
|
+
language: deps.language,
|
|
197726
197853
|
callbacks: {
|
|
197727
197854
|
onRepairRetry: async (error51) => {
|
|
197728
197855
|
emitProgress(`Repair retry (pass ${passCount + 1})…`);
|
|
@@ -198141,6 +198268,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
198141
198268
|
twoPass: deps.historianTwoPass,
|
|
198142
198269
|
subagentKind: "recomp",
|
|
198143
198270
|
agentId: HISTORIAN_RECOMP_AGENT,
|
|
198271
|
+
language: deps.language,
|
|
198144
198272
|
callbacks: {
|
|
198145
198273
|
onRepairRetry: async (error51) => {
|
|
198146
198274
|
await sendIgnoredMessage(client, sessionId, `## Magic Recomp — Partial
|
|
@@ -198633,7 +198761,7 @@ Historian recomp started. Rebuilding compartments and facts from raw Pi session
|
|
|
198633
198761
|
client: createPiHistorianClient({
|
|
198634
198762
|
runner: deps.runner,
|
|
198635
198763
|
model: deps.historianModel,
|
|
198636
|
-
systemPrompt: COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT,
|
|
198764
|
+
systemPrompt: withContentLanguageDirective(COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, deps.language, { preserveUserQuotes: true }),
|
|
198637
198765
|
fallbackModels: deps.historianFallbacks,
|
|
198638
198766
|
timeoutMs: deps.historianTimeoutMs,
|
|
198639
198767
|
thinkingLevel: deps.historianThinkingLevel,
|
|
@@ -198656,6 +198784,7 @@ Historian recomp started. Rebuilding compartments and facts from raw Pi session
|
|
|
198656
198784
|
autoPromote: deps.autoPromote,
|
|
198657
198785
|
ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
198658
198786
|
fallbackModels: deps.historianFallbacks,
|
|
198787
|
+
language: deps.language,
|
|
198659
198788
|
fallbackModelId: ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : undefined
|
|
198660
198789
|
}, parsed.kind === "partial" ? { range: parsed.range } : {});
|
|
198661
198790
|
if (result.published) {
|
|
@@ -198908,7 +199037,7 @@ async function runPiMemoryMigration(deps) {
|
|
|
198908
199037
|
}
|
|
198909
199038
|
const result = await deps.runner.run({
|
|
198910
199039
|
agent: "magic-context-historian",
|
|
198911
|
-
systemPrompt: MIGRATION_SYSTEM_PROMPT2,
|
|
199040
|
+
systemPrompt: withMigrationLanguageDirective(MIGRATION_SYSTEM_PROMPT2, deps.language),
|
|
198912
199041
|
userMessage: prompt,
|
|
198913
199042
|
model,
|
|
198914
199043
|
fallbackModels: undefined,
|
|
@@ -199020,7 +199149,8 @@ An upgrade or recomp is already running for this session in the background. Wait
|
|
|
199020
199149
|
thinkingLevel: deps.historianThinkingLevel,
|
|
199021
199150
|
directory: ctx.cwd,
|
|
199022
199151
|
sessionId,
|
|
199023
|
-
userMemoriesEnabled: deps.userMemoriesEnabled
|
|
199152
|
+
userMemoriesEnabled: deps.userMemoriesEnabled,
|
|
199153
|
+
language: deps.language
|
|
199024
199154
|
});
|
|
199025
199155
|
return outcome.summary;
|
|
199026
199156
|
} catch (error51) {
|
|
@@ -199092,7 +199222,7 @@ Rebuilding compartments into the v2 format and re-organizing project memories. T
|
|
|
199092
199222
|
thinkingLevel: deps.historianThinkingLevel,
|
|
199093
199223
|
directory: ctx.cwd,
|
|
199094
199224
|
accountingSessionId: sessionId,
|
|
199095
|
-
systemPrompt: COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT,
|
|
199225
|
+
systemPrompt: withContentLanguageDirective(COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, deps.language, { preserveUserQuotes: true }),
|
|
199096
199226
|
notify: (text) => sendCtxStatusMessage(pi, {
|
|
199097
199227
|
title: "/ctx-session-upgrade",
|
|
199098
199228
|
text,
|
|
@@ -199108,7 +199238,8 @@ Rebuilding compartments into the v2 format and re-organizing project memories. T
|
|
|
199108
199238
|
autoPromote: deps.autoPromote,
|
|
199109
199239
|
ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
199110
199240
|
fallbackModels: deps.historianFallbacks,
|
|
199111
|
-
fallbackModelId: sessionMainModel
|
|
199241
|
+
fallbackModelId: sessionMainModel,
|
|
199242
|
+
language: deps.language
|
|
199112
199243
|
}, {});
|
|
199113
199244
|
if (!recompResult.published || !isRecompComplete(recompResult.message)) {
|
|
199114
199245
|
const reason = contextualizeUpgradeReason(isRecompFailure(recompResult.message) ? extractRecompReason(recompResult.message) : `Compartments were not fully rebuilt: ${extractRecompReason(recompResult.message)}`);
|
|
@@ -199320,7 +199451,7 @@ function formatThresholdPercent(value) {
|
|
|
199320
199451
|
// package.json
|
|
199321
199452
|
var package_default = {
|
|
199322
199453
|
name: "@cortexkit/pi-magic-context",
|
|
199323
|
-
version: "0.
|
|
199454
|
+
version: "0.28.0",
|
|
199324
199455
|
type: "module",
|
|
199325
199456
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
199326
199457
|
main: "dist/index.js",
|
|
@@ -205475,7 +205606,8 @@ function resolveSidekickFromConfig(config2) {
|
|
|
205475
205606
|
systemPrompt: sidekick.system_prompt,
|
|
205476
205607
|
timeoutMs: sidekick.timeout_ms,
|
|
205477
205608
|
thinking_level: sidekick.thinking_level,
|
|
205478
|
-
fallbackModels: resolveFallbackChain(sidekick.fallback_models)
|
|
205609
|
+
fallbackModels: resolveFallbackChain(sidekick.fallback_models),
|
|
205610
|
+
language: config2.language
|
|
205479
205611
|
};
|
|
205480
205612
|
}
|
|
205481
205613
|
function resolveHistorianFromConfig(config2) {
|
|
@@ -205504,7 +205636,8 @@ function resolveHistorianFromConfig(config2) {
|
|
|
205504
205636
|
historyBudgetPercentage: config2.history_budget_percentage,
|
|
205505
205637
|
memoryEnabled: config2.memory.enabled,
|
|
205506
205638
|
autoPromote: config2.memory.auto_promote,
|
|
205507
|
-
userMemoriesEnabled: userMemoryCollectionEnabled(config2.dreamer)
|
|
205639
|
+
userMemoriesEnabled: userMemoryCollectionEnabled(config2.dreamer),
|
|
205640
|
+
language: config2.language
|
|
205508
205641
|
};
|
|
205509
205642
|
}
|
|
205510
205643
|
function resolveAutoSearchFromConfig(config2) {
|
|
@@ -205531,7 +205664,7 @@ async function src_default2(pi) {
|
|
|
205531
205664
|
return;
|
|
205532
205665
|
}
|
|
205533
205666
|
if (!db) {
|
|
205534
|
-
warn(`Magic Context (pi) storage unavailable at ${dbPath} (cache schema is newer than this binary supports). ` + "Plugin will not register hooks;
|
|
205667
|
+
warn(`Magic Context (pi) storage unavailable at ${dbPath} (cache schema is newer than this binary supports). ` + "A pinned or stale plugin is likely sharing this database with a newer instance. " + "Plugin will not register hooks; run 'npx @cortexkit/magic-context@latest doctor --force' " + "(or update Pi/OpenCode) and restart to recover.");
|
|
205535
205668
|
return;
|
|
205536
205669
|
}
|
|
205537
205670
|
const database = db;
|
|
@@ -205619,6 +205752,7 @@ async function src_default2(pi) {
|
|
|
205619
205752
|
executeThresholdTokens: cfg.execute_threshold_tokens
|
|
205620
205753
|
},
|
|
205621
205754
|
historian: hist,
|
|
205755
|
+
language: cfg.language,
|
|
205622
205756
|
autoSearch: auto,
|
|
205623
205757
|
resolveForProject: resolveContextOptionsForProject,
|
|
205624
205758
|
maybeAutoEmbedSession: (sessionId, dir, identity) => {
|
|
@@ -205691,6 +205825,7 @@ async function src_default2(pi) {
|
|
|
205691
205825
|
historianFallbacks: historianConfig?.fallbackModels,
|
|
205692
205826
|
historianTimeoutMs: config2.historian_timeout_ms,
|
|
205693
205827
|
historianThinkingLevel: historianConfig?.thinkingLevel,
|
|
205828
|
+
language: config2.language,
|
|
205694
205829
|
memoryEnabled: config2.memory.enabled,
|
|
205695
205830
|
autoPromote: config2.memory.auto_promote
|
|
205696
205831
|
});
|
|
@@ -205703,6 +205838,7 @@ async function src_default2(pi) {
|
|
|
205703
205838
|
historianFallbacks: historianConfig?.fallbackModels,
|
|
205704
205839
|
historianTimeoutMs: config2.historian_timeout_ms,
|
|
205705
205840
|
historianThinkingLevel: historianConfig?.thinkingLevel,
|
|
205841
|
+
language: config2.language,
|
|
205706
205842
|
memoryEnabled: config2.memory.enabled,
|
|
205707
205843
|
autoPromote: config2.memory.auto_promote,
|
|
205708
205844
|
userMemoriesEnabled: userMemoryCollectionEnabled(config2.dreamer)
|
|
@@ -205734,6 +205870,7 @@ async function src_default2(pi) {
|
|
|
205734
205870
|
config: dreamerConfig,
|
|
205735
205871
|
embeddingConfig: config2.embedding,
|
|
205736
205872
|
memoryEnabled: config2.memory.enabled,
|
|
205873
|
+
language: config2.language,
|
|
205737
205874
|
gitCommitIndexing: config2.memory.git_commit_indexing,
|
|
205738
205875
|
onAdjunctsRefreshNeeded: signalPiSystemPromptRefreshForProject
|
|
205739
205876
|
});
|
|
@@ -205848,6 +205985,7 @@ async function src_default2(pi) {
|
|
|
205848
205985
|
dreamerEnabled: effectiveDreamerRunnable,
|
|
205849
205986
|
temporalAwarenessEnabled: effectiveConfig.temporal_awareness ?? false,
|
|
205850
205987
|
cavemanTextCompressionEnabled: effectiveConfig.ctx_reduce_enabled === false && effectiveConfig.caveman_text_compression?.enabled === true,
|
|
205988
|
+
language: effectiveConfig.language,
|
|
205851
205989
|
userMemoriesEnabled: userMemoryCollectionEnabled(effectiveConfig.dreamer),
|
|
205852
205990
|
isCacheBusting,
|
|
205853
205991
|
existingSystemPrompt: event.systemPrompt
|
package/dist/subagent-entry.js
CHANGED
|
@@ -142942,7 +142942,7 @@ function enforceSchemaFence(db, dbPath, latestSupportedVersion) {
|
|
|
142942
142942
|
return true;
|
|
142943
142943
|
}
|
|
142944
142944
|
lastSchemaFenceRejection = { persistedVersion, supportedVersion: latestSupportedVersion };
|
|
142945
|
-
log(`[magic-context] storage fatal: refusing to open ${dbPath}; database schema v${persistedVersion} is newer than this binary supports (max v${latestSupportedVersion}).
|
|
142945
|
+
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.`);
|
|
142946
142946
|
return false;
|
|
142947
142947
|
}
|
|
142948
142948
|
var sqlitePragmaConfig = {
|
|
@@ -144835,6 +144835,10 @@ function stripUnsafeProjectConfigFields(projectRaw) {
|
|
|
144835
144835
|
delete projectRaw.auto_update;
|
|
144836
144836
|
warnings.push("Ignoring auto_update from project config (security: this setting only honors user-level config).");
|
|
144837
144837
|
}
|
|
144838
|
+
if ("language" in projectRaw) {
|
|
144839
|
+
delete projectRaw.language;
|
|
144840
|
+
warnings.push("Ignoring language from project config (security: output language is a user-level setting).");
|
|
144841
|
+
}
|
|
144838
144842
|
if ("sqlite" in projectRaw) {
|
|
144839
144843
|
delete projectRaw.sqlite;
|
|
144840
144844
|
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).");
|
|
@@ -159180,6 +159184,95 @@ function date4(params) {
|
|
|
159180
159184
|
|
|
159181
159185
|
// ../../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
159182
159186
|
config(en_default());
|
|
159187
|
+
// ../plugin/src/agents/language-directive.ts
|
|
159188
|
+
var ENGLISH_LANGUAGE_NAMES = new Intl.DisplayNames(["en"], {
|
|
159189
|
+
type: "language",
|
|
159190
|
+
fallback: "none"
|
|
159191
|
+
});
|
|
159192
|
+
function resolveLanguageName(language) {
|
|
159193
|
+
const code = typeof language === "string" ? language.trim().toLowerCase() : "";
|
|
159194
|
+
if (!/^[a-z]{2}$/.test(code))
|
|
159195
|
+
return "";
|
|
159196
|
+
let english;
|
|
159197
|
+
try {
|
|
159198
|
+
english = ENGLISH_LANGUAGE_NAMES.of(code) ?? undefined;
|
|
159199
|
+
} catch {
|
|
159200
|
+
return "";
|
|
159201
|
+
}
|
|
159202
|
+
if (!english)
|
|
159203
|
+
return "";
|
|
159204
|
+
let endonym;
|
|
159205
|
+
try {
|
|
159206
|
+
endonym = new Intl.DisplayNames([code], { type: "language", fallback: "none" }).of(code) ?? undefined;
|
|
159207
|
+
} catch {
|
|
159208
|
+
endonym = undefined;
|
|
159209
|
+
}
|
|
159210
|
+
return endonym && endonym !== english ? `${english} (${endonym})` : english;
|
|
159211
|
+
}
|
|
159212
|
+
function isValidLanguageCode(language) {
|
|
159213
|
+
return resolveLanguageName(language) !== "";
|
|
159214
|
+
}
|
|
159215
|
+
function buildContentLanguageDirective(language, options = {}) {
|
|
159216
|
+
const target = resolveLanguageName(language);
|
|
159217
|
+
if (!target)
|
|
159218
|
+
return "";
|
|
159219
|
+
const lines = [
|
|
159220
|
+
"## Output language",
|
|
159221
|
+
"",
|
|
159222
|
+
`Write human-readable prose you author in: ${target}.`,
|
|
159223
|
+
"",
|
|
159224
|
+
"Do not translate or rename structural tokens. Copy required output schemas exactly:",
|
|
159225
|
+
"- 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.",
|
|
159226
|
+
"- 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.",
|
|
159227
|
+
"- Localize only free-text prose values/content: summaries, memory text, explanations, titles, observations, and answers — unless the prompt says to preserve original wording.",
|
|
159228
|
+
"",
|
|
159229
|
+
"These literal values must remain English when used:",
|
|
159230
|
+
"PROJECT_RULES, ARCHITECTURE, CONSTRAINTS, CONFIG_VALUES, NAMING;",
|
|
159231
|
+
"causal_incident, trajectory_correction;",
|
|
159232
|
+
"feature, design, docs, release, investigation, bug, refactor, infra;",
|
|
159233
|
+
"memory, observation; true, false; No relevant memories found.",
|
|
159234
|
+
"",
|
|
159235
|
+
"Preserve the required output shape. Do not add commentary outside the requested XML/JSON/tool output."
|
|
159236
|
+
];
|
|
159237
|
+
if (options.preserveUserQuotes) {
|
|
159238
|
+
lines.push("", `Preserve U: lines and directly quoted user text in their original source language; write the surrounding summary prose in ${target}.`);
|
|
159239
|
+
}
|
|
159240
|
+
if (options.retrospective) {
|
|
159241
|
+
lines.push("", `Write the lesson text in ${target}; paraphrase source text and never quote the user.`);
|
|
159242
|
+
}
|
|
159243
|
+
return lines.join(`
|
|
159244
|
+
`);
|
|
159245
|
+
}
|
|
159246
|
+
function withContentLanguageDirective(systemPrompt, language, options = {}) {
|
|
159247
|
+
const directive = buildContentLanguageDirective(language, options);
|
|
159248
|
+
return directive ? `${systemPrompt}
|
|
159249
|
+
|
|
159250
|
+
${directive}` : systemPrompt;
|
|
159251
|
+
}
|
|
159252
|
+
function buildMigrationLanguageDirective(language) {
|
|
159253
|
+
const target = resolveLanguageName(language);
|
|
159254
|
+
if (!target)
|
|
159255
|
+
return "";
|
|
159256
|
+
return [
|
|
159257
|
+
"## Output language",
|
|
159258
|
+
"",
|
|
159259
|
+
"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."
|
|
159260
|
+
].join(`
|
|
159261
|
+
`);
|
|
159262
|
+
}
|
|
159263
|
+
function withMigrationLanguageDirective(systemPrompt, language) {
|
|
159264
|
+
const directive = buildMigrationLanguageDirective(language);
|
|
159265
|
+
return directive ? `${systemPrompt}
|
|
159266
|
+
|
|
159267
|
+
${directive}` : systemPrompt;
|
|
159268
|
+
}
|
|
159269
|
+
function buildPrimaryLanguageDirective(language) {
|
|
159270
|
+
const target = resolveLanguageName(language);
|
|
159271
|
+
if (!target)
|
|
159272
|
+
return "";
|
|
159273
|
+
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.`;
|
|
159274
|
+
}
|
|
159275
|
+
|
|
159183
159276
|
// ../plugin/src/features/magic-context/defaults.ts
|
|
159184
159277
|
var DEFAULT_PROTECTED_TAGS = 20;
|
|
159185
159278
|
|
|
@@ -159536,6 +159629,7 @@ var EmbeddingConfigSchema = BaseEmbeddingConfigSchema.transform((data) => {
|
|
|
159536
159629
|
var MagicContextConfigSchema = exports_external.object({
|
|
159537
159630
|
enabled: exports_external.boolean().default(true).describe("Enable magic context (default: true)"),
|
|
159538
159631
|
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."),
|
|
159632
|
+
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."),
|
|
159539
159633
|
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)"),
|
|
159540
159634
|
historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
|
|
159541
159635
|
dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
|
|
@@ -171478,6 +171572,9 @@ function getActiveTagTokenAggregate(db, sessionId, protectedTags = 0) {
|
|
|
171478
171572
|
nullCount: row?.null_count ?? 0
|
|
171479
171573
|
};
|
|
171480
171574
|
}
|
|
171575
|
+
var RECLAIM_HINT_EXCLUDED_TOOLS = ["todowrite"];
|
|
171576
|
+
var RECLAIM_HINT_MIN_TOKENS = 250;
|
|
171577
|
+
var RECLAIM_HINT_EXCLUDED_LIST = RECLAIM_HINT_EXCLUDED_TOOLS.map((name2) => `'${name2.replace(/'/g, "''")}'`).join(", ");
|
|
171481
171578
|
function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, limit = 4) {
|
|
171482
171579
|
if (limit <= 0)
|
|
171483
171580
|
return [];
|
|
@@ -171487,10 +171584,18 @@ function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, li
|
|
|
171487
171584
|
WHERE session_id = ? AND status = 'active'
|
|
171488
171585
|
ORDER BY tag_number DESC LIMIT 1 OFFSET ?
|
|
171489
171586
|
)` : "";
|
|
171490
|
-
const
|
|
171587
|
+
const excludeStateTools = RECLAIM_HINT_EXCLUDED_LIST ? `AND (tool_name IS NULL OR tool_name NOT IN (${RECLAIM_HINT_EXCLUDED_LIST}))` : "";
|
|
171588
|
+
const valueFloor = `AND (
|
|
171589
|
+
(token_count IS NULL AND input_token_count IS NULL)
|
|
171590
|
+
OR (COALESCE(token_count, 0) + COALESCE(input_token_count, 0)) >= ?
|
|
171591
|
+
)`;
|
|
171592
|
+
const params = protectedTags > 0 ? [sessionId, RECLAIM_HINT_MIN_TOKENS, sessionId, protectedTags - 1, boundedLimit] : [sessionId, RECLAIM_HINT_MIN_TOKENS, boundedLimit];
|
|
171491
171593
|
const rows = db.prepare(`SELECT tag_number, tool_name
|
|
171492
171594
|
FROM tags
|
|
171493
|
-
WHERE session_id = ? AND status = 'active' AND type = 'tool'
|
|
171595
|
+
WHERE session_id = ? AND status = 'active' AND type = 'tool'
|
|
171596
|
+
${excludeStateTools}
|
|
171597
|
+
${valueFloor}
|
|
171598
|
+
${whereProtected}
|
|
171494
171599
|
ORDER BY tag_number ASC, id ASC
|
|
171495
171600
|
LIMIT ?`).all(...params);
|
|
171496
171601
|
return rows.filter((row) => typeof row.tag_number === "number").map((row) => ({
|
package/package.json
CHANGED