172 lines
6.1 KiB
TypeScript
172 lines
6.1 KiB
TypeScript
/**
|
|
* restoreAgentSelection: classroom load must honor the user's explicit
|
|
* agent mode/selection (set in the AgentBar) when still valid for the loaded
|
|
* stage, and fall back to stage-derived defaults otherwise. Stage-derived
|
|
* defaults written by previous classroom loads are NOT user choices and must
|
|
* never carry across stages — otherwise visiting a preset classroom would
|
|
* permanently downgrade every auto classroom to preset agents.
|
|
*/
|
|
import { describe, it, expect } from 'vitest';
|
|
import {
|
|
restoreAgentSelection,
|
|
type AgentSelection,
|
|
} from '@/lib/orchestration/registry/agent-selection';
|
|
|
|
const PRESETS = new Set(['default-1', 'default-2', 'default-3', 'default-4']);
|
|
const isPresetAgent = (id: string) => PRESETS.has(id);
|
|
|
|
describe('restoreAgentSelection', () => {
|
|
it('keeps a user-set preset selection even when the stage has generated agents', () => {
|
|
const persisted: AgentSelection = {
|
|
mode: 'preset',
|
|
selectedAgentIds: ['default-2', 'default-3'],
|
|
};
|
|
expect(
|
|
restoreAgentSelection({
|
|
persisted,
|
|
persistedIsUserSet: true,
|
|
generatedAgentIds: ['gen-a', 'gen-b'],
|
|
isPresetAgent,
|
|
}),
|
|
).toEqual({ selection: persisted, isUserSet: true });
|
|
});
|
|
|
|
it("keeps a user-set auto selection that is a subset of this stage's generated agents", () => {
|
|
const persisted: AgentSelection = { mode: 'auto', selectedAgentIds: ['gen-b'] };
|
|
expect(
|
|
restoreAgentSelection({
|
|
persisted,
|
|
persistedIsUserSet: true,
|
|
generatedAgentIds: ['gen-a', 'gen-b'],
|
|
isPresetAgent,
|
|
}),
|
|
).toEqual({ selection: persisted, isUserSet: true });
|
|
});
|
|
|
|
it('ignores a stage-derived persisted selection and applies this stage defaults', () => {
|
|
// A previous classroom load wrote {preset, trio} as its fallback; that is
|
|
// not a user choice, so an auto stage must still get its generated agents.
|
|
expect(
|
|
restoreAgentSelection({
|
|
persisted: { mode: 'preset', selectedAgentIds: ['default-1', 'default-2', 'default-3'] },
|
|
persistedIsUserSet: false,
|
|
generatedAgentIds: ['gen-a', 'gen-b'],
|
|
isPresetAgent,
|
|
}),
|
|
).toEqual({
|
|
selection: { mode: 'auto', selectedAgentIds: ['gen-a', 'gen-b'] },
|
|
isUserSet: false,
|
|
});
|
|
});
|
|
|
|
it("resets a stale user-set auto selection (ids from another stage) to this stage's defaults", () => {
|
|
expect(
|
|
restoreAgentSelection({
|
|
persisted: { mode: 'auto', selectedAgentIds: ['other-stage-gen'] },
|
|
persistedIsUserSet: true,
|
|
generatedAgentIds: ['gen-a', 'gen-b'],
|
|
isPresetAgent,
|
|
}),
|
|
).toEqual({
|
|
selection: { mode: 'auto', selectedAgentIds: ['gen-a', 'gen-b'] },
|
|
isUserSet: false,
|
|
});
|
|
});
|
|
|
|
it('falls back to auto defaults when a user-set preset selection contains unknown ids', () => {
|
|
expect(
|
|
restoreAgentSelection({
|
|
persisted: { mode: 'preset', selectedAgentIds: ['gen-stale', 'default-2'] },
|
|
persistedIsUserSet: true,
|
|
generatedAgentIds: ['gen-a'],
|
|
isPresetAgent,
|
|
}),
|
|
).toEqual({ selection: { mode: 'auto', selectedAgentIds: ['gen-a'] }, isUserSet: false });
|
|
});
|
|
|
|
it('falls back to stage preset agents when nothing is generated and nothing was user-set', () => {
|
|
expect(
|
|
restoreAgentSelection({
|
|
persisted: { mode: 'auto', selectedAgentIds: ['other-stage-gen'] },
|
|
persistedIsUserSet: false,
|
|
generatedAgentIds: [],
|
|
stageAgentIds: ['default-4', 'gen-stale'],
|
|
isPresetAgent,
|
|
}),
|
|
).toEqual({
|
|
selection: { mode: 'preset', selectedAgentIds: ['default-4'] },
|
|
isUserSet: false,
|
|
});
|
|
});
|
|
|
|
it('falls back to the default preset trio when nothing else is valid', () => {
|
|
expect(
|
|
restoreAgentSelection({
|
|
persisted: { mode: 'preset', selectedAgentIds: [] },
|
|
persistedIsUserSet: true,
|
|
generatedAgentIds: [],
|
|
isPresetAgent,
|
|
}),
|
|
).toEqual({
|
|
selection: { mode: 'preset', selectedAgentIds: ['default-1', 'default-2', 'default-3'] },
|
|
isUserSet: false,
|
|
});
|
|
});
|
|
|
|
it('round-trips A(auto) → B(preset) → A without degrading A to preset agents', () => {
|
|
// Simulates sequential classroom loads with no user interaction: each
|
|
// load persists its result and feeds it into the next load.
|
|
const loadA = () => ({ generatedAgentIds: ['gen-a1', 'gen-a2'], stageAgentIds: undefined });
|
|
const loadB = () => ({ generatedAgentIds: [], stageAgentIds: ['default-1', 'default-2'] });
|
|
|
|
let state = {
|
|
selection: { mode: 'auto', selectedAgentIds: [] } as AgentSelection,
|
|
isUserSet: false,
|
|
};
|
|
state = restoreAgentSelection({
|
|
persisted: state.selection,
|
|
persistedIsUserSet: state.isUserSet,
|
|
...loadA(),
|
|
isPresetAgent,
|
|
});
|
|
expect(state.selection).toEqual({ mode: 'auto', selectedAgentIds: ['gen-a1', 'gen-a2'] });
|
|
|
|
state = restoreAgentSelection({
|
|
persisted: state.selection,
|
|
persistedIsUserSet: state.isUserSet,
|
|
...loadB(),
|
|
isPresetAgent,
|
|
});
|
|
expect(state.selection).toEqual({
|
|
mode: 'preset',
|
|
selectedAgentIds: ['default-1', 'default-2'],
|
|
});
|
|
|
|
state = restoreAgentSelection({
|
|
persisted: state.selection,
|
|
persistedIsUserSet: state.isUserSet,
|
|
...loadA(),
|
|
isPresetAgent,
|
|
});
|
|
expect(state.selection).toEqual({ mode: 'auto', selectedAgentIds: ['gen-a1', 'gen-a2'] });
|
|
});
|
|
|
|
it('carries a user-set preset choice through the same A → B → A round-trip', () => {
|
|
const persisted: AgentSelection = { mode: 'preset', selectedAgentIds: ['default-2'] };
|
|
let state = { selection: persisted, isUserSet: true };
|
|
for (const stage of [
|
|
{ generatedAgentIds: ['gen-a1'], stageAgentIds: undefined },
|
|
{ generatedAgentIds: [], stageAgentIds: ['default-1'] },
|
|
{ generatedAgentIds: ['gen-a1'], stageAgentIds: undefined },
|
|
]) {
|
|
state = restoreAgentSelection({
|
|
persisted: state.selection,
|
|
persistedIsUserSet: state.isUserSet,
|
|
...stage,
|
|
isPresetAgent,
|
|
});
|
|
expect(state).toEqual({ selection: persisted, isUserSet: true });
|
|
}
|
|
});
|
|
});
|