@wolfx/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 +193 -54
- package/dist/subagent-entry.js +108 -3
- package/package.json +1 -2
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) => ({
|
|
@@ -156329,13 +156341,10 @@ function compareSemverCore(a, b) {
|
|
|
156329
156341
|
const [b0, b1, b2] = core(b);
|
|
156330
156342
|
return a0 - b0 || a1 - b1 || a2 - b2;
|
|
156331
156343
|
}
|
|
156332
|
-
var ANNOUNCEMENT_VERSION = "0.
|
|
156344
|
+
var ANNOUNCEMENT_VERSION = "0.28.0";
|
|
156333
156345
|
var ANNOUNCEMENT_FEATURES = [
|
|
156334
|
-
|
|
156335
|
-
"
|
|
156336
|
-
"New Primers: durable answers to the questions that keep coming up about your project, kept current by the dreamer investigating the actual code.",
|
|
156337
|
-
"Embedding storage no longer wipes your vectors when you change model or endpoint. Different models now coexist, so switching providers keeps your existing vectors.",
|
|
156338
|
-
"Config moved to a shared CortexKit location (~/.config/cortexkit/ and <project>/.cortexkit/). This happens automatically on first run; your old file is preserved."
|
|
156346
|
+
`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.`,
|
|
156347
|
+
"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."
|
|
156339
156348
|
];
|
|
156340
156349
|
var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/F2uWxjGnU";
|
|
156341
156350
|
var STATE_FILENAME = "last_announced_version";
|
|
@@ -156397,6 +156406,95 @@ function shouldKeepSubagents() {
|
|
|
156397
156406
|
// src/index.ts
|
|
156398
156407
|
init_logger();
|
|
156399
156408
|
|
|
156409
|
+
// ../plugin/src/agents/language-directive.ts
|
|
156410
|
+
var ENGLISH_LANGUAGE_NAMES = new Intl.DisplayNames(["en"], {
|
|
156411
|
+
type: "language",
|
|
156412
|
+
fallback: "none"
|
|
156413
|
+
});
|
|
156414
|
+
function resolveLanguageName(language) {
|
|
156415
|
+
const code = typeof language === "string" ? language.trim().toLowerCase() : "";
|
|
156416
|
+
if (!/^[a-z]{2}$/.test(code))
|
|
156417
|
+
return "";
|
|
156418
|
+
let english;
|
|
156419
|
+
try {
|
|
156420
|
+
english = ENGLISH_LANGUAGE_NAMES.of(code) ?? undefined;
|
|
156421
|
+
} catch {
|
|
156422
|
+
return "";
|
|
156423
|
+
}
|
|
156424
|
+
if (!english)
|
|
156425
|
+
return "";
|
|
156426
|
+
let endonym;
|
|
156427
|
+
try {
|
|
156428
|
+
endonym = new Intl.DisplayNames([code], { type: "language", fallback: "none" }).of(code) ?? undefined;
|
|
156429
|
+
} catch {
|
|
156430
|
+
endonym = undefined;
|
|
156431
|
+
}
|
|
156432
|
+
return endonym && endonym !== english ? `${english} (${endonym})` : english;
|
|
156433
|
+
}
|
|
156434
|
+
function isValidLanguageCode(language) {
|
|
156435
|
+
return resolveLanguageName(language) !== "";
|
|
156436
|
+
}
|
|
156437
|
+
function buildContentLanguageDirective(language, options = {}) {
|
|
156438
|
+
const target = resolveLanguageName(language);
|
|
156439
|
+
if (!target)
|
|
156440
|
+
return "";
|
|
156441
|
+
const lines = [
|
|
156442
|
+
"## Output language",
|
|
156443
|
+
"",
|
|
156444
|
+
`Write human-readable prose you author in: ${target}.`,
|
|
156445
|
+
"",
|
|
156446
|
+
"Do not translate or rename structural tokens. Copy required output schemas exactly:",
|
|
156447
|
+
"- 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.",
|
|
156448
|
+
"- 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.",
|
|
156449
|
+
"- Localize only free-text prose values/content: summaries, memory text, explanations, titles, observations, and answers — unless the prompt says to preserve original wording.",
|
|
156450
|
+
"",
|
|
156451
|
+
"These literal values must remain English when used:",
|
|
156452
|
+
"PROJECT_RULES, ARCHITECTURE, CONSTRAINTS, CONFIG_VALUES, NAMING;",
|
|
156453
|
+
"causal_incident, trajectory_correction;",
|
|
156454
|
+
"feature, design, docs, release, investigation, bug, refactor, infra;",
|
|
156455
|
+
"memory, observation; true, false; No relevant memories found.",
|
|
156456
|
+
"",
|
|
156457
|
+
"Preserve the required output shape. Do not add commentary outside the requested XML/JSON/tool output."
|
|
156458
|
+
];
|
|
156459
|
+
if (options.preserveUserQuotes) {
|
|
156460
|
+
lines.push("", `Preserve U: lines and directly quoted user text in their original source language; write the surrounding summary prose in ${target}.`);
|
|
156461
|
+
}
|
|
156462
|
+
if (options.retrospective) {
|
|
156463
|
+
lines.push("", `Write the lesson text in ${target}; paraphrase source text and never quote the user.`);
|
|
156464
|
+
}
|
|
156465
|
+
return lines.join(`
|
|
156466
|
+
`);
|
|
156467
|
+
}
|
|
156468
|
+
function withContentLanguageDirective(systemPrompt, language, options = {}) {
|
|
156469
|
+
const directive = buildContentLanguageDirective(language, options);
|
|
156470
|
+
return directive ? `${systemPrompt}
|
|
156471
|
+
|
|
156472
|
+
${directive}` : systemPrompt;
|
|
156473
|
+
}
|
|
156474
|
+
function buildMigrationLanguageDirective(language) {
|
|
156475
|
+
const target = resolveLanguageName(language);
|
|
156476
|
+
if (!target)
|
|
156477
|
+
return "";
|
|
156478
|
+
return [
|
|
156479
|
+
"## Output language",
|
|
156480
|
+
"",
|
|
156481
|
+
"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."
|
|
156482
|
+
].join(`
|
|
156483
|
+
`);
|
|
156484
|
+
}
|
|
156485
|
+
function withMigrationLanguageDirective(systemPrompt, language) {
|
|
156486
|
+
const directive = buildMigrationLanguageDirective(language);
|
|
156487
|
+
return directive ? `${systemPrompt}
|
|
156488
|
+
|
|
156489
|
+
${directive}` : systemPrompt;
|
|
156490
|
+
}
|
|
156491
|
+
function buildPrimaryLanguageDirective(language) {
|
|
156492
|
+
const target = resolveLanguageName(language);
|
|
156493
|
+
if (!target)
|
|
156494
|
+
return "";
|
|
156495
|
+
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.`;
|
|
156496
|
+
}
|
|
156497
|
+
|
|
156400
156498
|
// ../plugin/src/features/magic-context/sidekick/core.ts
|
|
156401
156499
|
var SIDEKICK_SYSTEM_PROMPT = `You are Sidekick, a focused memory-retrieval subagent for an AI coding assistant.
|
|
156402
156500
|
|
|
@@ -157117,7 +157215,7 @@ function registerCtxAugCommand(pi, config) {
|
|
|
157117
157215
|
sessionLog(sessionLabel, "/ctx-aug: project identity", projectIdentity);
|
|
157118
157216
|
const result = await runner.run({
|
|
157119
157217
|
agent: "sidekick",
|
|
157120
|
-
systemPrompt: config.systemPrompt ?? SIDEKICK_SYSTEM_PROMPT,
|
|
157218
|
+
systemPrompt: withContentLanguageDirective(config.systemPrompt ?? SIDEKICK_SYSTEM_PROMPT, config.language),
|
|
157121
157219
|
userMessage: prompt,
|
|
157122
157220
|
model: config.model,
|
|
157123
157221
|
fallbackModels: config.fallbackModels,
|
|
@@ -161583,7 +161681,7 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
|
|
|
161583
161681
|
query: { directory: args.sessionDirectory },
|
|
161584
161682
|
body: {
|
|
161585
161683
|
agent: DREAMER_REVIEWER_AGENT,
|
|
161586
|
-
system: REVIEW_USER_MEMORIES_SYSTEM_PROMPT,
|
|
161684
|
+
system: withContentLanguageDirective(REVIEW_USER_MEMORIES_SYSTEM_PROMPT, args.language),
|
|
161587
161685
|
...modelBodyField(args.model),
|
|
161588
161686
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
161589
161687
|
}
|
|
@@ -164537,7 +164635,7 @@ async function refreshOnePrimer(args, primer, sliceMs, signal) {
|
|
|
164537
164635
|
query: { directory: args.sessionDirectory },
|
|
164538
164636
|
body: {
|
|
164539
164637
|
agent: DREAMER_PRIMER_INVESTIGATOR_AGENT,
|
|
164540
|
-
system: PRIMER_INVESTIGATOR_SYSTEM_PROMPT,
|
|
164638
|
+
system: withContentLanguageDirective(PRIMER_INVESTIGATOR_SYSTEM_PROMPT, args.language),
|
|
164541
164639
|
...modelBodyField(args.model),
|
|
164542
164640
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
164543
164641
|
}
|
|
@@ -165318,7 +165416,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
165318
165416
|
query: { directory: args.sessionDirectory },
|
|
165319
165417
|
body: {
|
|
165320
165418
|
agent: DREAMER_MEMORY_MAPPER_AGENT,
|
|
165321
|
-
system: VERIFY_SYSTEM_PROMPT,
|
|
165419
|
+
system: withContentLanguageDirective(VERIFY_SYSTEM_PROMPT, args.language),
|
|
165322
165420
|
...modelBodyField(args.model),
|
|
165323
165421
|
parts: [{ type: "text", text: prompt, synthetic: true }]
|
|
165324
165422
|
}
|
|
@@ -165598,7 +165696,8 @@ function createDreamTaskExecutor(deps) {
|
|
|
165598
165696
|
deadline,
|
|
165599
165697
|
promotionThreshold: config.promotionThreshold ?? 3,
|
|
165600
165698
|
model: config.model,
|
|
165601
|
-
fallbackModels: config.fallbackModels
|
|
165699
|
+
fallbackModels: config.fallbackModels,
|
|
165700
|
+
language: config.language ?? deps.language
|
|
165602
165701
|
});
|
|
165603
165702
|
recordRun("completed", null);
|
|
165604
165703
|
log(`[dreamer] review-user-memories: promoted=${result.promoted} merged=${result.merged} dismissed=${result.dismissed}`);
|
|
@@ -165634,7 +165733,8 @@ function createDreamTaskExecutor(deps) {
|
|
|
165634
165733
|
deadline,
|
|
165635
165734
|
forceBroad: config.task === "verify-broad",
|
|
165636
165735
|
model: config.model,
|
|
165637
|
-
fallbackModels: config.fallbackModels
|
|
165736
|
+
fallbackModels: config.fallbackModels,
|
|
165737
|
+
language: config.language ?? deps.language
|
|
165638
165738
|
});
|
|
165639
165739
|
recordRun("completed", null, {
|
|
165640
165740
|
memoryChanges: computeMemoryDelta(memoryBefore)
|
|
@@ -165686,6 +165786,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
165686
165786
|
deadline,
|
|
165687
165787
|
model: config.model,
|
|
165688
165788
|
fallbackModels: config.fallbackModels,
|
|
165789
|
+
language: config.language ?? deps.language,
|
|
165689
165790
|
rawProviderFactory: deps.primerRawProviderFactory
|
|
165690
165791
|
});
|
|
165691
165792
|
recordRun("completed", null);
|
|
@@ -165803,6 +165904,7 @@ function retrospectiveEventsForSessions(db, sessionIds) {
|
|
|
165803
165904
|
try {
|
|
165804
165905
|
for (const event of getCompartmentEvents(db, sessionId)) {
|
|
165805
165906
|
if (event.kind !== "causal_incident" && event.kind !== "trajectory_correction") {
|
|
165907
|
+
log(`[dreamer] dropping event: unknown kind="${event.kind}"`);
|
|
165806
165908
|
continue;
|
|
165807
165909
|
}
|
|
165808
165910
|
events.push({
|
|
@@ -165927,7 +166029,9 @@ async function runRetrospectiveTask(config, ctx, helpers) {
|
|
|
165927
166029
|
const frictionWindow = renderFrictionWindow(messages, flagged.map((message) => message.ordinal));
|
|
165928
166030
|
const eventSessionIds = new Set(messages.map((message) => message.sessionId));
|
|
165929
166031
|
const events = retrospectiveEventsForSessions(db, eventSessionIds);
|
|
165930
|
-
const deepenRun = await runChildTurn(RETROSPECTIVE_SYSTEM_PROMPT,
|
|
166032
|
+
const deepenRun = await runChildTurn(withContentLanguageDirective(RETROSPECTIVE_SYSTEM_PROMPT, config.language ?? deps.language, {
|
|
166033
|
+
retrospective: true
|
|
166034
|
+
}), buildRetrospectivePrompt({ projectPath: projectIdentity, frictionWindow, events }));
|
|
165931
166035
|
if (leaseLost)
|
|
165932
166036
|
throw new Error("Dream lease lost during retrospective");
|
|
165933
166037
|
const sourceSessionId = flagged[0]?.sessionId ?? userMessages[0]?.sessionId ?? "retrospective";
|
|
@@ -166013,7 +166117,7 @@ async function runAgenticTask(config, ctx, helpers) {
|
|
|
166013
166117
|
query: { directory: docsDir },
|
|
166014
166118
|
body: {
|
|
166015
166119
|
agent: task === "maintain-docs" ? DREAMER_DOCS_AGENT : DREAMER_AGENT,
|
|
166016
|
-
system: task === "maintain-docs" ? MAINTAIN_DOCS_SYSTEM_PROMPT : CURATE_SYSTEM_PROMPT,
|
|
166120
|
+
system: task === "maintain-docs" ? MAINTAIN_DOCS_SYSTEM_PROMPT : withContentLanguageDirective(CURATE_SYSTEM_PROMPT, config.language ?? deps.language),
|
|
166017
166121
|
...modelBodyField(config.model),
|
|
166018
166122
|
parts: [{ type: "text", text: taskPrompt, synthetic: true }]
|
|
166019
166123
|
}
|
|
@@ -166895,7 +166999,7 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
|
|
|
166895
166999
|
}
|
|
166896
167000
|
try {
|
|
166897
167001
|
await runCompiledSmartNoteSweep(reg, db);
|
|
166898
|
-
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreamerConfig);
|
|
167002
|
+
const runtimeConfigs = buildDreamTaskRuntimeConfigs(dreamerConfig, reg.language);
|
|
166899
167003
|
const executor = createDreamTaskExecutor({
|
|
166900
167004
|
client: reg.client,
|
|
166901
167005
|
sessionDirectory: reg.directory,
|
|
@@ -166903,7 +167007,8 @@ async function sweepProject(reg, origin, db, gitCommitEnabled) {
|
|
|
166903
167007
|
retrospectiveRawProvider: reg.retrospectiveRawProvider ?? ((db2) => new OpenCodeRetrospectiveRawProvider({ contextDb: db2, openOpenCodeDb })),
|
|
166904
167008
|
primerRawProviderFactory: reg.primerRawProviderFactory,
|
|
166905
167009
|
userMemoryCollectionEnabled: userMemoryCollectionEnabled(dreamerConfig),
|
|
166906
|
-
ensureProjectRegistered: reg.ensureRegistered
|
|
167010
|
+
ensureProjectRegistered: reg.ensureRegistered,
|
|
167011
|
+
language: reg.language
|
|
166907
167012
|
});
|
|
166908
167013
|
const ran = await runDueTasksForProject({
|
|
166909
167014
|
db,
|
|
@@ -167460,6 +167565,10 @@ function stripUnsafeProjectConfigFields(projectRaw) {
|
|
|
167460
167565
|
delete projectRaw.auto_update;
|
|
167461
167566
|
warnings.push("Ignoring auto_update from project config (security: this setting only honors user-level config).");
|
|
167462
167567
|
}
|
|
167568
|
+
if ("language" in projectRaw) {
|
|
167569
|
+
delete projectRaw.language;
|
|
167570
|
+
warnings.push("Ignoring language from project config (security: output language is a user-level setting).");
|
|
167571
|
+
}
|
|
167463
167572
|
if ("sqlite" in projectRaw) {
|
|
167464
167573
|
delete projectRaw.sqlite;
|
|
167465
167574
|
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).");
|
|
@@ -181957,6 +182066,7 @@ var EmbeddingConfigSchema = BaseEmbeddingConfigSchema.transform((data) => {
|
|
|
181957
182066
|
});
|
|
181958
182067
|
var MagicContextConfigSchema = exports_external.object({
|
|
181959
182068
|
enabled: exports_external.boolean().default(true).describe("Enable magic context (default: true)"),
|
|
182069
|
+
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."),
|
|
181960
182070
|
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)"),
|
|
181961
182071
|
historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
|
|
181962
182072
|
dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
|
|
@@ -182901,7 +183011,7 @@ class PiRetrospectiveRawProvider {
|
|
|
182901
183011
|
result.push({
|
|
182902
183012
|
sessionId: info.id,
|
|
182903
183013
|
path: info.path,
|
|
182904
|
-
updatedAt: typeof info.modified === "number" ? info.modified : undefined
|
|
183014
|
+
updatedAt: typeof info.modified === "number" ? info.modified : info.modified instanceof Date ? info.modified.getTime() : undefined
|
|
182905
183015
|
});
|
|
182906
183016
|
}
|
|
182907
183017
|
return result.sort((a, b) => (b.updatedAt ?? 0) - (a.updatedAt ?? 0));
|
|
@@ -182980,14 +183090,15 @@ function extractPiTextContent(content) {
|
|
|
182980
183090
|
}
|
|
182981
183091
|
async function loadDefaultPiSessionDeps2() {
|
|
182982
183092
|
const mod = await import(PI_CODING_AGENT_MODULE2);
|
|
182983
|
-
const
|
|
182984
|
-
const
|
|
182985
|
-
if (typeof
|
|
182986
|
-
throw new Error("Pi session APIs unavailable: expected SessionManager.
|
|
183093
|
+
const sessionListAll = mod.SessionManager?.listAll;
|
|
183094
|
+
const parseEntries = mod.parseSessionEntries;
|
|
183095
|
+
if (typeof sessionListAll !== "function" || typeof parseEntries !== "function") {
|
|
183096
|
+
throw new Error("Pi session APIs unavailable: expected SessionManager.listAll and parseSessionEntries");
|
|
182987
183097
|
}
|
|
183098
|
+
const { readFileSync: readFileSync9 } = await import("node:fs");
|
|
182988
183099
|
return {
|
|
182989
|
-
listSessions:
|
|
182990
|
-
loadEntriesFromFile
|
|
183100
|
+
listSessions: () => sessionListAll.call(mod.SessionManager),
|
|
183101
|
+
loadEntriesFromFile: (filePath) => parseEntries(readFileSync9(filePath, "utf-8"))
|
|
182991
183102
|
};
|
|
182992
183103
|
}
|
|
182993
183104
|
|
|
@@ -183018,6 +183129,7 @@ function registerPiDreamerProject(opts) {
|
|
|
183018
183129
|
projectIdentity: opts.projectIdentity,
|
|
183019
183130
|
client,
|
|
183020
183131
|
dreamerConfig: opts.config,
|
|
183132
|
+
language: opts.language,
|
|
183021
183133
|
gitCommitIndexing: opts.gitCommitIndexing,
|
|
183022
183134
|
ensureRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
183023
183135
|
retrospectiveRawProvider: () => new PiRetrospectiveRawProvider({ projectCwd: opts.projectDir }),
|
|
@@ -183032,7 +183144,7 @@ function registerPiDreamerProject(opts) {
|
|
|
183032
183144
|
const runManual = async (task) => runManualDream({
|
|
183033
183145
|
db: opts.db,
|
|
183034
183146
|
projectIdentity: opts.projectIdentity,
|
|
183035
|
-
tasks: buildDreamTaskRuntimeConfigs(opts.config),
|
|
183147
|
+
tasks: buildDreamTaskRuntimeConfigs(opts.config, opts.language),
|
|
183036
183148
|
executor: createDreamTaskExecutor({
|
|
183037
183149
|
client,
|
|
183038
183150
|
sessionDirectory: opts.projectDir,
|
|
@@ -183042,7 +183154,8 @@ function registerPiDreamerProject(opts) {
|
|
|
183042
183154
|
}),
|
|
183043
183155
|
primerRawProviderFactory: createPiPrimerRawProviderFactory(),
|
|
183044
183156
|
userMemoryCollectionEnabled: userMemoryCollectionEnabled(opts.config),
|
|
183045
|
-
ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory
|
|
183157
|
+
ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
183158
|
+
language: opts.language
|
|
183046
183159
|
}),
|
|
183047
183160
|
task
|
|
183048
183161
|
});
|
|
@@ -183951,6 +184064,7 @@ var pendingPiDecisionBySession = new Map;
|
|
|
183951
184064
|
var lastBoundMessageIdBySession = new Map;
|
|
183952
184065
|
var scheduledWriteTokensBySession = new Map;
|
|
183953
184066
|
var writerOverrideForTests = null;
|
|
184067
|
+
var retentionOverrideForTests = null;
|
|
183954
184068
|
function normalizeMaterializeReason(harness, reason, rematerialized) {
|
|
183955
184069
|
const raw = typeof reason === "string" ? reason.trim() : "";
|
|
183956
184070
|
if (raw.length > 0) {
|
|
@@ -184091,7 +184205,7 @@ function writeTransformDecisionRow(dbPath, row) {
|
|
|
184091
184205
|
WHERE session_id = ? AND harness = ?
|
|
184092
184206
|
ORDER BY ts_ms DESC, rowid DESC
|
|
184093
184207
|
LIMIT ?
|
|
184094
|
-
)`).run(row.sessionId, row.harness, row.sessionId, row.harness, TRANSFORM_DECISIONS_RETENTION);
|
|
184208
|
+
)`).run(row.sessionId, row.harness, row.sessionId, row.harness, retentionOverrideForTests ?? TRANSFORM_DECISIONS_RETENTION);
|
|
184095
184209
|
} finally {
|
|
184096
184210
|
closeQuietly(db);
|
|
184097
184211
|
}
|
|
@@ -185826,6 +185940,7 @@ function channel1RefireTokens(workingWindowTokens) {
|
|
|
185826
185940
|
var S_GENTLE = 0.2;
|
|
185827
185941
|
var S_FIRM = 0.4;
|
|
185828
185942
|
var S_URGENT = 0.65;
|
|
185943
|
+
var CHANNEL1_PRESSURE_FLOOR = 0.8;
|
|
185829
185944
|
var LEVEL_RANK = { gentle: 1, firm: 2, urgent: 3 };
|
|
185830
185945
|
var DROP_SENTINELS = ["[dropped", "[truncated"];
|
|
185831
185946
|
function isDroppedToolOutput(output) {
|
|
@@ -185836,7 +185951,8 @@ function toolOutputTokens(output) {
|
|
|
185836
185951
|
return Math.round(byteSize(output) * TOKENS_PER_BYTE);
|
|
185837
185952
|
}
|
|
185838
185953
|
function decideChannel1(input) {
|
|
185839
|
-
const { undroppedTokens,
|
|
185954
|
+
const { undroppedTokens, workingWindowTokens, hasRecentReduce } = input;
|
|
185955
|
+
const pressure = Math.min(1, Math.max(0, input.pressure));
|
|
185840
185956
|
const resetCycle = hasRecentReduce || undroppedTokens < input.lastNudgeUndropped;
|
|
185841
185957
|
const lastNudge = resetCycle ? 0 : input.lastNudgeUndropped;
|
|
185842
185958
|
const lastLevel = resetCycle ? "" : input.lastNudgeLevel;
|
|
@@ -185851,8 +185967,10 @@ function decideChannel1(input) {
|
|
|
185851
185967
|
return quiet();
|
|
185852
185968
|
if (undroppedTokens < CHANNEL1_FLOOR_TOKENS)
|
|
185853
185969
|
return quiet();
|
|
185854
|
-
|
|
185855
|
-
|
|
185970
|
+
if (pressure < CHANNEL1_PRESSURE_FLOOR)
|
|
185971
|
+
return quiet();
|
|
185972
|
+
const denom = Math.max(input.estimatedInputTokens, 1);
|
|
185973
|
+
const severity = Math.min(1, undroppedTokens / denom);
|
|
185856
185974
|
if (severity < S_GENTLE)
|
|
185857
185975
|
return quiet();
|
|
185858
185976
|
let level;
|
|
@@ -188168,6 +188286,7 @@ function maybeChannel1ReminderForToolResult(args) {
|
|
|
188168
188286
|
const decision = decideChannel1({
|
|
188169
188287
|
undroppedTokens,
|
|
188170
188288
|
pressure,
|
|
188289
|
+
estimatedInputTokens: state.lastInputTokens + state.turnToolTokens,
|
|
188171
188290
|
workingWindowTokens,
|
|
188172
188291
|
lastNudgeUndropped: getLastNudgeUndropped(db, sessionId),
|
|
188173
188292
|
lastNudgeLevel: getLastNudgeLevel(db, sessionId),
|
|
@@ -190975,8 +191094,8 @@ function buildHistorianFailureNotice(failureCount, lastError) {
|
|
|
190975
191094
|
].join(`
|
|
190976
191095
|
`);
|
|
190977
191096
|
}
|
|
190978
|
-
function buildHistorianRepairPrompt(originalPrompt, previousOutput, validationError) {
|
|
190979
|
-
|
|
191097
|
+
function buildHistorianRepairPrompt(originalPrompt, previousOutput, validationError, language) {
|
|
191098
|
+
const prompt = [
|
|
190980
191099
|
originalPrompt,
|
|
190981
191100
|
"",
|
|
190982
191101
|
"Your previous XML response was invalid and cannot be persisted.",
|
|
@@ -190989,6 +191108,7 @@ function buildHistorianRepairPrompt(originalPrompt, previousOutput, validationEr
|
|
|
190989
191108
|
previousOutput
|
|
190990
191109
|
].join(`
|
|
190991
191110
|
`);
|
|
191111
|
+
return withContentLanguageDirective(prompt, language, { preserveUserQuotes: true });
|
|
190992
191112
|
}
|
|
190993
191113
|
function validateStoredCompartments(compartments) {
|
|
190994
191114
|
if (compartments.length === 0) {
|
|
@@ -193112,9 +193232,11 @@ ${chunkText}`,
|
|
|
193112
193232
|
};
|
|
193113
193233
|
};
|
|
193114
193234
|
retainDrainReservationForRetryThrottle = true;
|
|
193235
|
+
const historianSystemPrompt = withContentLanguageDirective(COMPARTMENT_AGENT_SYSTEM_PROMPT, deps.language, { preserveUserQuotes: true });
|
|
193236
|
+
const historianEditorSystemPrompt = withContentLanguageDirective(HISTORIAN_EDITOR_SYSTEM_PROMPT, deps.language, { preserveUserQuotes: true });
|
|
193115
193237
|
const firstResult = await runner.run({
|
|
193116
193238
|
agent: HISTORIAN_AGENT_NAME,
|
|
193117
|
-
systemPrompt:
|
|
193239
|
+
systemPrompt: historianSystemPrompt,
|
|
193118
193240
|
userMessage: prompt,
|
|
193119
193241
|
model: historianModel,
|
|
193120
193242
|
fallbackModels,
|
|
@@ -193129,10 +193251,10 @@ ${chunkText}`,
|
|
|
193129
193251
|
let validatedDraftText = firstResult.ok ? firstResult.assistantText : null;
|
|
193130
193252
|
if (validatedPass.kind === "validation-failed") {
|
|
193131
193253
|
sessionLog(sessionId, `historian: first pass validation failed, retrying with repair prompt: ${validatedPass.error}`);
|
|
193132
|
-
const repairPrompt = buildHistorianRepairPrompt(prompt, validatedPass.rawText, validatedPass.error);
|
|
193254
|
+
const repairPrompt = buildHistorianRepairPrompt(prompt, validatedPass.rawText, validatedPass.error, deps.language);
|
|
193133
193255
|
const repairResult = await runner.run({
|
|
193134
193256
|
agent: HISTORIAN_AGENT_NAME,
|
|
193135
|
-
systemPrompt:
|
|
193257
|
+
systemPrompt: historianSystemPrompt,
|
|
193136
193258
|
userMessage: repairPrompt,
|
|
193137
193259
|
model: historianModel,
|
|
193138
193260
|
fallbackModels,
|
|
@@ -193157,7 +193279,7 @@ ${chunkText}`,
|
|
|
193157
193279
|
sessionLog(sessionId, `historian: escalating to configured fallback model ${candidate}`);
|
|
193158
193280
|
const fbResult = await runner.run({
|
|
193159
193281
|
agent: HISTORIAN_AGENT_NAME,
|
|
193160
|
-
systemPrompt:
|
|
193282
|
+
systemPrompt: historianSystemPrompt,
|
|
193161
193283
|
userMessage: prompt,
|
|
193162
193284
|
model: candidate,
|
|
193163
193285
|
fallbackModels: undefined,
|
|
@@ -193193,7 +193315,7 @@ ${chunkText}`,
|
|
|
193193
193315
|
sessionLog(sessionId, "historian two-pass: running editor on draft");
|
|
193194
193316
|
const editorResult = await runner.run({
|
|
193195
193317
|
agent: HISTORIAN_AGENT_NAME,
|
|
193196
|
-
systemPrompt:
|
|
193318
|
+
systemPrompt: historianEditorSystemPrompt,
|
|
193197
193319
|
userMessage: buildHistorianEditorPrompt(draftAssistantText),
|
|
193198
193320
|
model: historianModel,
|
|
193199
193321
|
timeoutMs: historianTimeoutMs,
|
|
@@ -194014,7 +194136,7 @@ Drop silently — do not narrate it. NEVER drop large ranges blindly (e.g., "1-5
|
|
|
194014
194136
|
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.`;
|
|
194015
194137
|
var CAVEMAN_COMPRESSION_WARNING = `
|
|
194016
194138
|
**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.`;
|
|
194017
|
-
function buildMagicContextSection(_agent, protectedTags, ctxReduceEnabled = true, dreamerEnabled = false, temporalAwarenessEnabled = false, cavemanTextCompressionEnabled = false, subagentMode = false) {
|
|
194139
|
+
function buildMagicContextSection(_agent, protectedTags, ctxReduceEnabled = true, dreamerEnabled = false, temporalAwarenessEnabled = false, cavemanTextCompressionEnabled = false, subagentMode = false, language) {
|
|
194018
194140
|
if (subagentMode) {
|
|
194019
194141
|
return `## Magic Context
|
|
194020
194142
|
|
|
@@ -194026,13 +194148,17 @@ The dreamer evaluates smart note conditions during nightly runs and surfaces the
|
|
|
194026
194148
|
Example: \`ctx_note(action="write", content="Implement X because Y", surface_condition="When PR #42 is merged in this repo")\`` : "";
|
|
194027
194149
|
const temporalGuidance = temporalAwarenessEnabled ? TEMPORAL_AWARENESS_GUIDANCE : "";
|
|
194028
194150
|
const cavemanWarning = cavemanTextCompressionEnabled && !ctxReduceEnabled ? CAVEMAN_COMPRESSION_WARNING : "";
|
|
194151
|
+
const languageDirective = buildPrimaryLanguageDirective(language);
|
|
194152
|
+
const languageGuidance = languageDirective ? `
|
|
194153
|
+
|
|
194154
|
+
${languageDirective}` : "";
|
|
194029
194155
|
if (!ctxReduceEnabled) {
|
|
194030
194156
|
return `## Magic Context
|
|
194031
194157
|
|
|
194032
194158
|
${LONG_TERM_PARTNER_FRAME}
|
|
194033
194159
|
${PARTNER_FRAME_CLOSER_NO_REDUCE}
|
|
194034
194160
|
|
|
194035
|
-
${BASE_INTRO_NO_REDUCE()}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}`;
|
|
194161
|
+
${BASE_INTRO_NO_REDUCE()}${smartNoteGuidance}${temporalGuidance}${cavemanWarning}${languageGuidance}`;
|
|
194036
194162
|
}
|
|
194037
194163
|
return `## Magic Context
|
|
194038
194164
|
|
|
@@ -194042,7 +194168,7 @@ ${PARTNER_FRAME_CLOSER_REDUCE}
|
|
|
194042
194168
|
${BASE_INTRO(protectedTags)}${smartNoteGuidance}${temporalGuidance}
|
|
194043
194169
|
${GENERIC_SECTION}
|
|
194044
194170
|
|
|
194045
|
-
Prefer many small targeted operations over one large blanket operation, and keep the working set tidy as routine maintenance
|
|
194171
|
+
Prefer many small targeted operations over one large blanket operation, and keep the working set tidy as routine maintenance.${languageGuidance}`;
|
|
194046
194172
|
}
|
|
194047
194173
|
|
|
194048
194174
|
// src/system-prompt.ts
|
|
@@ -194054,7 +194180,7 @@ function buildMagicContextBlock(opts) {
|
|
|
194054
194180
|
const includeGuidance = (opts.includeGuidance ?? true) && !existing.includes(MAGIC_CONTEXT_MARKER);
|
|
194055
194181
|
if (!includeGuidance)
|
|
194056
194182
|
return null;
|
|
194057
|
-
return buildMagicContextSection(null, opts.protectedTags ?? 20, opts.ctxReduceEnabled ?? true, opts.dreamerEnabled ?? false, opts.temporalAwarenessEnabled ?? false, opts.cavemanTextCompressionEnabled ?? false);
|
|
194183
|
+
return buildMagicContextSection(null, opts.protectedTags ?? 20, opts.ctxReduceEnabled ?? true, opts.dreamerEnabled ?? false, opts.temporalAwarenessEnabled ?? false, opts.cavemanTextCompressionEnabled ?? false, false, opts.language);
|
|
194058
194184
|
}
|
|
194059
194185
|
var DATE_PATTERN = /Today's date: .+/;
|
|
194060
194186
|
function processSystemPromptForCache(args) {
|
|
@@ -195746,6 +195872,7 @@ function spawnPiHistorianRun(args) {
|
|
|
195746
195872
|
memoryEnabled: historian.memoryEnabled,
|
|
195747
195873
|
autoPromote: historian.autoPromote,
|
|
195748
195874
|
userMemoriesEnabled: historian.userMemoriesEnabled,
|
|
195875
|
+
language: historian.language,
|
|
195749
195876
|
compartmentLeaseHolderId: holderId,
|
|
195750
195877
|
onPublished: () => {
|
|
195751
195878
|
const sessionStillActive = isContextHandlerSessionActive(sessionId);
|
|
@@ -196695,7 +196822,7 @@ async function runValidatedHistorianPass(args) {
|
|
|
196695
196822
|
return finalResult;
|
|
196696
196823
|
}
|
|
196697
196824
|
await args.callbacks?.onRepairRetry?.(firstValidation.error ?? "invalid compartment output");
|
|
196698
|
-
const repairPrompt = buildHistorianRepairPrompt(args.prompt, firstRun.result, firstValidation.error ?? "invalid compartment output");
|
|
196825
|
+
const repairPrompt = buildHistorianRepairPrompt(args.prompt, firstRun.result, firstValidation.error ?? "invalid compartment output", args.language);
|
|
196699
196826
|
const repairRun = await runHistorianPrompt({
|
|
196700
196827
|
...args,
|
|
196701
196828
|
prompt: repairPrompt,
|
|
@@ -197337,6 +197464,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
197337
197464
|
twoPass: deps.historianTwoPass,
|
|
197338
197465
|
subagentKind: "recomp",
|
|
197339
197466
|
agentId: HISTORIAN_RECOMP_AGENT,
|
|
197467
|
+
language: deps.language,
|
|
197340
197468
|
callbacks: {
|
|
197341
197469
|
onRepairRetry: async (error51) => {
|
|
197342
197470
|
emitProgress(`Repair retry (pass ${passCount + 1})…`);
|
|
@@ -197755,6 +197883,7 @@ Historian pass ${passCount + 1}, attempt ${passAttempt} started for messages ${c
|
|
|
197755
197883
|
twoPass: deps.historianTwoPass,
|
|
197756
197884
|
subagentKind: "recomp",
|
|
197757
197885
|
agentId: HISTORIAN_RECOMP_AGENT,
|
|
197886
|
+
language: deps.language,
|
|
197758
197887
|
callbacks: {
|
|
197759
197888
|
onRepairRetry: async (error51) => {
|
|
197760
197889
|
await sendIgnoredMessage(client, sessionId, `## Magic Recomp — Partial
|
|
@@ -198247,7 +198376,7 @@ Historian recomp started. Rebuilding compartments and facts from raw Pi session
|
|
|
198247
198376
|
client: createPiHistorianClient({
|
|
198248
198377
|
runner: deps.runner,
|
|
198249
198378
|
model: deps.historianModel,
|
|
198250
|
-
systemPrompt: COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT,
|
|
198379
|
+
systemPrompt: withContentLanguageDirective(COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, deps.language, { preserveUserQuotes: true }),
|
|
198251
198380
|
fallbackModels: deps.historianFallbacks,
|
|
198252
198381
|
timeoutMs: deps.historianTimeoutMs,
|
|
198253
198382
|
thinkingLevel: deps.historianThinkingLevel,
|
|
@@ -198270,6 +198399,7 @@ Historian recomp started. Rebuilding compartments and facts from raw Pi session
|
|
|
198270
198399
|
autoPromote: deps.autoPromote,
|
|
198271
198400
|
ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
198272
198401
|
fallbackModels: deps.historianFallbacks,
|
|
198402
|
+
language: deps.language,
|
|
198273
198403
|
fallbackModelId: ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : undefined
|
|
198274
198404
|
}, parsed.kind === "partial" ? { range: parsed.range } : {});
|
|
198275
198405
|
if (result.published) {
|
|
@@ -198522,7 +198652,7 @@ async function runPiMemoryMigration(deps) {
|
|
|
198522
198652
|
}
|
|
198523
198653
|
const result = await deps.runner.run({
|
|
198524
198654
|
agent: "magic-context-historian",
|
|
198525
|
-
systemPrompt: MIGRATION_SYSTEM_PROMPT2,
|
|
198655
|
+
systemPrompt: withMigrationLanguageDirective(MIGRATION_SYSTEM_PROMPT2, deps.language),
|
|
198526
198656
|
userMessage: prompt,
|
|
198527
198657
|
model,
|
|
198528
198658
|
fallbackModels: undefined,
|
|
@@ -198634,7 +198764,8 @@ An upgrade or recomp is already running for this session in the background. Wait
|
|
|
198634
198764
|
thinkingLevel: deps.historianThinkingLevel,
|
|
198635
198765
|
directory: ctx.cwd,
|
|
198636
198766
|
sessionId,
|
|
198637
|
-
userMemoriesEnabled: deps.userMemoriesEnabled
|
|
198767
|
+
userMemoriesEnabled: deps.userMemoriesEnabled,
|
|
198768
|
+
language: deps.language
|
|
198638
198769
|
});
|
|
198639
198770
|
return outcome.summary;
|
|
198640
198771
|
} catch (error51) {
|
|
@@ -198706,7 +198837,7 @@ Rebuilding compartments into the v2 format and re-organizing project memories. T
|
|
|
198706
198837
|
thinkingLevel: deps.historianThinkingLevel,
|
|
198707
198838
|
directory: ctx.cwd,
|
|
198708
198839
|
accountingSessionId: sessionId,
|
|
198709
|
-
systemPrompt: COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT,
|
|
198840
|
+
systemPrompt: withContentLanguageDirective(COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, deps.language, { preserveUserQuotes: true }),
|
|
198710
198841
|
notify: (text) => sendCtxStatusMessage(pi, {
|
|
198711
198842
|
title: "/ctx-session-upgrade",
|
|
198712
198843
|
text,
|
|
@@ -198722,7 +198853,8 @@ Rebuilding compartments into the v2 format and re-organizing project memories. T
|
|
|
198722
198853
|
autoPromote: deps.autoPromote,
|
|
198723
198854
|
ensureProjectRegistered: ensureProjectRegisteredFromPiDirectory,
|
|
198724
198855
|
fallbackModels: deps.historianFallbacks,
|
|
198725
|
-
fallbackModelId: sessionMainModel
|
|
198856
|
+
fallbackModelId: sessionMainModel,
|
|
198857
|
+
language: deps.language
|
|
198726
198858
|
}, {});
|
|
198727
198859
|
if (!recompResult.published || !isRecompComplete(recompResult.message)) {
|
|
198728
198860
|
const reason = contextualizeUpgradeReason(isRecompFailure(recompResult.message) ? extractRecompReason(recompResult.message) : `Compartments were not fully rebuilt: ${extractRecompReason(recompResult.message)}`);
|
|
@@ -198934,7 +199066,7 @@ function formatThresholdPercent(value) {
|
|
|
198934
199066
|
// package.json
|
|
198935
199067
|
var package_default = {
|
|
198936
199068
|
name: "@wolfx/pi-magic-context",
|
|
198937
|
-
version: "0.
|
|
199069
|
+
version: "0.28.0",
|
|
198938
199070
|
type: "module",
|
|
198939
199071
|
description: "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
198940
199072
|
main: "dist/index.js",
|
|
@@ -205113,7 +205245,8 @@ function resolveSidekickFromConfig(config2) {
|
|
|
205113
205245
|
systemPrompt: sidekick.system_prompt,
|
|
205114
205246
|
timeoutMs: sidekick.timeout_ms,
|
|
205115
205247
|
thinking_level: sidekick.thinking_level,
|
|
205116
|
-
fallbackModels: resolveFallbackChain(sidekick.fallback_models)
|
|
205248
|
+
fallbackModels: resolveFallbackChain(sidekick.fallback_models),
|
|
205249
|
+
language: config2.language
|
|
205117
205250
|
};
|
|
205118
205251
|
}
|
|
205119
205252
|
function resolveHistorianFromConfig(config2) {
|
|
@@ -205142,7 +205275,8 @@ function resolveHistorianFromConfig(config2) {
|
|
|
205142
205275
|
historyBudgetPercentage: config2.history_budget_percentage,
|
|
205143
205276
|
memoryEnabled: config2.memory.enabled,
|
|
205144
205277
|
autoPromote: config2.memory.auto_promote,
|
|
205145
|
-
userMemoriesEnabled: userMemoryCollectionEnabled(config2.dreamer)
|
|
205278
|
+
userMemoriesEnabled: userMemoryCollectionEnabled(config2.dreamer),
|
|
205279
|
+
language: config2.language
|
|
205146
205280
|
};
|
|
205147
205281
|
}
|
|
205148
205282
|
function resolveAutoSearchFromConfig(config2) {
|
|
@@ -205169,7 +205303,7 @@ async function src_default2(pi) {
|
|
|
205169
205303
|
return;
|
|
205170
205304
|
}
|
|
205171
205305
|
if (!db) {
|
|
205172
|
-
warn(`Magic Context (pi) storage unavailable at ${dbPath} (cache schema is newer than this binary supports). ` + "Plugin will not register hooks;
|
|
205306
|
+
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.");
|
|
205173
205307
|
return;
|
|
205174
205308
|
}
|
|
205175
205309
|
const database = db;
|
|
@@ -205257,6 +205391,7 @@ async function src_default2(pi) {
|
|
|
205257
205391
|
executeThresholdTokens: cfg.execute_threshold_tokens
|
|
205258
205392
|
},
|
|
205259
205393
|
historian: hist,
|
|
205394
|
+
language: cfg.language,
|
|
205260
205395
|
autoSearch: auto,
|
|
205261
205396
|
resolveForProject: resolveContextOptionsForProject,
|
|
205262
205397
|
maybeAutoEmbedSession: (sessionId, dir, identity) => {
|
|
@@ -205329,6 +205464,7 @@ async function src_default2(pi) {
|
|
|
205329
205464
|
historianFallbacks: historianConfig?.fallbackModels,
|
|
205330
205465
|
historianTimeoutMs: config2.historian_timeout_ms,
|
|
205331
205466
|
historianThinkingLevel: historianConfig?.thinkingLevel,
|
|
205467
|
+
language: config2.language,
|
|
205332
205468
|
memoryEnabled: config2.memory.enabled,
|
|
205333
205469
|
autoPromote: config2.memory.auto_promote
|
|
205334
205470
|
});
|
|
@@ -205341,6 +205477,7 @@ async function src_default2(pi) {
|
|
|
205341
205477
|
historianFallbacks: historianConfig?.fallbackModels,
|
|
205342
205478
|
historianTimeoutMs: config2.historian_timeout_ms,
|
|
205343
205479
|
historianThinkingLevel: historianConfig?.thinkingLevel,
|
|
205480
|
+
language: config2.language,
|
|
205344
205481
|
memoryEnabled: config2.memory.enabled,
|
|
205345
205482
|
autoPromote: config2.memory.auto_promote,
|
|
205346
205483
|
userMemoriesEnabled: userMemoryCollectionEnabled(config2.dreamer)
|
|
@@ -205372,6 +205509,7 @@ async function src_default2(pi) {
|
|
|
205372
205509
|
config: dreamerConfig,
|
|
205373
205510
|
embeddingConfig: config2.embedding,
|
|
205374
205511
|
memoryEnabled: config2.memory.enabled,
|
|
205512
|
+
language: config2.language,
|
|
205375
205513
|
gitCommitIndexing: config2.memory.git_commit_indexing,
|
|
205376
205514
|
onAdjunctsRefreshNeeded: signalPiSystemPromptRefreshForProject
|
|
205377
205515
|
});
|
|
@@ -205486,6 +205624,7 @@ async function src_default2(pi) {
|
|
|
205486
205624
|
dreamerEnabled: effectiveDreamerRunnable,
|
|
205487
205625
|
temporalAwarenessEnabled: effectiveConfig.temporal_awareness ?? false,
|
|
205488
205626
|
cavemanTextCompressionEnabled: effectiveConfig.ctx_reduce_enabled === false && effectiveConfig.caveman_text_compression?.enabled === true,
|
|
205627
|
+
language: effectiveConfig.language,
|
|
205489
205628
|
userMemoriesEnabled: userMemoryCollectionEnabled(effectiveConfig.dreamer),
|
|
205490
205629
|
isCacheBusting,
|
|
205491
205630
|
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 = {
|
|
@@ -144839,6 +144839,10 @@ function stripUnsafeProjectConfigFields(projectRaw) {
|
|
|
144839
144839
|
delete projectRaw.auto_update;
|
|
144840
144840
|
warnings.push("Ignoring auto_update from project config (security: this setting only honors user-level config).");
|
|
144841
144841
|
}
|
|
144842
|
+
if ("language" in projectRaw) {
|
|
144843
|
+
delete projectRaw.language;
|
|
144844
|
+
warnings.push("Ignoring language from project config (security: output language is a user-level setting).");
|
|
144845
|
+
}
|
|
144842
144846
|
if ("sqlite" in projectRaw) {
|
|
144843
144847
|
delete projectRaw.sqlite;
|
|
144844
144848
|
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).");
|
|
@@ -159184,6 +159188,95 @@ function date4(params) {
|
|
|
159184
159188
|
|
|
159185
159189
|
// ../../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
159186
159190
|
config(en_default());
|
|
159191
|
+
// ../plugin/src/agents/language-directive.ts
|
|
159192
|
+
var ENGLISH_LANGUAGE_NAMES = new Intl.DisplayNames(["en"], {
|
|
159193
|
+
type: "language",
|
|
159194
|
+
fallback: "none"
|
|
159195
|
+
});
|
|
159196
|
+
function resolveLanguageName(language) {
|
|
159197
|
+
const code = typeof language === "string" ? language.trim().toLowerCase() : "";
|
|
159198
|
+
if (!/^[a-z]{2}$/.test(code))
|
|
159199
|
+
return "";
|
|
159200
|
+
let english;
|
|
159201
|
+
try {
|
|
159202
|
+
english = ENGLISH_LANGUAGE_NAMES.of(code) ?? undefined;
|
|
159203
|
+
} catch {
|
|
159204
|
+
return "";
|
|
159205
|
+
}
|
|
159206
|
+
if (!english)
|
|
159207
|
+
return "";
|
|
159208
|
+
let endonym;
|
|
159209
|
+
try {
|
|
159210
|
+
endonym = new Intl.DisplayNames([code], { type: "language", fallback: "none" }).of(code) ?? undefined;
|
|
159211
|
+
} catch {
|
|
159212
|
+
endonym = undefined;
|
|
159213
|
+
}
|
|
159214
|
+
return endonym && endonym !== english ? `${english} (${endonym})` : english;
|
|
159215
|
+
}
|
|
159216
|
+
function isValidLanguageCode(language) {
|
|
159217
|
+
return resolveLanguageName(language) !== "";
|
|
159218
|
+
}
|
|
159219
|
+
function buildContentLanguageDirective(language, options = {}) {
|
|
159220
|
+
const target = resolveLanguageName(language);
|
|
159221
|
+
if (!target)
|
|
159222
|
+
return "";
|
|
159223
|
+
const lines = [
|
|
159224
|
+
"## Output language",
|
|
159225
|
+
"",
|
|
159226
|
+
`Write human-readable prose you author in: ${target}.`,
|
|
159227
|
+
"",
|
|
159228
|
+
"Do not translate or rename structural tokens. Copy required output schemas exactly:",
|
|
159229
|
+
"- 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.",
|
|
159230
|
+
"- 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.",
|
|
159231
|
+
"- Localize only free-text prose values/content: summaries, memory text, explanations, titles, observations, and answers — unless the prompt says to preserve original wording.",
|
|
159232
|
+
"",
|
|
159233
|
+
"These literal values must remain English when used:",
|
|
159234
|
+
"PROJECT_RULES, ARCHITECTURE, CONSTRAINTS, CONFIG_VALUES, NAMING;",
|
|
159235
|
+
"causal_incident, trajectory_correction;",
|
|
159236
|
+
"feature, design, docs, release, investigation, bug, refactor, infra;",
|
|
159237
|
+
"memory, observation; true, false; No relevant memories found.",
|
|
159238
|
+
"",
|
|
159239
|
+
"Preserve the required output shape. Do not add commentary outside the requested XML/JSON/tool output."
|
|
159240
|
+
];
|
|
159241
|
+
if (options.preserveUserQuotes) {
|
|
159242
|
+
lines.push("", `Preserve U: lines and directly quoted user text in their original source language; write the surrounding summary prose in ${target}.`);
|
|
159243
|
+
}
|
|
159244
|
+
if (options.retrospective) {
|
|
159245
|
+
lines.push("", `Write the lesson text in ${target}; paraphrase source text and never quote the user.`);
|
|
159246
|
+
}
|
|
159247
|
+
return lines.join(`
|
|
159248
|
+
`);
|
|
159249
|
+
}
|
|
159250
|
+
function withContentLanguageDirective(systemPrompt, language, options = {}) {
|
|
159251
|
+
const directive = buildContentLanguageDirective(language, options);
|
|
159252
|
+
return directive ? `${systemPrompt}
|
|
159253
|
+
|
|
159254
|
+
${directive}` : systemPrompt;
|
|
159255
|
+
}
|
|
159256
|
+
function buildMigrationLanguageDirective(language) {
|
|
159257
|
+
const target = resolveLanguageName(language);
|
|
159258
|
+
if (!target)
|
|
159259
|
+
return "";
|
|
159260
|
+
return [
|
|
159261
|
+
"## Output language",
|
|
159262
|
+
"",
|
|
159263
|
+
"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."
|
|
159264
|
+
].join(`
|
|
159265
|
+
`);
|
|
159266
|
+
}
|
|
159267
|
+
function withMigrationLanguageDirective(systemPrompt, language) {
|
|
159268
|
+
const directive = buildMigrationLanguageDirective(language);
|
|
159269
|
+
return directive ? `${systemPrompt}
|
|
159270
|
+
|
|
159271
|
+
${directive}` : systemPrompt;
|
|
159272
|
+
}
|
|
159273
|
+
function buildPrimaryLanguageDirective(language) {
|
|
159274
|
+
const target = resolveLanguageName(language);
|
|
159275
|
+
if (!target)
|
|
159276
|
+
return "";
|
|
159277
|
+
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.`;
|
|
159278
|
+
}
|
|
159279
|
+
|
|
159187
159280
|
// ../plugin/src/features/magic-context/defaults.ts
|
|
159188
159281
|
var DEFAULT_PROTECTED_TAGS = 20;
|
|
159189
159282
|
|
|
@@ -159531,6 +159624,7 @@ var EmbeddingConfigSchema = BaseEmbeddingConfigSchema.transform((data) => {
|
|
|
159531
159624
|
});
|
|
159532
159625
|
var MagicContextConfigSchema = exports_external.object({
|
|
159533
159626
|
enabled: exports_external.boolean().default(true).describe("Enable magic context (default: true)"),
|
|
159627
|
+
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."),
|
|
159534
159628
|
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)"),
|
|
159535
159629
|
historian: HistorianConfigSchema.describe("Historian agent configuration (model, fallback_models, variant, temperature, maxTokens, permission, two_pass, etc.)"),
|
|
159536
159630
|
dreamer: DreamerConfigSchema.optional().describe("Dreamer agent + scheduling configuration (model, fallback_models, disable, schedule, tasks, etc.)"),
|
|
@@ -171098,6 +171192,9 @@ function getActiveTagTokenAggregate(db, sessionId, protectedTags = 0) {
|
|
|
171098
171192
|
nullCount: row?.null_count ?? 0
|
|
171099
171193
|
};
|
|
171100
171194
|
}
|
|
171195
|
+
var RECLAIM_HINT_EXCLUDED_TOOLS = ["todowrite"];
|
|
171196
|
+
var RECLAIM_HINT_MIN_TOKENS = 250;
|
|
171197
|
+
var RECLAIM_HINT_EXCLUDED_LIST = RECLAIM_HINT_EXCLUDED_TOOLS.map((name2) => `'${name2.replace(/'/g, "''")}'`).join(", ");
|
|
171101
171198
|
function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, limit = 4) {
|
|
171102
171199
|
if (limit <= 0)
|
|
171103
171200
|
return [];
|
|
@@ -171107,10 +171204,18 @@ function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, li
|
|
|
171107
171204
|
WHERE session_id = ? AND status = 'active'
|
|
171108
171205
|
ORDER BY tag_number DESC LIMIT 1 OFFSET ?
|
|
171109
171206
|
)` : "";
|
|
171110
|
-
const
|
|
171207
|
+
const excludeStateTools = RECLAIM_HINT_EXCLUDED_LIST ? `AND (tool_name IS NULL OR tool_name NOT IN (${RECLAIM_HINT_EXCLUDED_LIST}))` : "";
|
|
171208
|
+
const valueFloor = `AND (
|
|
171209
|
+
(token_count IS NULL AND input_token_count IS NULL)
|
|
171210
|
+
OR (COALESCE(token_count, 0) + COALESCE(input_token_count, 0)) >= ?
|
|
171211
|
+
)`;
|
|
171212
|
+
const params = protectedTags > 0 ? [sessionId, RECLAIM_HINT_MIN_TOKENS, sessionId, protectedTags - 1, boundedLimit] : [sessionId, RECLAIM_HINT_MIN_TOKENS, boundedLimit];
|
|
171111
171213
|
const rows = db.prepare(`SELECT tag_number, tool_name
|
|
171112
171214
|
FROM tags
|
|
171113
|
-
WHERE session_id = ? AND status = 'active' AND type = 'tool'
|
|
171215
|
+
WHERE session_id = ? AND status = 'active' AND type = 'tool'
|
|
171216
|
+
${excludeStateTools}
|
|
171217
|
+
${valueFloor}
|
|
171218
|
+
${whereProtected}
|
|
171114
171219
|
ORDER BY tag_number ASC, id ASC
|
|
171115
171220
|
LIMIT ?`).all(...params);
|
|
171116
171221
|
return rows.filter((row) => typeof row.tag_number === "number").map((row) => ({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wolfx/pi-magic-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Pi coding agent extension for Magic Context — cross-session memory and context management",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -37,7 +37,6 @@
|
|
|
37
37
|
"prepublishOnly": "bun run build"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
|
|
41
40
|
"ai-tokenizer": "^1.0.6",
|
|
42
41
|
"comment-json": "^4.2.5",
|
|
43
42
|
"quickjs-emscripten": "^0.32.0",
|