Guide for adding new LLM models to Letta Code. Use when the user wants to add support for a new model, needs to know valid model handles, or wants to update model-specific compatibility behavior. Covers runtime catalog sources, CI test matrices, and handle validation.
66
79%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./.skills/adding-models/SKILL.mdThis skill guides you through adding a new LLM model to Letta Code.
Key files:
src/agent/remote-model-catalog.ts - Runtime catalog loading and projectionsrc/agent/model-catalog.ts - Model lookup and compatibility aliases.github/workflows/ci.yml - CI test matrix (optional)src/tools/manager.ts - Toolset detection logic (rarely needed)First identify the agent source. These inputs are deliberately different:
| Agent source | Rows shown | Labels, presets, and capabilities |
|---|---|---|
| Cloud hosted | GET /v1/models/catalog only | GET /v1/models/catalog |
| Cloud organization BYOK | BYOK rows from GET /v1/models | Match to catalog metadata using provider metadata and model name; retain the BYOK handle for selection |
| Local | pi-ai inventory | pi-ai metadata |
| Custom App Server | Server runtime inventory | Server runtime metadata |
In Cloud mode, never use base/hosted rows from GET /v1/models to filter,
supplement, delay, or provide a fallback for the hosted catalog. This once made
GPT-4o appear in a selector even though the Cloud catalog deliberately omitted
it. GET /v1/models remains necessary for organization-specific BYOK rows.
Query the Cloud hosted catalog to see hosted preset IDs, handles, and capabilities:
curl -s https://api.letta.com/v1/models/catalog | jq '.models[] | [.id, .handle]'To inspect organization BYOK rows from a Cloud backend, query its model
inventory and filter by provider_category:
curl -s https://api.letta.com/v1/models/ \
| jq '.[] | select(.provider_category == "byok") | [.handle, .provider_type]'Do not use this response as a second hosted catalog.
Common provider prefixes:
anthropic/ - Claude modelsopenai/ - GPT modelsgoogle_ai/ - Gemini modelsgoogle_vertex/ - Vertex AIopenrouter/ - Various providersLetta Code does not bundle a model catalog:
GET /v1/models/catalog response.GET /v1/models contributes only organization BYOK rows to selectors.Add the model at the source that owns it. A hosted preset belongs in the server catalog. A local provider model belongs in pi-ai or that provider's discovery runtime.
Only change this repository when the model needs Letta Code-specific compatibility behavior, such as preserving an established CLI alias or recognizing a new provider for toolset selection. Keep that logic narrow and derive the handle and metadata from the runtime catalog rather than copying model definitions here.
Test with headless mode:
bun run src/index.ts --new --model <model-id> -p "hi, what model are you?"Example:
bun run src/index.ts --new --model gemini-3-flash -p "hi, what model are you?"To include the model in automated testing, add it to .github/workflows/ci.yml:
# Find the headless job matrix around line 122
model: [gpt-5-minimal, gpt-4.1, sonnet-4.5, gemini-pro, your-new-model, glm-4.6, haiku]Models are automatically assigned toolsets based on provider:
openai/* → codex toolsetgoogle_ai/* or google_vertex/* → gemini toolsetdefault toolsetThis is handled by isGeminiModel() and isOpenAIModel() in src/tools/manager.ts. You typically don't need to modify this unless adding a new provider.
"Handle not found" error: The model handle is incorrect. Run the validation script to see valid handles.
Model works but wrong toolset: Check src/tools/manager.ts to ensure the provider prefix is recognized.
7a4337e
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.