fix: pin existing default agents and rename --new to --new-agent (#556)
Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
@@ -105,6 +105,8 @@ export async function ensureDefaultAgents(
|
||||
const existingMemo = await findDefaultAgent(client, MEMO_TAG);
|
||||
if (existingMemo) {
|
||||
memoAgent = existingMemo;
|
||||
// Ensure it's pinned (might not be if settings were cleared or new machine)
|
||||
settingsManager.pinGlobal(existingMemo.id);
|
||||
} else {
|
||||
const { agent } = await createAgent(DEFAULT_AGENT_CONFIGS.memo);
|
||||
await addTagToAgent(client, agent.id, MEMO_TAG);
|
||||
@@ -114,7 +116,10 @@ export async function ensureDefaultAgents(
|
||||
|
||||
// Check/create Incognito
|
||||
const existingIncognito = await findDefaultAgent(client, INCOGNITO_TAG);
|
||||
if (!existingIncognito) {
|
||||
if (existingIncognito) {
|
||||
// Ensure it's pinned (might not be if settings were cleared or new machine)
|
||||
settingsManager.pinGlobal(existingIncognito.id);
|
||||
} else {
|
||||
const { agent } = await createAgent(DEFAULT_AGENT_CONFIGS.incognito);
|
||||
await addTagToAgent(client, agent.id, INCOGNITO_TAG);
|
||||
settingsManager.pinGlobal(agent.id);
|
||||
|
||||
@@ -7414,6 +7414,7 @@ Plan file path: ${planFilePath}`;
|
||||
{activeOverlay === "conversations" && (
|
||||
<ConversationSelector
|
||||
agentId={agentId}
|
||||
agentName={agentName ?? undefined}
|
||||
currentConversationId={conversationId}
|
||||
onSelect={async (convId) => {
|
||||
closeOverlay();
|
||||
|
||||
@@ -13,6 +13,7 @@ const SOLID_LINE = "─";
|
||||
|
||||
interface ConversationSelectorProps {
|
||||
agentId: string;
|
||||
agentName?: string;
|
||||
currentConversationId: string;
|
||||
onSelect: (conversationId: string) => void;
|
||||
onNewConversation: () => void;
|
||||
@@ -186,6 +187,7 @@ function getMessageStats(messages: Message[]): {
|
||||
|
||||
export function ConversationSelector({
|
||||
agentId,
|
||||
agentName,
|
||||
currentConversationId,
|
||||
onSelect,
|
||||
onNewConversation,
|
||||
@@ -511,7 +513,9 @@ export function ConversationSelector({
|
||||
{/* Empty state */}
|
||||
{!loading && !error && conversations.length === 0 && (
|
||||
<Box flexDirection="column">
|
||||
<Text dimColor>No conversations found</Text>
|
||||
<Text dimColor>
|
||||
No conversations for {agentName || agentId.slice(0, 12)}
|
||||
</Text>
|
||||
<Text dimColor>Press N to start a new conversation</Text>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
@@ -68,7 +68,8 @@ export async function handleHeadlessCommand(
|
||||
continue: { type: "boolean", short: "c" },
|
||||
resume: { type: "boolean", short: "r" },
|
||||
conversation: { type: "string" },
|
||||
new: { type: "boolean" },
|
||||
"new-agent": { type: "boolean" },
|
||||
new: { type: "boolean" }, // Deprecated - kept for helpful error message
|
||||
agent: { type: "string", short: "a" },
|
||||
model: { type: "string", short: "m" },
|
||||
system: { type: "string", short: "s" },
|
||||
@@ -180,12 +181,21 @@ export async function handleHeadlessCommand(
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Check for deprecated --new flag
|
||||
if (values.new) {
|
||||
console.error(
|
||||
"Error: --new has been renamed to --new-agent\n" +
|
||||
'Usage: letta -p "..." --new-agent',
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Resolve agent (same logic as interactive mode)
|
||||
let agent: AgentState | null = null;
|
||||
const specifiedAgentId = values.agent as string | undefined;
|
||||
const specifiedConversationId = values.conversation as string | undefined;
|
||||
const shouldContinue = values.continue as boolean | undefined;
|
||||
const forceNew = values.new as boolean | undefined;
|
||||
const forceNew = values["new-agent"] as boolean | undefined;
|
||||
const systemPromptPreset = values.system as string | undefined;
|
||||
const systemCustom = values["system-custom"] as string | undefined;
|
||||
const systemAppend = values["system-append"] as string | undefined;
|
||||
|
||||
20
src/index.ts
20
src/index.ts
@@ -344,7 +344,8 @@ async function main(): Promise<void> {
|
||||
continue: { type: "boolean" }, // Deprecated - kept for error message
|
||||
resume: { type: "boolean", short: "r" }, // Resume last session (or specific conversation with --conversation)
|
||||
conversation: { type: "string", short: "C" }, // Specific conversation ID to resume (--conv alias supported)
|
||||
new: { type: "boolean" },
|
||||
"new-agent": { type: "boolean" }, // Force create a new agent
|
||||
new: { type: "boolean" }, // Deprecated - kept for helpful error message
|
||||
"init-blocks": { type: "string" },
|
||||
"base-tools": { type: "string" },
|
||||
agent: { type: "string", short: "a" },
|
||||
@@ -426,7 +427,17 @@ async function main(): Promise<void> {
|
||||
const shouldResume = (values.resume as boolean | undefined) ?? false;
|
||||
const specifiedConversationId =
|
||||
(values.conversation as string | undefined) ?? null; // Specific conversation to resume
|
||||
const forceNew = (values.new as boolean | undefined) ?? false;
|
||||
const forceNew = (values["new-agent"] as boolean | undefined) ?? false;
|
||||
|
||||
// Check for deprecated --new flag
|
||||
if (values.new) {
|
||||
console.error(
|
||||
"Error: --new has been renamed to --new-agent\n" +
|
||||
"Usage: letta --new-agent",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const initBlocksRaw = values["init-blocks"] as string | undefined;
|
||||
const baseToolsRaw = values["base-tools"] as string | undefined;
|
||||
let specifiedAgentId = (values.agent as string | undefined) ?? null;
|
||||
@@ -838,6 +849,7 @@ async function main(): Promise<void> {
|
||||
>(null);
|
||||
// Track agent and conversation for conversation selector (--resume flag)
|
||||
const [resumeAgentId, setResumeAgentId] = useState<string | null>(null);
|
||||
const [resumeAgentName, setResumeAgentName] = useState<string | null>(null);
|
||||
const [selectedConversationId, setSelectedConversationId] = useState<
|
||||
string | null
|
||||
>(null);
|
||||
@@ -969,8 +981,9 @@ async function main(): Promise<void> {
|
||||
if (lastAgentId) {
|
||||
// Verify agent exists
|
||||
try {
|
||||
await client.agents.retrieve(lastAgentId);
|
||||
const agent = await client.agents.retrieve(lastAgentId);
|
||||
setResumeAgentId(lastAgentId);
|
||||
setResumeAgentName(agent.name ?? null);
|
||||
setLoadingState("selecting_conversation");
|
||||
return;
|
||||
} catch {
|
||||
@@ -1493,6 +1506,7 @@ async function main(): Promise<void> {
|
||||
if (loadingState === "selecting_conversation" && resumeAgentId) {
|
||||
return React.createElement(ConversationSelector, {
|
||||
agentId: resumeAgentId,
|
||||
agentName: resumeAgentName ?? undefined,
|
||||
currentConversationId: "", // No current conversation yet
|
||||
onSelect: (conversationId: string) => {
|
||||
setSelectedConversationId(conversationId);
|
||||
|
||||
@@ -38,7 +38,7 @@ async function runBidirectional(
|
||||
"stream-json",
|
||||
"--output-format",
|
||||
"stream-json",
|
||||
"--new",
|
||||
"--new-agent",
|
||||
"-m",
|
||||
"haiku",
|
||||
"--yolo",
|
||||
|
||||
@@ -70,7 +70,7 @@ async function runCLI(
|
||||
"-p",
|
||||
scenarioPrompt(),
|
||||
"--yolo",
|
||||
"--new",
|
||||
"--new-agent",
|
||||
"--output-format",
|
||||
output,
|
||||
"-m",
|
||||
|
||||
@@ -22,7 +22,7 @@ async function runHeadlessCommand(
|
||||
[
|
||||
"run",
|
||||
"dev",
|
||||
"--new",
|
||||
"--new-agent",
|
||||
"-p",
|
||||
prompt,
|
||||
"--output-format",
|
||||
|
||||
@@ -61,7 +61,7 @@ async function runCLI(
|
||||
"-p",
|
||||
windowsScenarioPrompt(),
|
||||
"--yolo",
|
||||
"--new",
|
||||
"--new-agent",
|
||||
"--output-format",
|
||||
"text",
|
||||
"-m",
|
||||
|
||||
Reference in New Issue
Block a user