import assert from 'node:assert/strict'; import test from 'node:test'; import { applyContextBudgetToHarnessEntries, applyContextBudgetToOrchestration, buildContextBudgetBlocks, fingerprintContent, planContextBudget, resolveContextBudgetMode, } from './context-budget.mjs'; test('resolveContextBudgetMode defaults to off', () => { assert.equal(resolveContextBudgetMode({}), 'off'); assert.equal(resolveContextBudgetMode({ MEMIND_CONTEXT_BUDGET_MODE: 'shadow' }), 'shadow'); assert.equal(resolveContextBudgetMode({ MEMIND_CONTEXT_BUDGET_MODE: 'bogus' }), 'off'); }); test('fingerprintContent normalizes whitespace and case', () => { assert.equal( fingerprintContent(' Hello World '), fingerprintContent('hello world'), ); }); test('planContextBudget dedupes duplicate fingerprints across sources', () => { const duplicate = '用户偏好:喜欢简洁回答'; const plan = planContextBudget({ memories: [{ label: '偏好', text: duplicate }], harnessEntries: [{ title: 'TKMind 用户偏好画像', content: duplicate }], userTask: '帮我总结今天的工作', }, { maxChars: 10_000, env: { MEMIND_CONTEXT_BUDGET_MODE: 'shadow' }, }); assert.equal(plan.duplicateItems.length, 1); assert.equal(plan.keptBlockCount, plan.inputBlockCount - 1); }); test('planContextBudget drops lower-priority blocks when over budget', () => { const plan = planContextBudget({ userTask: 'task', skillPrompt: 'skill', goalEnvelope: 'goal', temporalText: 'temporal', memories: [{ label: 'm1', text: 'memory-one' }], harnessEntries: [{ title: 'TKMind 已沉淀用户记忆', content: 'stored-memory' }], }, { maxChars: 20, env: { MEMIND_CONTEXT_BUDGET_MODE: 'active' }, }); assert.ok(plan.droppedItems.length > 0); assert.ok(plan.blocks.some((block) => block.source === 'user_task')); assert.ok(plan.droppedItems.every((item) => item.source !== 'user_task')); }); test('applyContextBudgetToOrchestration is no-op in shadow mode', () => { const memoryContext = { injectionEnabled: true, memories: [{ label: 'a', text: 'alpha' }, { label: 'b', text: 'beta' }], }; const applied = applyContextBudgetToOrchestration({ memoryContext, userTask: 'do work', env: { MEMIND_CONTEXT_BUDGET_MODE: 'shadow', MEMIND_CONTEXT_BUDGET_MAX_CHARS: '10' }, }); assert.equal(applied.applied, false); assert.equal(applied.memoryContext.memories.length, 2); assert.ok(applied.plan); }); test('applyContextBudgetToHarnessEntries filters in active mode', () => { const entries = [ { title: 'TKMind 当前时间基准', content: 'time anchor' }, { title: 'TKMind 已沉淀用户记忆', content: 'long '.repeat(200) }, ]; const applied = applyContextBudgetToHarnessEntries(entries, { env: { MEMIND_CONTEXT_BUDGET_MODE: 'active', MEMIND_CONTEXT_BUDGET_MAX_CHARS: '40', }, }); assert.equal(applied.applied, true); assert.ok(applied.entries.length < entries.length); assert.ok(applied.entries.some((entry) => entry.title === 'TKMind 当前时间基准')); }); test('buildContextBudgetBlocks preserves source metadata', () => { const blocks = buildContextBudgetBlocks({ userTask: 'hello', harnessEntries: [{ title: 'TKMind 用户空间沙箱', content: 'sandbox rules' }], }); assert.ok(blocks.some((block) => block.source === 'user_task')); assert.ok(blocks.some((block) => block.source === 'harness' && block.priority >= 90)); });