this repo has no description
1#!/usr/bin/env bun
2/**
3 * Verification script to check Letta + LiteLLM + anthropic-proxy setup
4 *
5 * This verifies that:
6 * 1. Letta is running and healthy
7 * 2. Claude models are available via LiteLLM (configured via OPENAI_API_BASE)
8 * 3. The proxy chain is working
9 *
10 * Run: bun scripts/setup-letta-provider.ts
11 */
12
13const LETTA_BASE_URL = process.env['LETTA_BASE_URL'] ?? 'http://localhost:8283';
14
15interface Model {
16 handle: string;
17 provider_name: string;
18 model_endpoint?: string;
19}
20
21async function listModels(): Promise<Model[]> {
22 const response = await fetch(`${LETTA_BASE_URL}/v1/models/`);
23 if (!response.ok) {
24 throw new Error(`Failed to fetch models: ${response.status}`);
25 }
26 return (await response.json()) as Model[];
27}
28
29async function testAgentCreation(): Promise<boolean> {
30 // Create a test agent with letta-free, then update to Claude
31 console.log('Testing agent creation workflow...');
32
33 // Step 1: Create agent with letta-free
34 const createResponse = await fetch(`${LETTA_BASE_URL}/v1/agents/`, {
35 method: 'POST',
36 headers: { 'Content-Type': 'application/json' },
37 body: JSON.stringify({
38 name: `test-setup-${Date.now().toString()}`,
39 model: 'letta/letta-free',
40 embedding: 'letta/letta-free',
41 memory_blocks: [{ label: 'persona', value: 'Test agent' }],
42 }),
43 });
44
45 if (!createResponse.ok) {
46 console.error(' Failed to create test agent:', await createResponse.text());
47 return false;
48 }
49
50 const agent = (await createResponse.json()) as { id: string };
51 console.log(` Created test agent: ${agent.id}`);
52
53 // Step 2: Update to Claude
54 const updateResponse = await fetch(`${LETTA_BASE_URL}/v1/agents/${agent.id}`, {
55 method: 'PATCH',
56 headers: { 'Content-Type': 'application/json' },
57 body: JSON.stringify({
58 llm_config: {
59 handle: 'openai/claude-opus-4-5-20251101',
60 model: 'claude-opus-4-5-20251101',
61 model_endpoint_type: 'openai',
62 model_endpoint: 'http://litellm:4000',
63 context_window: 200000,
64 temperature: 0.7,
65 },
66 }),
67 });
68
69 if (!updateResponse.ok) {
70 console.error(' Failed to update agent to Claude:', await updateResponse.text());
71 // Clean up
72 await fetch(`${LETTA_BASE_URL}/v1/agents/${agent.id}`, { method: 'DELETE' });
73 return false;
74 }
75
76 console.log(' Updated agent to use Claude Opus 4.5');
77
78 // Step 3: Send test message
79 const messageResponse = await fetch(`${LETTA_BASE_URL}/v1/agents/${agent.id}/messages`, {
80 method: 'POST',
81 headers: { 'Content-Type': 'application/json' },
82 body: JSON.stringify({
83 messages: [{ role: 'user', content: 'Say "Hello from Claude!" and nothing else.' }],
84 }),
85 });
86
87 if (!messageResponse.ok) {
88 console.error(' Failed to send test message:', await messageResponse.text());
89 // Clean up
90 await fetch(`${LETTA_BASE_URL}/v1/agents/${agent.id}`, { method: 'DELETE' });
91 return false;
92 }
93
94 console.log(' Test message sent successfully');
95
96 // Clean up
97 await fetch(`${LETTA_BASE_URL}/v1/agents/${agent.id}`, { method: 'DELETE' });
98 console.log(' Test agent cleaned up');
99
100 return true;
101}
102
103async function main(): Promise<void> {
104 console.log('=== Letta Setup Verification ===\n');
105
106 // Check if Letta is running
107 try {
108 const health = await fetch(`${LETTA_BASE_URL}/v1/health/`);
109 if (!health.ok) {
110 throw new Error('Letta health check failed');
111 }
112 console.log('Letta is running.\n');
113 } catch {
114 console.error('Error: Letta is not accessible at', LETTA_BASE_URL);
115 console.error('Make sure to run: docker compose up -d');
116 process.exit(1);
117 }
118
119 // List available models
120 console.log('Available models:');
121 const models = await listModels();
122 const claudeModels = models.filter((m) => m.handle.includes('claude'));
123
124 for (const model of models) {
125 const marker = model.handle.includes('claude') ? ' <-- Claude via LiteLLM' : '';
126 console.log(` - ${model.handle} (${model.provider_name})${marker}`);
127 }
128
129 if (claudeModels.length === 0) {
130 console.error('\nNo Claude models found. Check OPENAI_API_BASE and LiteLLM configuration.');
131 process.exit(1);
132 }
133
134 console.log(`\nFound ${claudeModels.length.toString()} Claude model(s) via LiteLLM.\n`);
135
136 // Test agent creation workflow
137 const success = await testAgentCreation();
138
139 if (success) {
140 console.log('\nSetup verified! You can now run: bun run dev');
141 } else {
142 console.error('\nSetup verification failed. Check the logs above.');
143 process.exit(1);
144 }
145}
146
147main().catch((error: unknown) => {
148 console.error('Verification failed:', error);
149 process.exit(1);
150});