@letta-ai/letta-code 0.13.10 → 0.13.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/letta.js +183 -28
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,8 +15,10 @@ npm install -g @letta-ai/letta-code
|
|
|
15
15
|
```
|
|
16
16
|
Navigate to your project directory and run `letta` (see various command-line options [on the docs](https://docs.letta.com/letta-code/commands)).
|
|
17
17
|
|
|
18
|
+
Run `/connect` to configure your own LLM API keys (OpenAI, Anthropic, etc.), and use `/model` to swap models.
|
|
19
|
+
|
|
18
20
|
> [!NOTE]
|
|
19
|
-
> By default, Letta Code will to connect to the [Letta API](https://app.letta.com/). Use `/connect` to use your own LLM API keys and coding plans (Codex,
|
|
21
|
+
> By default, Letta Code will to connect to the [Letta API](https://app.letta.com/). Use `/connect` to use your own LLM API keys and coding plans (Codex, zAI, Minimax) for free. Set `LETTA_BASE_URL` to connect to an external [Docker server](https://docs.letta.com/letta-code/docker).
|
|
20
22
|
|
|
21
23
|
## Philosophy
|
|
22
24
|
Letta Code is built around long-lived agents that persist across sessions and improve with use. Rather than working in independent sessions, each session is tied to a persisted agent that learns.
|
package/letta.js
CHANGED
|
@@ -3108,7 +3108,7 @@ var package_default;
|
|
|
3108
3108
|
var init_package = __esm(() => {
|
|
3109
3109
|
package_default = {
|
|
3110
3110
|
name: "@letta-ai/letta-code",
|
|
3111
|
-
version: "0.13.
|
|
3111
|
+
version: "0.13.11",
|
|
3112
3112
|
description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
|
|
3113
3113
|
type: "module",
|
|
3114
3114
|
bin: {
|
|
@@ -61185,6 +61185,19 @@ function getResourceLimitMessage(e) {
|
|
|
61185
61185
|
}
|
|
61186
61186
|
return;
|
|
61187
61187
|
}
|
|
61188
|
+
function isAgentLimitError(e) {
|
|
61189
|
+
if (e.status !== 429)
|
|
61190
|
+
return false;
|
|
61191
|
+
const errorBody = e.error;
|
|
61192
|
+
if (errorBody && typeof errorBody === "object") {
|
|
61193
|
+
if ("reasons" in errorBody && Array.isArray(errorBody.reasons)) {
|
|
61194
|
+
if (errorBody.reasons.includes("agents-limit-exceeded")) {
|
|
61195
|
+
return true;
|
|
61196
|
+
}
|
|
61197
|
+
}
|
|
61198
|
+
}
|
|
61199
|
+
return false;
|
|
61200
|
+
}
|
|
61188
61201
|
function isCreditExhaustedError(e) {
|
|
61189
61202
|
if (e.status !== 402)
|
|
61190
61203
|
return false;
|
|
@@ -61217,6 +61230,15 @@ function formatErrorDetails(e, agentId, conversationId) {
|
|
|
61217
61230
|
const resetInfo = rateLimitResetMs > 0 ? formatResetTime(rateLimitResetMs) : "Try again later";
|
|
61218
61231
|
return `You've hit your usage limit. ${resetInfo}. View usage: ${LETTA_USAGE_URL}`;
|
|
61219
61232
|
}
|
|
61233
|
+
if (isAgentLimitError(e)) {
|
|
61234
|
+
const { billingTier } = getErrorContext();
|
|
61235
|
+
if (billingTier?.toLowerCase() === "free") {
|
|
61236
|
+
return `You've reached the agent limit (3) for the Free Plan. Delete agents at: ${LETTA_AGENTS_URL}
|
|
61237
|
+
Or upgrade to Pro for unlimited agents at: ${LETTA_USAGE_URL}`;
|
|
61238
|
+
}
|
|
61239
|
+
return `You've reached your agent limit. Delete agents at: ${LETTA_AGENTS_URL}
|
|
61240
|
+
Or check your plan at: ${LETTA_USAGE_URL}`;
|
|
61241
|
+
}
|
|
61220
61242
|
const resourceLimitMsg = getResourceLimitMessage(e);
|
|
61221
61243
|
if (resourceLimitMsg) {
|
|
61222
61244
|
const match3 = resourceLimitMsg.match(/limit for (\w+)/);
|
|
@@ -62285,15 +62307,10 @@ In headless mode, use:
|
|
|
62285
62307
|
console.error(`Error: Invalid model "${model}"`);
|
|
62286
62308
|
process.exit(1);
|
|
62287
62309
|
}
|
|
62288
|
-
const
|
|
62289
|
-
const
|
|
62290
|
-
|
|
62291
|
-
|
|
62292
|
-
const { updateAgentLLMConfig: updateAgentLLMConfig2 } = await init_modify().then(() => exports_modify);
|
|
62293
|
-
const updateArgs = getModelUpdateArgs(model);
|
|
62294
|
-
await updateAgentLLMConfig2(agent.id, modelHandle, updateArgs);
|
|
62295
|
-
agent = await client.agents.retrieve(agent.id);
|
|
62296
|
-
}
|
|
62310
|
+
const { updateAgentLLMConfig: updateAgentLLMConfig2 } = await init_modify().then(() => exports_modify);
|
|
62311
|
+
const updateArgs = getModelUpdateArgs(model);
|
|
62312
|
+
await updateAgentLLMConfig2(agent.id, modelHandle, updateArgs);
|
|
62313
|
+
agent = await client.agents.retrieve(agent.id);
|
|
62297
62314
|
}
|
|
62298
62315
|
if (systemPromptPreset) {
|
|
62299
62316
|
const { updateAgentSystemPrompt: updateAgentSystemPrompt2 } = await init_modify().then(() => exports_modify);
|
|
@@ -64296,6 +64313,9 @@ function AgentSelector({
|
|
|
64296
64313
|
const [allQuery, setAllQuery] = import_react29.useState("");
|
|
64297
64314
|
const [searchInput, setSearchInput] = import_react29.useState("");
|
|
64298
64315
|
const [activeQuery, setActiveQuery] = import_react29.useState("");
|
|
64316
|
+
const [viewState, setViewState] = import_react29.useState({ type: "list" });
|
|
64317
|
+
const [deleteConfirmInput, setDeleteConfirmInput] = import_react29.useState("");
|
|
64318
|
+
const [deleteLoading, setDeleteLoading] = import_react29.useState(false);
|
|
64299
64319
|
const loadPinnedAgents = import_react29.useCallback(async () => {
|
|
64300
64320
|
setPinnedLoading(true);
|
|
64301
64321
|
try {
|
|
@@ -64439,9 +64459,10 @@ function AgentSelector({
|
|
|
64439
64459
|
setAllLoadingMore(false);
|
|
64440
64460
|
}
|
|
64441
64461
|
}, [allLoadingMore, allHasMore, allCursor, fetchListAgents, activeQuery]);
|
|
64442
|
-
const
|
|
64462
|
+
const validPinnedAgents = pinnedAgents.filter((p) => p.agent !== null);
|
|
64463
|
+
const pinnedTotalPages = Math.ceil(validPinnedAgents.length / DISPLAY_PAGE_SIZE2);
|
|
64443
64464
|
const pinnedStartIndex = pinnedPage * DISPLAY_PAGE_SIZE2;
|
|
64444
|
-
const pinnedPageAgents =
|
|
64465
|
+
const pinnedPageAgents = validPinnedAgents.slice(pinnedStartIndex, pinnedStartIndex + DISPLAY_PAGE_SIZE2);
|
|
64445
64466
|
const lettaCodeTotalPages = Math.ceil(lettaCodeAgents.length / DISPLAY_PAGE_SIZE2);
|
|
64446
64467
|
const lettaCodeStartIndex = lettaCodePage * DISPLAY_PAGE_SIZE2;
|
|
64447
64468
|
const lettaCodePageAgents = lettaCodeAgents.slice(lettaCodeStartIndex, lettaCodeStartIndex + DISPLAY_PAGE_SIZE2);
|
|
@@ -64465,11 +64486,49 @@ function AgentSelector({
|
|
|
64465
64486
|
setActiveQuery("");
|
|
64466
64487
|
}
|
|
64467
64488
|
}, [activeQuery]);
|
|
64489
|
+
const handleDeleteAgent = import_react29.useCallback(async () => {
|
|
64490
|
+
if (viewState.type !== "deleteConfirm")
|
|
64491
|
+
return;
|
|
64492
|
+
const { agent, agentId } = viewState;
|
|
64493
|
+
const expectedName = agent.name || agentId.slice(0, 12);
|
|
64494
|
+
if (deleteConfirmInput !== expectedName)
|
|
64495
|
+
return;
|
|
64496
|
+
setDeleteLoading(true);
|
|
64497
|
+
try {
|
|
64498
|
+
const client = clientRef.current || await getClient2();
|
|
64499
|
+
clientRef.current = client;
|
|
64500
|
+
await client.agents.delete(agentId);
|
|
64501
|
+
setViewState({ type: "list" });
|
|
64502
|
+
setDeleteConfirmInput("");
|
|
64503
|
+
loadPinnedAgents();
|
|
64504
|
+
setLettaCodeLoaded(false);
|
|
64505
|
+
setAllLoaded(false);
|
|
64506
|
+
} catch {} finally {
|
|
64507
|
+
setDeleteLoading(false);
|
|
64508
|
+
}
|
|
64509
|
+
}, [viewState, deleteConfirmInput, loadPinnedAgents]);
|
|
64468
64510
|
use_input_default((input, key) => {
|
|
64469
64511
|
if (key.ctrl && input === "c") {
|
|
64470
64512
|
onCancel();
|
|
64471
64513
|
return;
|
|
64472
64514
|
}
|
|
64515
|
+
if (viewState.type === "deleteConfirm") {
|
|
64516
|
+
if (key.escape) {
|
|
64517
|
+
setViewState({ type: "list" });
|
|
64518
|
+
setDeleteConfirmInput("");
|
|
64519
|
+
return;
|
|
64520
|
+
}
|
|
64521
|
+
if (deleteLoading)
|
|
64522
|
+
return;
|
|
64523
|
+
if (key.return) {
|
|
64524
|
+
handleDeleteAgent();
|
|
64525
|
+
} else if (key.backspace || key.delete) {
|
|
64526
|
+
setDeleteConfirmInput((prev) => prev.slice(0, -1));
|
|
64527
|
+
} else if (input && !key.ctrl && !key.meta) {
|
|
64528
|
+
setDeleteConfirmInput((prev) => prev + input);
|
|
64529
|
+
}
|
|
64530
|
+
return;
|
|
64531
|
+
}
|
|
64473
64532
|
if (key.tab) {
|
|
64474
64533
|
const currentIndex = TABS.findIndex((t) => t.id === activeTab);
|
|
64475
64534
|
const nextIndex = (currentIndex + 1) % TABS.length;
|
|
@@ -64568,6 +64627,30 @@ function AgentSelector({
|
|
|
64568
64627
|
}
|
|
64569
64628
|
loadPinnedAgents();
|
|
64570
64629
|
}
|
|
64630
|
+
} else if (input === "d" || input === "D") {
|
|
64631
|
+
let selectedAgent = null;
|
|
64632
|
+
let selectedAgentId = null;
|
|
64633
|
+
if (activeTab === "pinned") {
|
|
64634
|
+
const selected = pinnedPageAgents[pinnedSelectedIndex];
|
|
64635
|
+
if (selected?.agent) {
|
|
64636
|
+
selectedAgent = selected.agent;
|
|
64637
|
+
selectedAgentId = selected.agentId;
|
|
64638
|
+
}
|
|
64639
|
+
} else if (activeTab === "letta-code") {
|
|
64640
|
+
selectedAgent = lettaCodePageAgents[lettaCodeSelectedIndex] ?? null;
|
|
64641
|
+
selectedAgentId = selectedAgent?.id ?? null;
|
|
64642
|
+
} else {
|
|
64643
|
+
selectedAgent = allPageAgents[allSelectedIndex] ?? null;
|
|
64644
|
+
selectedAgentId = selectedAgent?.id ?? null;
|
|
64645
|
+
}
|
|
64646
|
+
if (selectedAgent && selectedAgentId) {
|
|
64647
|
+
setViewState({
|
|
64648
|
+
type: "deleteConfirm",
|
|
64649
|
+
agent: selectedAgent,
|
|
64650
|
+
agentId: selectedAgentId
|
|
64651
|
+
});
|
|
64652
|
+
setDeleteConfirmInput("");
|
|
64653
|
+
}
|
|
64571
64654
|
} else if (input === "n" || input === "N") {
|
|
64572
64655
|
onCreateNewAgent?.();
|
|
64573
64656
|
} else if (activeTab !== "pinned" && input && !key.ctrl && !key.meta) {
|
|
@@ -64703,7 +64786,85 @@ function AgentSelector({
|
|
|
64703
64786
|
]
|
|
64704
64787
|
}, data.agentId, true, undefined, this);
|
|
64705
64788
|
};
|
|
64789
|
+
const renderDeleteConfirm = () => {
|
|
64790
|
+
if (viewState.type !== "deleteConfirm")
|
|
64791
|
+
return null;
|
|
64792
|
+
const { agent, agentId } = viewState;
|
|
64793
|
+
const displayName = agent.name || agentId.slice(0, 12);
|
|
64794
|
+
const inputMatches = deleteConfirmInput === displayName;
|
|
64795
|
+
return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(jsx_dev_runtime8.Fragment, {
|
|
64796
|
+
children: [
|
|
64797
|
+
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
|
|
64798
|
+
flexDirection: "column",
|
|
64799
|
+
marginBottom: 1,
|
|
64800
|
+
children: [
|
|
64801
|
+
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
|
|
64802
|
+
children: [
|
|
64803
|
+
" ",
|
|
64804
|
+
"Are you sure you want to delete",
|
|
64805
|
+
" ",
|
|
64806
|
+
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
|
|
64807
|
+
bold: true,
|
|
64808
|
+
children: displayName
|
|
64809
|
+
}, undefined, false, undefined, this),
|
|
64810
|
+
"?"
|
|
64811
|
+
]
|
|
64812
|
+
}, undefined, true, undefined, this),
|
|
64813
|
+
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
|
|
64814
|
+
color: "red",
|
|
64815
|
+
children: [
|
|
64816
|
+
" ",
|
|
64817
|
+
"This action can not be undone."
|
|
64818
|
+
]
|
|
64819
|
+
}, undefined, true, undefined, this)
|
|
64820
|
+
]
|
|
64821
|
+
}, undefined, true, undefined, this),
|
|
64822
|
+
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
|
|
64823
|
+
flexDirection: "row",
|
|
64824
|
+
children: [
|
|
64825
|
+
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
|
|
64826
|
+
color: colors.selector.itemHighlighted,
|
|
64827
|
+
children: "> "
|
|
64828
|
+
}, undefined, false, undefined, this),
|
|
64829
|
+
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
|
|
64830
|
+
dimColor: !deleteConfirmInput,
|
|
64831
|
+
children: deleteConfirmInput || "(type the agent's name)"
|
|
64832
|
+
}, undefined, false, undefined, this)
|
|
64833
|
+
]
|
|
64834
|
+
}, undefined, true, undefined, this),
|
|
64835
|
+
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
|
|
64836
|
+
marginTop: 1,
|
|
64837
|
+
children: /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
|
|
64838
|
+
dimColor: true,
|
|
64839
|
+
children: [
|
|
64840
|
+
" ",
|
|
64841
|
+
deleteLoading ? "Deleting... · Esc cancel" : inputMatches ? "Enter to delete · Esc cancel" : "Esc cancel"
|
|
64842
|
+
]
|
|
64843
|
+
}, undefined, true, undefined, this)
|
|
64844
|
+
}, undefined, false, undefined, this)
|
|
64845
|
+
]
|
|
64846
|
+
}, undefined, true, undefined, this);
|
|
64847
|
+
};
|
|
64706
64848
|
const solidLine = SOLID_LINE2.repeat(Math.max(terminalWidth, 10));
|
|
64849
|
+
if (viewState.type === "deleteConfirm") {
|
|
64850
|
+
return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
|
|
64851
|
+
flexDirection: "column",
|
|
64852
|
+
children: [
|
|
64853
|
+
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
|
|
64854
|
+
dimColor: true,
|
|
64855
|
+
children: `> ${command}`
|
|
64856
|
+
}, undefined, false, undefined, this),
|
|
64857
|
+
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
|
|
64858
|
+
dimColor: true,
|
|
64859
|
+
children: solidLine
|
|
64860
|
+
}, undefined, false, undefined, this),
|
|
64861
|
+
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
|
|
64862
|
+
height: 1
|
|
64863
|
+
}, undefined, false, undefined, this),
|
|
64864
|
+
renderDeleteConfirm()
|
|
64865
|
+
]
|
|
64866
|
+
}, undefined, true, undefined, this);
|
|
64867
|
+
}
|
|
64707
64868
|
return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
|
|
64708
64869
|
flexDirection: "column",
|
|
64709
64870
|
children: [
|
|
@@ -64789,7 +64950,7 @@ function AgentSelector({
|
|
|
64789
64950
|
]
|
|
64790
64951
|
}, undefined, true, undefined, this)
|
|
64791
64952
|
}, undefined, false, undefined, this),
|
|
64792
|
-
!currentLoading && (activeTab === "pinned" &&
|
|
64953
|
+
!currentLoading && (activeTab === "pinned" && validPinnedAgents.length === 0 || activeTab === "letta-code" && !lettaCodeError && lettaCodeAgents.length === 0 || activeTab === "all" && !allError && allAgents.length === 0) && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
|
|
64793
64954
|
flexDirection: "column",
|
|
64794
64955
|
children: [
|
|
64795
64956
|
/* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Text, {
|
|
@@ -64802,7 +64963,7 @@ function AgentSelector({
|
|
|
64802
64963
|
}, undefined, false, undefined, this)
|
|
64803
64964
|
]
|
|
64804
64965
|
}, undefined, true, undefined, this),
|
|
64805
|
-
activeTab === "pinned" && !pinnedLoading &&
|
|
64966
|
+
activeTab === "pinned" && !pinnedLoading && validPinnedAgents.length > 0 && /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
|
|
64806
64967
|
flexDirection: "column",
|
|
64807
64968
|
children: pinnedPageAgents.map((data, index) => renderPinnedItem(data, index, index === pinnedSelectedIndex))
|
|
64808
64969
|
}, undefined, false, undefined, this),
|
|
@@ -64814,10 +64975,10 @@ function AgentSelector({
|
|
|
64814
64975
|
flexDirection: "column",
|
|
64815
64976
|
children: allPageAgents.map((agent, index) => renderAgentItem(agent, index, index === allSelectedIndex))
|
|
64816
64977
|
}, undefined, false, undefined, this),
|
|
64817
|
-
!currentLoading && (activeTab === "pinned" &&
|
|
64978
|
+
!currentLoading && (activeTab === "pinned" && validPinnedAgents.length > 0 || activeTab === "letta-code" && !lettaCodeError && lettaCodeAgents.length > 0 || activeTab === "all" && !allError && allAgents.length > 0) && (() => {
|
|
64818
64979
|
const footerWidth = Math.max(0, terminalWidth - 2);
|
|
64819
64980
|
const pageText = activeTab === "pinned" ? `Page ${pinnedPage + 1}/${pinnedTotalPages || 1}` : activeTab === "letta-code" ? `Page ${lettaCodePage + 1}${lettaCodeHasMore ? "+" : `/${lettaCodeTotalPages || 1}`}${lettaCodeLoadingMore ? " (loading...)" : ""}` : `Page ${allPage + 1}${allHasMore ? "+" : `/${allTotalPages || 1}`}${allLoadingMore ? " (loading...)" : ""}`;
|
|
64820
|
-
const hintsText = `Enter select · ↑↓ navigate ·
|
|
64981
|
+
const hintsText = `Enter select · ↑↓ ←→ navigate · Tab switch · D delete${activeTab === "pinned" ? " · P unpin" : ""}${onCreateNewAgent ? " · N new" : ""} · Esc cancel`;
|
|
64821
64982
|
return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(Box_default, {
|
|
64822
64983
|
flexDirection: "column",
|
|
64823
64984
|
children: [
|
|
@@ -97015,22 +97176,16 @@ Error: ${message}`);
|
|
|
97015
97176
|
setIsResumingSession(resuming);
|
|
97016
97177
|
if (resuming && (model || systemPromptPreset2)) {
|
|
97017
97178
|
if (model) {
|
|
97018
|
-
const { resolveModel: resolveModel3 } = await Promise.resolve().then(() => (init_model2(), exports_model2));
|
|
97179
|
+
const { resolveModel: resolveModel3, getModelUpdateArgs: getModelUpdateArgs4 } = await Promise.resolve().then(() => (init_model2(), exports_model2));
|
|
97019
97180
|
const modelHandle = resolveModel3(model);
|
|
97020
97181
|
if (!modelHandle) {
|
|
97021
97182
|
console.error(`Error: Invalid model "${model}"`);
|
|
97022
97183
|
process.exit(1);
|
|
97023
97184
|
}
|
|
97024
|
-
const
|
|
97025
|
-
const
|
|
97026
|
-
|
|
97027
|
-
|
|
97028
|
-
const { updateAgentLLMConfig: updateAgentLLMConfig3 } = await init_modify2().then(() => exports_modify2);
|
|
97029
|
-
const { getModelUpdateArgs: getModelUpdateArgs4 } = await Promise.resolve().then(() => (init_model2(), exports_model2));
|
|
97030
|
-
const updateArgs = getModelUpdateArgs4(model);
|
|
97031
|
-
await updateAgentLLMConfig3(agent.id, modelHandle, updateArgs);
|
|
97032
|
-
agent = await client.agents.retrieve(agent.id);
|
|
97033
|
-
}
|
|
97185
|
+
const { updateAgentLLMConfig: updateAgentLLMConfig3 } = await init_modify2().then(() => exports_modify2);
|
|
97186
|
+
const updateArgs = getModelUpdateArgs4(model);
|
|
97187
|
+
await updateAgentLLMConfig3(agent.id, modelHandle, updateArgs);
|
|
97188
|
+
agent = await client.agents.retrieve(agent.id);
|
|
97034
97189
|
}
|
|
97035
97190
|
if (systemPromptPreset2) {
|
|
97036
97191
|
const { updateAgentSystemPrompt: updateAgentSystemPrompt3 } = await init_modify2().then(() => exports_modify2);
|
|
@@ -97264,4 +97419,4 @@ Error during initialization: ${message}`);
|
|
|
97264
97419
|
}
|
|
97265
97420
|
main();
|
|
97266
97421
|
|
|
97267
|
-
//# debugId=
|
|
97422
|
+
//# debugId=8E63B855C90D4DD564756E2164756E21
|