fix(mods): respect environment directory for loading mods#3334
Open
KY64 wants to merge 2 commits into
Open
Conversation
This is to ensure consistency from installing, loading, listing mods to respect LETTA_MODS_DIR and LETTA_EXTENSIONS_DIR
carenthomas
reviewed
Jul 13, 2026
| const envDirs = getModsDirectoryFromEnv(env); | ||
| return { | ||
| globalModsDirectory: | ||
| envDirs.globalModsDirectory ?? getGlobalModsDirectory(homeDirectory), |
Collaborator
There was a problem hiding this comment.
This keeps an empty string from getModsDirectoryFromEnv because it uses ??. That regresses the existing env parsing where LETTA_MODS_DIR=/whitespace is treated as unset: runtime/list now resolve the global mods root to "" and stop loading the default mods dir. Can we normalize empty strings to undefined, or use the same || fallback here?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
LETTA_MODS_DIRandLETTA_EXTENSIONS_DIRenv vars were respected by install / update / remove commands (viaresolveDefaultGlobalModsDirectory()), but ignored by both the runtime mod engine and letta mods list. This meant:letta install npm:foo→ installed to the custom directory ✅letta mods list→ looked in ~/.letta/mods/ insteadSilent failure: the CLI appeared to work but the agent runtime never saw the mod.
Fixes #3333.
Root Cause
src/mods/mod-engine.tscalledgetGlobalModsDirectory()andgetLegacyGlobalExtensionsDirectory()which is resolved to the hardcoded defaults (~/.letta/mods/, ~/.letta/extensions/) evenwhen env vars were set.
src/cli/subcommands/mods.tshad the same pattern:listMods()calledgetGlobalModsDirectory()andgetLegacyGlobalExtensionsDirectory()directly, bypassing env var resolution entirely.Changes
src/mods/paths.ts
ResolvedGlobalModDirectoriesinterface andresolveGlobalModDirectories()function — resolves bothdirectories independently from env vars, falling back to the hardcoded defaults. Unlike
resolveDefaultGlobalModsDirectory(), this does NOT fall back from ~/.letta/mods/ to ~/.letta/extensions/ — theruntime treats them as separate sources.
src/mods/mod-engine.ts
resolveLocalModSources()now respect env vars for mods directory.getLegacyExtensionMigrationTarget()now resolves the migration target root from env vars instead of thehardcoded default, so the diagnostic message points to the correct custom directory.
src/cli/subcommands/mods.ts
listMods()now respect env vars for mods directory.