feat(new): accept optional conversation name argument and polish /resume results (#1451)

This commit is contained in:
Kian Jones
2026-03-19 16:31:59 -07:00
committed by GitHub
parent 4409d7224b
commit 4f1db10704
4 changed files with 29 additions and 21 deletions

View File

@@ -8130,10 +8130,14 @@ export default function App({
}
// Special handling for /new command - start new conversation
if (msg.trim() === "/new") {
const newMatch = msg.trim().match(/^\/new(?:\s+(.+))?$/);
if (newMatch) {
const conversationName = newMatch[1]?.trim();
const cmd = commandRunner.start(
msg.trim(),
"Starting new conversation...",
conversationName
? `Starting new conversation: ${conversationName}...`
: "Starting new conversation...",
);
// New conversations should not inherit pending reasoning-tier debounce.
@@ -8150,8 +8154,14 @@ export default function App({
const conversation = await client.conversations.create({
agent_id: agentId,
isolated_block_labels: [...ISOLATED_BLOCK_LABELS],
...(conversationName && { summary: conversationName }),
});
// If we created the conversation with an explicit summary, mark it as set
// to prevent auto-summary from first user message overwriting it
if (conversationName) {
hasSetConversationSummaryRef.current = true;
}
await maybeCarryOverActiveConversationModel(conversation.id);
// Update conversationId state
@@ -13939,6 +13949,11 @@ If using apply_patch, use this exact relative patch path: ${applyPatchRelativePa
messageHistory: resumeData.messageHistory,
};
// If the conversation already has a summary, prevent auto-summary from overwriting it
if (selectorContext?.summary) {
hasSetConversationSummaryRef.current = true;
}
settingsManager.setLocalLastSession(
{ agentId, conversationId: convId },
process.cwd(),

View File

@@ -441,20 +441,6 @@ export function ConversationSelector({
const bracket = <Text dimColor>{"⎿ "}</Text>;
const indent = " "; // Same width as "⎿ " for alignment
// Priority 1: Summary
if (conv.summary) {
return (
<Box flexDirection="row" marginLeft={2}>
{bracket}
<Text dimColor italic>
{conv.summary.length > 57
? `${conv.summary.slice(0, 54)}...`
: conv.summary}
</Text>
</Box>
);
}
// Priority 2: Preview lines with emoji prefixes
if (previewLines.length > 0) {
return (
@@ -516,9 +502,15 @@ export function ConversationSelector({
bold={isSelected}
color={isSelected ? colors.selector.itemHighlighted : undefined}
>
{isDefault ? "default" : conv.id}
{conv.summary
? `${conv.summary.length > 40 ? `${conv.summary.slice(0, 37)}...` : conv.summary} (${conv.id})`
: isDefault
? "default"
: conv.id}
</Text>
{isDefault && <Text dimColor> (agent's default conversation)</Text>}
{!conv.summary && isDefault && (
<Text dimColor> (agent's default conversation)</Text>
)}
{isCurrent && (
<Text color={colors.selector.itemCurrent}> (current)</Text>
)}

View File

@@ -153,8 +153,9 @@ describe("model preset refresh wiring", () => {
) ?? [];
expect(carryOverCalls.length).toBeGreaterThanOrEqual(3);
const newCmdAnchor = source.indexOf('if (msg.trim() === "/new")');
expect(newCmdAnchor).toBeGreaterThanOrEqual(0);
const newCmdAnchor = source.indexOf(
"const newMatch = msg.trim().match(/^\\/new(?:\\s+(.+))?$/);",
);
const newCmdWindow = source.slice(newCmdAnchor, newCmdAnchor + 1800);
expect(newCmdWindow).toContain(
"await maybeCarryOverActiveConversationModel(conversation.id);",

View File

@@ -29,7 +29,7 @@ describe("bootstrap reminder reset wiring", () => {
const anchors = [
'origin: "agent-switch"',
'const inputCmd = "/new";', // new-agent creation flow
'if (msg.trim() === "/new")',
"const newMatch = msg.trim().match(/^\\/new(?:\\s+(.+))?$/);",
'if (msg.trim() === "/clear")',
'origin: "resume-direct"',
'if (action.type === "switch_conversation")', // queued conversation switch flow