49a1a68a29
Add fail-open headroom provider routing for goosed sync, context-budget planning with shadow telemetry events, and fix portal-resume smoke to skip force_deep_reasoning by default so session round-trip checks stay fast. Co-authored-by: Cursor <cursoragent@cursor.com>
361 lines
9.9 KiB
JavaScript
361 lines
9.9 KiB
JavaScript
import crypto from 'node:crypto';
|
|
|
|
export const CONTEXT_BUDGET_MODES = Object.freeze(['off', 'shadow', 'active']);
|
|
export const DEFAULT_CONTEXT_BUDGET_MAX_CHARS = 12_000;
|
|
|
|
const SOURCE_PRIORITY = Object.freeze({
|
|
user_task: 100,
|
|
skill_prompt: 90,
|
|
goal: 85,
|
|
temporal: 75,
|
|
memory: 65,
|
|
harness: 50,
|
|
});
|
|
|
|
const HARNESS_TITLE_PRIORITY = Object.freeze({
|
|
'TKMind 用户空间沙箱': 95,
|
|
'TKMind 当前时间基准': 94,
|
|
'TKMind 代码委托策略': 88,
|
|
'TKMind 日程写入规则': 82,
|
|
'TKMind 定时自动任务规则': 82,
|
|
'TKMind 长期记忆规则': 58,
|
|
'TKMind 用户偏好画像': 57,
|
|
'TKMind 已沉淀用户记忆': 56,
|
|
});
|
|
|
|
function normalizeMode(value, fallback = 'off') {
|
|
const raw = String(value ?? fallback).trim().toLowerCase();
|
|
return CONTEXT_BUDGET_MODES.includes(raw) ? raw : fallback;
|
|
}
|
|
|
|
export function resolveContextBudgetMode(env = process.env) {
|
|
return normalizeMode(env.MEMIND_CONTEXT_BUDGET_MODE, 'off');
|
|
}
|
|
|
|
export function resolveContextBudgetMaxChars(env = process.env) {
|
|
const raw = Number(env.MEMIND_CONTEXT_BUDGET_MAX_CHARS ?? DEFAULT_CONTEXT_BUDGET_MAX_CHARS);
|
|
return Number.isFinite(raw) && raw > 0 ? Math.floor(raw) : DEFAULT_CONTEXT_BUDGET_MAX_CHARS;
|
|
}
|
|
|
|
export function fingerprintContent(text) {
|
|
const normalized = String(text ?? '')
|
|
.replace(/\s+/g, ' ')
|
|
.trim()
|
|
.toLowerCase();
|
|
if (!normalized) return null;
|
|
return crypto.createHash('sha256').update(normalized).digest('hex').slice(0, 16);
|
|
}
|
|
|
|
function blockPriority(block) {
|
|
const source = String(block?.source ?? '').trim();
|
|
const base = SOURCE_PRIORITY[source] ?? 40;
|
|
if (source !== 'harness') return base;
|
|
const title = String(block?.title ?? block?.label ?? '').trim();
|
|
return HARNESS_TITLE_PRIORITY[title] ?? base;
|
|
}
|
|
|
|
function blockChars(block) {
|
|
return String(block?.text ?? block?.content ?? '').length;
|
|
}
|
|
|
|
function normalizeMemoryBlock(item) {
|
|
const label = String(item?.label ?? item?.title ?? '').trim();
|
|
const text = String(item?.text ?? item?.content ?? item?.summary ?? '').trim();
|
|
if (!text) return null;
|
|
return {
|
|
source: 'memory',
|
|
id: String(item?.id ?? item?.memoryId ?? label ?? text.slice(0, 32)),
|
|
label: label || null,
|
|
text,
|
|
fingerprint: fingerprintContent(text),
|
|
priority: SOURCE_PRIORITY.memory,
|
|
chars: text.length,
|
|
};
|
|
}
|
|
|
|
function normalizeHarnessBlock(entry) {
|
|
const title = String(entry?.title ?? '').trim();
|
|
const text = String(entry?.content ?? entry?.text ?? '').trim();
|
|
if (!text) return null;
|
|
return {
|
|
source: 'harness',
|
|
id: title || text.slice(0, 32),
|
|
title: title || null,
|
|
text,
|
|
fingerprint: fingerprintContent(text),
|
|
priority: blockPriority({ source: 'harness', title }),
|
|
chars: text.length,
|
|
};
|
|
}
|
|
|
|
export function buildContextBudgetBlocks({
|
|
memories = [],
|
|
temporalText = '',
|
|
goalEnvelope = '',
|
|
harnessEntries = [],
|
|
skillPrompt = '',
|
|
userTask = '',
|
|
} = {}) {
|
|
const blocks = [];
|
|
|
|
const task = String(userTask ?? '').trim();
|
|
if (task) {
|
|
blocks.push({
|
|
source: 'user_task',
|
|
id: 'user_task',
|
|
text: task,
|
|
fingerprint: fingerprintContent(task),
|
|
priority: SOURCE_PRIORITY.user_task,
|
|
chars: task.length,
|
|
});
|
|
}
|
|
|
|
const skill = String(skillPrompt ?? '').trim();
|
|
if (skill) {
|
|
blocks.push({
|
|
source: 'skill_prompt',
|
|
id: 'skill_prompt',
|
|
text: skill,
|
|
fingerprint: fingerprintContent(skill),
|
|
priority: SOURCE_PRIORITY.skill_prompt,
|
|
chars: skill.length,
|
|
});
|
|
}
|
|
|
|
const goal = String(goalEnvelope ?? '').trim();
|
|
if (goal) {
|
|
blocks.push({
|
|
source: 'goal',
|
|
id: 'goal',
|
|
text: goal,
|
|
fingerprint: fingerprintContent(goal),
|
|
priority: SOURCE_PRIORITY.goal,
|
|
chars: goal.length,
|
|
});
|
|
}
|
|
|
|
const temporal = String(temporalText ?? '').trim();
|
|
if (temporal) {
|
|
blocks.push({
|
|
source: 'temporal',
|
|
id: 'temporal',
|
|
text: temporal,
|
|
fingerprint: fingerprintContent(temporal),
|
|
priority: SOURCE_PRIORITY.temporal,
|
|
chars: temporal.length,
|
|
});
|
|
}
|
|
|
|
for (const item of Array.isArray(memories) ? memories : []) {
|
|
const block = normalizeMemoryBlock(item);
|
|
if (block) blocks.push(block);
|
|
}
|
|
|
|
for (const entry of Array.isArray(harnessEntries) ? harnessEntries : []) {
|
|
const block = normalizeHarnessBlock(entry);
|
|
if (block) blocks.push(block);
|
|
}
|
|
|
|
return blocks;
|
|
}
|
|
|
|
export function planContextBudget(input = {}, { maxChars, env = process.env } = {}) {
|
|
const mode = resolveContextBudgetMode(env);
|
|
const budget = Number.isFinite(maxChars) ? maxChars : resolveContextBudgetMaxChars(env);
|
|
const blocks = buildContextBudgetBlocks(input);
|
|
const seenFingerprints = new Set();
|
|
const kept = [];
|
|
const droppedItems = [];
|
|
const duplicateItems = [];
|
|
|
|
const sorted = [...blocks].sort((a, b) => {
|
|
const priorityDelta = blockPriority(b) - blockPriority(a);
|
|
if (priorityDelta !== 0) return priorityDelta;
|
|
return blockChars(a) - blockChars(b);
|
|
});
|
|
|
|
let totalChars = 0;
|
|
for (const block of sorted) {
|
|
if (block.source === 'user_task') {
|
|
kept.push(block);
|
|
totalChars += block.chars;
|
|
if (block.fingerprint) seenFingerprints.add(block.fingerprint);
|
|
continue;
|
|
}
|
|
|
|
if (block.fingerprint && seenFingerprints.has(block.fingerprint)) {
|
|
duplicateItems.push({
|
|
source: block.source,
|
|
id: block.id,
|
|
reason: 'duplicate_fingerprint',
|
|
fingerprint: block.fingerprint,
|
|
chars: block.chars,
|
|
});
|
|
continue;
|
|
}
|
|
|
|
if (totalChars + block.chars > budget) {
|
|
droppedItems.push({
|
|
source: block.source,
|
|
id: block.id,
|
|
reason: 'over_budget',
|
|
fingerprint: block.fingerprint ?? null,
|
|
chars: block.chars,
|
|
priority: blockPriority(block),
|
|
});
|
|
continue;
|
|
}
|
|
|
|
kept.push(block);
|
|
totalChars += block.chars;
|
|
if (block.fingerprint) seenFingerprints.add(block.fingerprint);
|
|
}
|
|
|
|
const fingerprints = [...seenFingerprints];
|
|
return {
|
|
mode,
|
|
budget,
|
|
blocks: kept,
|
|
droppedItems,
|
|
duplicateItems,
|
|
totalChars,
|
|
fingerprints,
|
|
inputBlockCount: blocks.length,
|
|
keptBlockCount: kept.length,
|
|
};
|
|
}
|
|
|
|
export function applyContextBudgetToOrchestration({
|
|
memoryContext = null,
|
|
goalContext = null,
|
|
runtimeContext = null,
|
|
skillPrompt = '',
|
|
userTask = '',
|
|
plan = null,
|
|
env = process.env,
|
|
} = {}) {
|
|
const mode = resolveContextBudgetMode(env);
|
|
if (mode === 'off') {
|
|
return {
|
|
memoryContext,
|
|
goalContext,
|
|
runtimeContext,
|
|
skillPrompt,
|
|
plan: null,
|
|
applied: false,
|
|
};
|
|
}
|
|
|
|
const resolvedPlan = plan ?? planContextBudget({
|
|
memories: memoryContext?.injectionEnabled ? memoryContext.memories : [],
|
|
temporalText: runtimeContext?.injectionEnabled ? runtimeContext.injectionText : '',
|
|
goalEnvelope: goalContext?.injectionEnabled ? goalContext.envelope : '',
|
|
skillPrompt,
|
|
userTask,
|
|
}, { env });
|
|
|
|
if (mode === 'shadow') {
|
|
return {
|
|
memoryContext,
|
|
goalContext,
|
|
runtimeContext,
|
|
skillPrompt,
|
|
plan: resolvedPlan,
|
|
applied: false,
|
|
};
|
|
}
|
|
|
|
const keptBySource = {
|
|
memory: new Set(),
|
|
goal: false,
|
|
temporal: false,
|
|
skill_prompt: false,
|
|
};
|
|
|
|
for (const block of resolvedPlan.blocks) {
|
|
if (block.source === 'memory') keptBySource.memory.add(block.id);
|
|
if (block.source === 'goal') keptBySource.goal = true;
|
|
if (block.source === 'temporal') keptBySource.temporal = true;
|
|
if (block.source === 'skill_prompt') keptBySource.skill_prompt = true;
|
|
}
|
|
|
|
const nextMemoryContext = memoryContext?.injectionEnabled
|
|
? {
|
|
...memoryContext,
|
|
memories: (Array.isArray(memoryContext.memories) ? memoryContext.memories : [])
|
|
.filter((item, index) => {
|
|
const label = String(item?.label ?? item?.title ?? '').trim();
|
|
const text = String(item?.text ?? item?.content ?? item?.summary ?? '').trim();
|
|
const id = String(item?.id ?? item?.memoryId ?? label ?? (text.slice(0, 32) || `memory-${index}`));
|
|
return keptBySource.memory.has(id);
|
|
}),
|
|
}
|
|
: memoryContext;
|
|
|
|
const nextGoalContext = goalContext?.injectionEnabled && !keptBySource.goal
|
|
? { ...goalContext, injectionEnabled: false, envelope: '' }
|
|
: goalContext;
|
|
|
|
const nextRuntimeContext = runtimeContext?.injectionEnabled && !keptBySource.temporal
|
|
? { ...runtimeContext, injectionEnabled: false, injectionText: '' }
|
|
: runtimeContext;
|
|
|
|
const nextSkillPrompt = keptBySource.skill_prompt ? skillPrompt : '';
|
|
|
|
return {
|
|
memoryContext: nextMemoryContext,
|
|
goalContext: nextGoalContext,
|
|
runtimeContext: nextRuntimeContext,
|
|
skillPrompt: nextSkillPrompt,
|
|
plan: resolvedPlan,
|
|
applied: true,
|
|
};
|
|
}
|
|
|
|
export function applyContextBudgetToHarnessEntries(entries = [], { plan = null, env = process.env } = {}) {
|
|
const mode = resolveContextBudgetMode(env);
|
|
if (mode !== 'active') {
|
|
return {
|
|
entries,
|
|
plan: plan ?? (mode === 'shadow'
|
|
? planContextBudget({ harnessEntries: entries }, { env })
|
|
: null),
|
|
applied: false,
|
|
};
|
|
}
|
|
|
|
const resolvedPlan = plan ?? planContextBudget({ harnessEntries: entries }, { env });
|
|
const keptIds = new Set(
|
|
resolvedPlan.blocks
|
|
.filter((block) => block.source === 'harness')
|
|
.map((block) => block.id),
|
|
);
|
|
|
|
return {
|
|
entries: entries.filter((entry) => {
|
|
const title = String(entry?.title ?? '').trim();
|
|
const text = String(entry?.content ?? entry?.text ?? '').trim();
|
|
const id = title || text.slice(0, 32);
|
|
return keptIds.has(id);
|
|
}),
|
|
plan: resolvedPlan,
|
|
applied: true,
|
|
};
|
|
}
|
|
|
|
export function buildContextBudgetResolvedEvent(plan) {
|
|
if (!plan) return null;
|
|
return {
|
|
mode: plan.mode,
|
|
budget: plan.budget,
|
|
totalChars: plan.totalChars,
|
|
inputBlockCount: plan.inputBlockCount,
|
|
keptBlockCount: plan.keptBlockCount,
|
|
droppedCount: plan.droppedItems.length,
|
|
duplicateCount: plan.duplicateItems.length,
|
|
droppedItems: plan.droppedItems,
|
|
duplicateItems: plan.duplicateItems,
|
|
fingerprints: plan.fingerprints,
|
|
};
|
|
}
|