Overwrite foreign steps/cfg in sparse patches when the user did not ask for params, and skip the cold-load path when Ollama already has the chat model resident. Co-authored-by: Cursor <cursoragent@cursor.com>
155 lines
5.1 KiB
JavaScript
155 lines
5.1 KiB
JavaScript
import { describe, it } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {
|
|
extractPatch,
|
|
isPatchObject,
|
|
normalizePatch,
|
|
setPatchKeys,
|
|
} from '../src/patch.js';
|
|
import {
|
|
mergeDelta,
|
|
emptySession,
|
|
patchWantsGenerate,
|
|
sessionFromLegacyParams,
|
|
toPersistParams,
|
|
resolveTurnIntent,
|
|
mergeExactParamsForGenerate,
|
|
resolveExactProfileDefaults,
|
|
} from '../src/session.js';
|
|
|
|
describe('patch.js', () => {
|
|
it('extractPatch finds generation patch in fence', () => {
|
|
const text = 'Here you go\n```json\n{"prompt":"A red fox in snow","generate":true}\n```';
|
|
const { prose, patch } = extractPatch(text);
|
|
assert.ok(patch);
|
|
assert.equal(patch.prompt, 'A red fox in snow');
|
|
assert.equal(patch.generate, true);
|
|
assert.ok(!prose.includes('```'));
|
|
});
|
|
|
|
it('normalizePatch maps legacy actions generate', () => {
|
|
const p = normalizePatch({ prompt: 'x', actions: ['generate'] });
|
|
assert.equal(p.generate, true);
|
|
});
|
|
|
|
it('scheduler-only patch is detected with full key list', () => {
|
|
setPatchKeys(['prompt', 'scheduler', 'generate', 'ask']);
|
|
assert.equal(isPatchObject({ scheduler: 'euler' }), true);
|
|
});
|
|
});
|
|
|
|
describe('session.js', () => {
|
|
it('mergeDelta is sparse and keeps other fields', () => {
|
|
let s = emptySession();
|
|
s.gen.prompt = 'old';
|
|
s.gen.steps = 8;
|
|
s = mergeDelta(s, { aspect: '16:9', generate: true });
|
|
assert.equal(s.gen.prompt, 'old');
|
|
assert.equal(s.gen.steps, 8);
|
|
assert.equal(s.gen.aspect, '16:9');
|
|
assert.equal(patchWantsGenerate({ generate: true }), true);
|
|
assert.equal(patchWantsGenerate({ actions: ['generate'] }), true);
|
|
});
|
|
|
|
it('legacy flat params upgrade to session shape', () => {
|
|
const s = sessionFromLegacyParams({
|
|
prompt: 'fox',
|
|
steps: 28,
|
|
loras: [{ name: 'a', weight: 0.8 }],
|
|
genResults: [{ id: 'var1', src: '/View/x.png' }],
|
|
persona: 'leonid',
|
|
});
|
|
assert.equal(s.gen.prompt, 'fox');
|
|
assert.equal(s.gen.steps, 28);
|
|
assert.equal(s.board.genResults.length, 1);
|
|
const blob = toPersistParams(s);
|
|
assert.ok(blob.gen);
|
|
assert.ok(blob.board);
|
|
});
|
|
|
|
it('resolveTurnIntent vetoes generate', () => {
|
|
const intent = resolveTurnIntent(
|
|
{ generate: true, prompt: 'x' },
|
|
'не генерируй',
|
|
{ vetoFn: (t) => /не\s+генерир/i.test(t) },
|
|
);
|
|
assert.equal(intent.generate, false);
|
|
assert.equal(intent.vetoed, true);
|
|
});
|
|
|
|
it('mergeExactParamsForGenerate fills turbo profile when LLM omits steps/cfg', () => {
|
|
const exact = {
|
|
generation: { profile: 'turbo', steps: 8, cfg: 1, sigma_shift: 1.15 },
|
|
profiles: {
|
|
turbo: { steps: 8, cfg: 1, sigma_shift: 1.15 },
|
|
raw: { steps: 28, cfg: 4.5, sigma_shift: 1.15 },
|
|
},
|
|
};
|
|
const { patch, clearSessionKeys, profile } = mergeExactParamsForGenerate(
|
|
{ prompt: 'a fox', generate: true },
|
|
{
|
|
exact,
|
|
profiles: exact.profiles,
|
|
profileName: 'turbo',
|
|
sessionExact: { steps: 20, cfg: 7 },
|
|
userParamIntent: false,
|
|
},
|
|
);
|
|
assert.equal(profile, 'turbo');
|
|
assert.equal(patch.steps, 8);
|
|
assert.equal(patch.cfg, 1);
|
|
assert.equal(patch.sigma_shift, 1.15);
|
|
assert.deepEqual(clearSessionKeys.sort(), ['cfg', 'steps']);
|
|
});
|
|
|
|
it('mergeExactParamsForGenerate keeps user-intent sessionExact and explicit patch', () => {
|
|
const exact = {
|
|
generation: { steps: 8, cfg: 1 },
|
|
profiles: { raw: { steps: 28, cfg: 4.5, sigma_shift: 1.15 } },
|
|
};
|
|
const kept = mergeExactParamsForGenerate(
|
|
{ generate: true, actions: ['generate'] },
|
|
{
|
|
exact,
|
|
profiles: exact.profiles,
|
|
profileName: 'raw',
|
|
sessionExact: { steps: 20 },
|
|
userParamIntent: true,
|
|
},
|
|
);
|
|
assert.equal(kept.patch.steps, 20);
|
|
assert.equal(kept.patch.cfg, 4.5);
|
|
assert.deepEqual(kept.clearSessionKeys, []);
|
|
|
|
const explicit = mergeExactParamsForGenerate(
|
|
{ generate: true, steps: 12, cfg: 2 },
|
|
{ exact, profiles: exact.profiles, profileName: 'turbo', userParamIntent: true },
|
|
);
|
|
assert.equal(explicit.patch.steps, 12);
|
|
assert.equal(explicit.patch.cfg, 2);
|
|
|
|
const forced = mergeExactParamsForGenerate(
|
|
{ generate: true, steps: 20, cfg: 7 },
|
|
{
|
|
exact: { generation: { steps: 8, cfg: 1 }, profiles: { turbo: { steps: 8, cfg: 1, sigma_shift: 1.15 } } },
|
|
profiles: { turbo: { steps: 8, cfg: 1, sigma_shift: 1.15 } },
|
|
profileName: 'turbo',
|
|
userParamIntent: false,
|
|
},
|
|
);
|
|
assert.equal(forced.patch.steps, 8);
|
|
assert.equal(forced.patch.cfg, 1);
|
|
});
|
|
|
|
it('resolveExactProfileDefaults picks raw over generation defaults', () => {
|
|
const d = resolveExactProfileDefaults({
|
|
exact: { generation: { steps: 8, cfg: 1, sigma_shift: 1.15 } },
|
|
profiles: { raw: { steps: 28, cfg: 4.5 } },
|
|
profileName: 'raw',
|
|
});
|
|
assert.equal(d.steps, 28);
|
|
assert.equal(d.cfg, 4.5);
|
|
assert.equal(d.sigma_shift, 1.15);
|
|
});
|
|
});
|