feat: add API key caching via settings.json (#16)

Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
Charles Packer
2025-10-27 23:41:34 -07:00
committed by GitHub
parent fdfc94d9db
commit 50c249e36d
8 changed files with 46 additions and 13 deletions

View File

@@ -1,13 +1,41 @@
import { LettaClient } from "@letta-ai/letta-client";
import { loadSettings, updateSettings } from "../settings";
export function getClient() {
const token = process.env.LETTA_API_KEY;
export async function getClient() {
const settings = await loadSettings();
const token = process.env.LETTA_API_KEY || settings.env?.LETTA_API_KEY;
if (!token) {
console.error("Missing LETTA_API_KEY");
console.error(
"Set it via environment variable or add it to ~/.letta/settings.json:",
);
console.error(' { "env": { "LETTA_API_KEY": "sk-let-..." } }');
process.exit(1);
}
const baseUrl = process.env.LETTA_BASE_URL || "https://api.letta.com";
const baseUrl =
process.env.LETTA_BASE_URL ||
settings.env?.LETTA_BASE_URL ||
"https://api.letta.com";
// Auto-cache: if env vars are set but not in settings, write them to settings
let needsUpdate = false;
const updatedEnv = { ...settings.env };
if (process.env.LETTA_API_KEY && !settings.env?.LETTA_API_KEY) {
updatedEnv.LETTA_API_KEY = process.env.LETTA_API_KEY;
needsUpdate = true;
}
if (process.env.LETTA_BASE_URL && !settings.env?.LETTA_BASE_URL) {
updatedEnv.LETTA_BASE_URL = process.env.LETTA_BASE_URL;
needsUpdate = true;
}
if (needsUpdate) {
await updateSettings({ env: updatedEnv });
}
return new LettaClient({ token, baseUrl });
}

View File

@@ -17,7 +17,7 @@ export async function createAgent(
name = "letta-cli-agent",
model = "anthropic/claude-sonnet-4-5-20250929",
) {
const client = getClient();
const client = await getClient();
// Get loaded tool names (tools are already registered with Letta)
const toolNames = [

View File

@@ -14,7 +14,7 @@ export async function sendMessageStream(
// add more later: includePings, request timeouts, etc.
} = { streamTokens: true, background: true },
): Promise<AsyncIterable<Letta.LettaStreamingResponse>> {
const client = getClient();
const client = await getClient();
return client.agents.messages.createStream(agentId, {
messages: messages,
streamTokens: opts.streamTokens ?? true,

View File

@@ -20,7 +20,7 @@ export async function updateAgentLLMConfig(
modelHandle: string,
updateArgs?: Record<string, unknown>,
): Promise<Letta.LlmConfig> {
const client = getClient();
const client = await getClient();
// Step 1: Update model (top-level field)
await client.agents.modify(agentId, { model: modelHandle });