This commit is contained in:
christinatong01
2026-03-19 17:22:02 -07:00
8 changed files with 48 additions and 28 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "@letta-ai/letta-code",
"version": "0.19.4",
"version": "0.19.5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@letta-ai/letta-code",
"version": "0.19.4",
"version": "0.19.5",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "@letta-ai/letta-code",
"version": "0.19.4",
"version": "0.19.5",
"description": "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
"type": "module",
"bin": {
@@ -68,7 +68,7 @@
"fix": "bunx --bun @biomejs/biome@2.2.5 check --write src",
"typecheck": "tsc --noEmit",
"check": "bun run scripts/check.js",
"dev": "LETTA_DEBUG=1 bun --loader:.md=text --loader:.mdx=text --loader:.txt=text run src/index.ts",
"dev": "LETTA_DEBUG=${LETTA_DEBUG:-1} bun --loader:.md=text --loader:.mdx=text --loader:.txt=text run src/index.ts",
"build": "node scripts/postinstall-patches.js && bun run build.js",
"test:update-chain:manual": "bun run src/tests/update-chain-smoke.ts --mode manual",
"test:update-chain:startup": "bun run src/tests/update-chain-smoke.ts --mode startup",

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

@@ -116,7 +116,7 @@ export function MessageSearch({
const [searchInput, setSearchInput] = useState(initialQuery ?? "");
const [activeQuery, setActiveQuery] = useState(initialQuery ?? "");
const [searchMode, setSearchMode] = useState<SearchMode>("hybrid");
const [searchRange, setSearchRange] = useState<SearchRange>("all");
const [searchRange, setSearchRange] = useState<SearchRange>("agent");
const [results, setResults] = useState<MessageSearchResponse>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);

View File

@@ -1468,12 +1468,24 @@
"parallel_tool_calls": true
}
},
{
"id": "minimax-m2.7",
"handle": "minimax/MiniMax-M2.7",
"label": "MiniMax 2.7",
"description": "MiniMax's latest coding model",
"isFeatured": true,
"free": true,
"updateArgs": {
"context_window": 160000,
"max_output_tokens": 64000,
"parallel_tool_calls": true
}
},
{
"id": "minimax-m2.5",
"handle": "minimax/MiniMax-M2.5",
"label": "MiniMax 2.5",
"description": "MiniMax's latest coding model",
"isFeatured": true,
"description": "MiniMax's latest coding model (legacy)",
"free": true,
"updateArgs": {
"context_window": 160000,

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