fix: reset-conversation clears per-channel conversations in v2 store (#320)
The reset-conversation CLI command was reading/writing the agent JSON file directly, missing the per-channel conversations map introduced with conversation routing. Now uses Store.clearConversation() which clears both the legacy conversationId and all per-channel conversation keys. Also adds multi-agent awareness: prompts which agent to reset when multiple agents are configured. Closes #316 Written by Cameron and Letta Code "Debugging is twice as hard as writing the code in the first place." -- Brian Kernighan
This commit is contained in:
74
src/cli.ts
74
src/cli.ts
@@ -419,31 +419,64 @@ async function main() {
|
||||
}
|
||||
|
||||
case 'reset-conversation': {
|
||||
const { existsSync, readFileSync, writeFileSync } = await import('node:fs');
|
||||
const { join } = await import('node:path');
|
||||
const p = await import('@clack/prompts');
|
||||
|
||||
const dataDir = getDataDir();
|
||||
const agentJsonPath = join(dataDir, 'lettabot-agent.json');
|
||||
|
||||
p.intro('Reset Conversation');
|
||||
|
||||
if (!existsSync(agentJsonPath)) {
|
||||
p.log.error('No agent store found. Run the server first to create an agent.');
|
||||
const configuredName =
|
||||
(config.agent?.name?.trim())
|
||||
|| (config.agents?.length && config.agents[0].name?.trim())
|
||||
|| 'LettaBot';
|
||||
|
||||
const configuredAgents = (config.agents?.length ? config.agents : [{ name: configuredName }])
|
||||
.map(agent => agent.name?.trim())
|
||||
.filter((name): name is string => !!name);
|
||||
|
||||
const uniqueAgents = Array.from(new Set(configuredAgents));
|
||||
|
||||
let targetAgents = uniqueAgents;
|
||||
if (uniqueAgents.length > 1) {
|
||||
const choice = await p.select({
|
||||
message: 'Which agent should be reset?',
|
||||
options: [
|
||||
{ value: '__all__', label: 'All configured agents' },
|
||||
...uniqueAgents.map(name => ({ value: name, label: name })),
|
||||
],
|
||||
});
|
||||
if (p.isCancel(choice)) {
|
||||
p.cancel('Cancelled');
|
||||
break;
|
||||
}
|
||||
targetAgents = choice === '__all__' ? uniqueAgents : [choice as string];
|
||||
}
|
||||
|
||||
const entries = targetAgents.map((name) => {
|
||||
const store = new Store('lettabot-agent.json', name);
|
||||
const info = store.getInfo();
|
||||
const perChannelKeys = info.conversations ? Object.keys(info.conversations) : [];
|
||||
return {
|
||||
name,
|
||||
store,
|
||||
hasLegacy: !!info.conversationId,
|
||||
perChannelKeys,
|
||||
};
|
||||
});
|
||||
|
||||
const hasAny = entries.some(entry => entry.hasLegacy || entry.perChannelKeys.length > 0);
|
||||
if (!hasAny) {
|
||||
p.log.info('No conversation IDs stored. Nothing to reset.');
|
||||
break;
|
||||
}
|
||||
|
||||
const store = JSON.parse(readFileSync(agentJsonPath, 'utf-8'));
|
||||
const oldConversationId = store.conversationId;
|
||||
|
||||
if (!oldConversationId) {
|
||||
p.log.info('No conversation ID stored. Nothing to reset.');
|
||||
break;
|
||||
for (const entry of entries) {
|
||||
if (entry.hasLegacy) {
|
||||
p.log.warn(`Current conversation (${entry.name}): ${entry.store.conversationId}`);
|
||||
} else if (entry.perChannelKeys.length > 0) {
|
||||
p.log.warn(`Current per-channel conversations (${entry.name}): ${entry.perChannelKeys.length}`);
|
||||
}
|
||||
}
|
||||
|
||||
p.log.warn(`Current conversation: ${oldConversationId}`);
|
||||
p.log.message('');
|
||||
p.log.message('This will clear the conversation ID, causing the bot to create');
|
||||
p.log.message('This will clear the conversation ID(s), causing the bot to create');
|
||||
p.log.message('a new conversation on the next message. Use this if you see:');
|
||||
p.log.message(' • "stop_reason: error" with empty responses');
|
||||
p.log.message(' • Messages not reaching the agent');
|
||||
@@ -452,7 +485,7 @@ async function main() {
|
||||
p.log.message('The agent and its memory will be preserved.');
|
||||
|
||||
const confirmed = await p.confirm({
|
||||
message: 'Reset conversation?',
|
||||
message: `Reset conversation${entries.length > 1 ? 's' : ''}?`,
|
||||
initialValue: true,
|
||||
});
|
||||
|
||||
@@ -461,10 +494,11 @@ async function main() {
|
||||
break;
|
||||
}
|
||||
|
||||
store.conversationId = null;
|
||||
writeFileSync(agentJsonPath, JSON.stringify(store, null, 2));
|
||||
for (const entry of entries) {
|
||||
entry.store.clearConversation();
|
||||
}
|
||||
|
||||
p.log.success('Conversation ID cleared');
|
||||
p.log.success(`Conversation ID${entries.length > 1 ? 's' : ''} cleared`);
|
||||
p.outro('Restart the server - a new conversation will be created on the next message.');
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user