fix: patch the auth flow for bad keys

This commit is contained in:
cpacker
2025-11-04 15:11:34 -08:00
parent dd3a87f66a
commit ceae108c1f
2 changed files with 29 additions and 7 deletions

View File

@@ -3,6 +3,8 @@
* Uses Device Code Flow for CLI authentication
*/
import Letta from "@letta-ai/letta-client";
export const OAUTH_CONFIG = {
clientId: "ci-let-724dea7e98f4af6f8f370f4b1466200c",
clientSecret: "", // Not needed for device code flow
@@ -152,20 +154,21 @@ export async function refreshAccessToken(
}
/**
* Validate credentials by checking health endpoint
* Validate credentials by checking an authenticated endpoint
* Uses SDK's agents.list() which requires valid authentication
*/
export async function validateCredentials(
baseUrl: string,
apiKey: string,
): Promise<boolean> {
try {
const response = await fetch(`${baseUrl}/v1/health`, {
headers: {
Authorization: `Bearer ${apiKey}`,
},
});
// Create a temporary client to test authentication
const client = new Letta({ apiKey, baseURL: baseUrl });
return response.ok;
// Try to list agents - this requires valid authentication
await client.agents.list({ limit: 1 });
return true;
} catch {
return false;
}

View File

@@ -1,4 +1,8 @@
import type Letta from "@letta-ai/letta-client";
import {
AuthenticationError,
PermissionDeniedError,
} from "@letta-ai/letta-client";
import { TOOL_DEFINITIONS, type ToolName } from "./toolDefinitions";
export const TOOL_NAMES = Object.keys(TOOL_DEFINITIONS) as ToolName[];
@@ -288,6 +292,18 @@ export async function upsertToolsToServer(client: Letta): Promise<void> {
const elapsed = Date.now() - attemptStartTime;
const totalElapsed = Date.now() - startTime;
// Check if this is an auth error - fail immediately without retrying
if (
error instanceof AuthenticationError ||
error instanceof PermissionDeniedError
) {
throw new Error(
`Authentication failed. Please check your LETTA_API_KEY.\n` +
`Run 'rm ~/.letta/settings.json' and restart to re-authenticate.\n` +
`Original error: ${error.message}`,
);
}
// If we still have time, retry with exponential backoff
if (totalElapsed < MAX_TOTAL_TIME) {
const backoffDelay = Math.min(1000 * 2 ** retryCount, 5000); // Max 5s backoff
@@ -296,6 +312,9 @@ export async function upsertToolsToServer(client: Letta): Promise<void> {
console.error(
`Tool upsert attempt ${retryCount + 1} failed after ${elapsed}ms. Retrying in ${backoffDelay}ms... (${Math.round(remainingTime / 1000)}s remaining)`,
);
console.error(
`Error: ${error instanceof Error ? error.message : String(error)}`,
);
await new Promise((resolve) => setTimeout(resolve, backoffDelay));
return attemptUpsert(retryCount + 1);