-
Notifications
You must be signed in to change notification settings - Fork 2.4k
fix: generatedAgentConfigs unconditionally set — default agents polluted as "generated" #353
Description
Problem
In lib/server/classroom-generation.ts, generatedAgentConfigs is set on the Stage object unconditionally — regardless of whether agentMode is 'default' or 'generate':
// L216-227: agents resolved based on agentMode
if (agentMode === 'generate') {
agents = await generateAgentProfiles(requirement, lang, aiCall);
} else {
agents = getDefaultAgents(); // returns default-1 ~ default-6
}
// L306: unconditional — always set, even for default agents
generatedAgentConfigs: agents.map((a, i) => ({ ... }))When agentMode === 'default', generatedAgentConfigs contains the 6 default agents (default-1 ~ default-6).
On the client side, saveGeneratedAgents() saves them to IndexedDB with isGenerated: true, overwriting the original isDefault: true entries in the Agent Registry.
Consequence
If a user navigates from a server-generated (default-mode) classroom to another classroom in the same SPA session:
loadGeneratedAgentsForStage(newClassroomId)clears allisGeneratedagents from the Registry- The default agents (
default-1~default-6) were overwritten asisGeneratedin step 1 of the previous load — so they get deleted - The original
isDefaultentries are gone (only restored on full page refresh via zustand persist merge)
Practical impact is low (page refresh fixes it), but it's a latent correctness issue.
Related: Stage missing agentIds for default mode
When using default agents, the Stage object also doesn't set the agentIds field. The client-side fallback in page.tsx (L96) defaults to ['default-1', 'default-2', 'default-3'] — only 3 of the 6 defaults. This is currently masked by the unconditional generatedAgentConfigs, but would become visible if the above is fixed.
Suggested Fix
const stage: Stage = {
// ...
// Only embed agent configs for LLM-generated agents
...(agentMode === 'generate' ? {
generatedAgentConfigs: agents.map((a, i) => ({
id: a.id, name: a.name, role: a.role,
persona: a.persona || '',
avatar: AGENT_DEFAULT_AVATARS[i % AGENT_DEFAULT_AVATARS.length],
color: AGENT_COLOR_PALETTE[i % AGENT_COLOR_PALETTE.length],
priority: a.role === 'teacher' ? 10 : a.role === 'assistant' ? 7 : 5,
}))
} : {
agentIds: agents.map(a => a.id) // default mode: just record IDs
}),
};Context
Discovered during review of #336. The unconditional setting was introduced in that PR.