@letta-ai/letta-code 0.28.1 → 0.28.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/letta.js CHANGED
@@ -4815,7 +4815,7 @@ var package_default;
4815
4815
  var init_package = __esm(() => {
4816
4816
  package_default = {
4817
4817
  name: "@letta-ai/letta-code",
4818
- version: "0.28.1",
4818
+ version: "0.28.2",
4819
4819
  description: "Letta Code is a CLI tool for interacting with stateful Letta agents from the terminal.",
4820
4820
  type: "module",
4821
4821
  packageManager: "bun@1.3.0",
@@ -155344,6 +155344,9 @@ var init_byok_providers = __esm(() => {
155344
155344
  ];
155345
155345
  });
155346
155346
 
155347
+ // src/providers/openai-codex-constants.ts
155348
+ var OPENAI_CODEX_PROVIDER_NAME = "chatgpt-plus-pro";
155349
+
155347
155350
  // src/providers/openai-codex-provider.ts
155348
155351
  function normalizeChatGPTOAuthProviderName(providerName) {
155349
155352
  const normalized = (providerName ?? OPENAI_CODEX_PROVIDER_NAME).trim();
@@ -155384,7 +155387,7 @@ async function createOrUpdateOpenAICodexProvider(config3, options3 = {}, provide
155384
155387
  }
155385
155388
  return createOpenAICodexProvider(config3, options3, normalizedProviderName);
155386
155389
  }
155387
- var OPENAI_CODEX_PROVIDER_NAME = "chatgpt-plus-pro", CHATGPT_OAUTH_PROVIDER_NAME_PATTERN, CHATGPT_OAUTH_PROVIDER_TYPE = "chatgpt_oauth";
155390
+ var CHATGPT_OAUTH_PROVIDER_NAME_PATTERN, CHATGPT_OAUTH_PROVIDER_TYPE = "chatgpt_oauth";
155388
155391
  var init_openai_codex_provider = __esm(() => {
155389
155392
  init_metadata();
155390
155393
  init_byok_providers();
@@ -161540,14 +161543,187 @@ var init_model_catalog = __esm(() => {
161540
161543
  models2 = models_default.models;
161541
161544
  });
161542
161545
 
161546
+ // src/agent/model-handles.ts
161547
+ function normalizeModelHandleForRegistry(modelHandle) {
161548
+ if (!modelHandle)
161549
+ return null;
161550
+ const [provider, ...modelParts] = modelHandle.split("/");
161551
+ const model = modelParts.join("/");
161552
+ if (provider === CHATGPT_OAUTH_LLM_CONFIG_PROVIDER && model.length > 0) {
161553
+ return `${OPENAI_CODEX_PROVIDER_NAME}/${model}`;
161554
+ }
161555
+ if (provider === LOCAL_CHATGPT_OAUTH_HANDLE_PREFIX.slice(0, -1) && model.length > 0 && !model.endsWith("-fast")) {
161556
+ return `${OPENAI_CODEX_PROVIDER_NAME}/${model}`;
161557
+ }
161558
+ if (provider === "lc-anthropic" && model.length > 0) {
161559
+ return `anthropic/${model}`;
161560
+ }
161561
+ return modelHandle;
161562
+ }
161563
+ function modelPortionFromHandle(modelHandle) {
161564
+ const slashIndex = modelHandle.indexOf("/");
161565
+ if (slashIndex === -1)
161566
+ return null;
161567
+ return modelHandle.slice(slashIndex + 1);
161568
+ }
161569
+ function providerPrefix(modelHandle) {
161570
+ const slashIndex = modelHandle.indexOf("/");
161571
+ if (slashIndex <= 0)
161572
+ return null;
161573
+ return modelHandle.slice(0, slashIndex);
161574
+ }
161575
+ function isKnownModelProviderPrefix(provider) {
161576
+ return KNOWN_LLM_CONFIG_ENDPOINT_TYPES.has(provider) || MODEL_HANDLE_PROVIDER_PREFIXES.has(provider) || LOCAL_MODEL_PROVIDER_PREFIXES.has(provider);
161577
+ }
161578
+ function isKnownProviderPrefixedHandle(modelHandle) {
161579
+ const provider = providerPrefix(modelHandle);
161580
+ return provider !== null && isKnownModelProviderPrefix(provider);
161581
+ }
161582
+ function modelHandleProviderForEndpointType(endpointType) {
161583
+ return LLM_CONFIG_ENDPOINT_TYPE_MODEL_HANDLE_PROVIDERS.get(endpointType) ?? endpointType;
161584
+ }
161585
+ function endpointTypeMatchesModelProvider(endpointType, modelProvider) {
161586
+ return endpointType === modelProvider || modelHandleProviderForEndpointType(endpointType) === modelProvider || endpointType === CHATGPT_OAUTH_LLM_CONFIG_PROVIDER && modelProvider === "openai-codex" || endpointType === "openai";
161587
+ }
161588
+ function exactRegistryModelHandle(modelHandle) {
161589
+ const registryHandle = normalizeModelHandleForRegistry(modelHandle) ?? modelHandle;
161590
+ return models2.some((model) => model.handle === registryHandle) ? registryHandle : null;
161591
+ }
161592
+ function uniqueRegistryHandleForModelName(modelName) {
161593
+ const matches = new Set(models2.filter((model) => modelPortionFromHandle(model.handle) === modelName).map((model) => model.handle));
161594
+ return matches.size === 1 ? [...matches][0] ?? null : null;
161595
+ }
161596
+ function normalizeKnownModelHandle(modelHandle) {
161597
+ const registryHandle = normalizeModelHandleForRegistry(modelHandle) ?? modelHandle;
161598
+ const exact = exactRegistryModelHandle(registryHandle);
161599
+ if (exact)
161600
+ return exact;
161601
+ const model = modelPortionFromHandle(registryHandle);
161602
+ if (!model) {
161603
+ return uniqueRegistryHandleForModelName(registryHandle) ?? registryHandle;
161604
+ }
161605
+ const provider = providerPrefix(registryHandle);
161606
+ if (provider && !isKnownModelProviderPrefix(provider)) {
161607
+ return registryHandle;
161608
+ }
161609
+ return uniqueRegistryHandleForModelName(model) ?? registryHandle;
161610
+ }
161611
+ function resolveModelHandleFromLlmConfig(llmConfig) {
161612
+ if (!llmConfig?.model)
161613
+ return null;
161614
+ const model = llmConfig.model;
161615
+ const endpointType = llmConfig.model_endpoint_type;
161616
+ if (endpointType) {
161617
+ const normalizedModel2 = normalizeModelHandleForRegistry(model) ?? model;
161618
+ const modelProvider = providerPrefix(normalizedModel2);
161619
+ if (modelProvider && isKnownModelProviderPrefix(modelProvider) && endpointTypeMatchesModelProvider(endpointType, modelProvider)) {
161620
+ return normalizeKnownModelHandle(normalizedModel2);
161621
+ }
161622
+ return normalizeKnownModelHandle(`${modelHandleProviderForEndpointType(endpointType)}/${model}`);
161623
+ }
161624
+ const normalizedModel = normalizeKnownModelHandle(model);
161625
+ if (normalizedModel !== model || exactRegistryModelHandle(normalizedModel) || isKnownProviderPrefixedHandle(normalizedModel)) {
161626
+ return normalizedModel;
161627
+ }
161628
+ return model;
161629
+ }
161630
+ function endpointTypeForModelHandleProvider(provider) {
161631
+ const alias = MODEL_HANDLE_PROVIDER_LLM_CONFIG_ENDPOINT_TYPES.get(provider);
161632
+ if (alias)
161633
+ return alias;
161634
+ if (KNOWN_LLM_CONFIG_ENDPOINT_TYPES.has(provider))
161635
+ return provider;
161636
+ if (LOCAL_MODEL_PROVIDER_PREFIXES.has(provider))
161637
+ return provider;
161638
+ return null;
161639
+ }
161640
+ function endpointTypeForModelHandle(provider, providerType) {
161641
+ const inferred = endpointTypeForModelHandleProvider(provider);
161642
+ if (!providerType)
161643
+ return inferred;
161644
+ const compatibleProviderType = MODEL_SETTINGS_PROVIDER_LLM_CONFIG_ENDPOINT_TYPES.get(providerType) ?? providerType;
161645
+ if (!isKnownModelProviderPrefix(provider))
161646
+ return compatibleProviderType;
161647
+ if (providerType === "openai" && provider !== "openai")
161648
+ return inferred;
161649
+ return endpointTypeMatchesModelProvider(providerType, provider) ? compatibleProviderType : inferred;
161650
+ }
161651
+ function mapModelHandleToLlmConfigPatch(modelHandle, providerType) {
161652
+ const normalizedHandle = normalizeKnownModelHandle(modelHandle);
161653
+ const provider = providerPrefix(normalizedHandle);
161654
+ const model = modelPortionFromHandle(normalizedHandle);
161655
+ if (!provider || !model) {
161656
+ return { model: normalizedHandle };
161657
+ }
161658
+ const endpointType = endpointTypeForModelHandle(provider, providerType);
161659
+ if (!endpointType) {
161660
+ return { model: normalizedHandle };
161661
+ }
161662
+ const compatibleModel = endpointType === "openai" && provider !== "openai" ? normalizedHandle : model;
161663
+ return { model: compatibleModel, model_endpoint_type: endpointType };
161664
+ }
161665
+ var LOCAL_MODEL_HANDLE_PREFIXES, LOCAL_CHATGPT_OAUTH_HANDLE_PREFIX = "openai-codex/", CHATGPT_OAUTH_LLM_CONFIG_PROVIDER = "chatgpt_oauth", KNOWN_LLM_CONFIG_ENDPOINT_TYPES, LLM_CONFIG_ENDPOINT_TYPE_MODEL_HANDLE_PROVIDERS, MODEL_HANDLE_PROVIDER_LLM_CONFIG_ENDPOINT_TYPES, MODEL_SETTINGS_PROVIDER_LLM_CONFIG_ENDPOINT_TYPES, MODEL_HANDLE_PROVIDER_PREFIXES, LOCAL_MODEL_PROVIDER_PREFIXES;
161666
+ var init_model_handles = __esm(() => {
161667
+ init_model_catalog();
161668
+ LOCAL_MODEL_HANDLE_PREFIXES = [
161669
+ "ollama/",
161670
+ "ollama-cloud/",
161671
+ "lmstudio/",
161672
+ "llama.cpp/",
161673
+ "llama-cpp/"
161674
+ ];
161675
+ KNOWN_LLM_CONFIG_ENDPOINT_TYPES = new Set([
161676
+ "anthropic",
161677
+ "bedrock",
161678
+ "chatgpt_oauth",
161679
+ "google_ai",
161680
+ "google_vertex",
161681
+ "minimax",
161682
+ "moonshot",
161683
+ "moonshot_coding",
161684
+ "openai",
161685
+ "openrouter",
161686
+ "zai",
161687
+ "zai_coding"
161688
+ ]);
161689
+ LLM_CONFIG_ENDPOINT_TYPE_MODEL_HANDLE_PROVIDERS = new Map([
161690
+ [CHATGPT_OAUTH_LLM_CONFIG_PROVIDER, OPENAI_CODEX_PROVIDER_NAME],
161691
+ ["lmstudio", "lmstudio"],
161692
+ ["lmstudio_openai", "lmstudio"],
161693
+ ["llamacpp", "llama.cpp"],
161694
+ ["llama_cpp", "llama.cpp"],
161695
+ ["llama.cpp", "llama.cpp"],
161696
+ ["ollama_cloud", "ollama-cloud"]
161697
+ ]);
161698
+ MODEL_HANDLE_PROVIDER_LLM_CONFIG_ENDPOINT_TYPES = new Map([
161699
+ [OPENAI_CODEX_PROVIDER_NAME, CHATGPT_OAUTH_LLM_CONFIG_PROVIDER],
161700
+ ["openai-codex", CHATGPT_OAUTH_LLM_CONFIG_PROVIDER],
161701
+ ["lmstudio", "lmstudio"],
161702
+ ["llama.cpp", "llamacpp"],
161703
+ ["llama-cpp", "llamacpp"],
161704
+ ["ollama-cloud", "openai"]
161705
+ ]);
161706
+ MODEL_SETTINGS_PROVIDER_LLM_CONFIG_ENDPOINT_TYPES = new Map([
161707
+ ["lmstudio_openai", "lmstudio"],
161708
+ ["llama_cpp", "llamacpp"],
161709
+ ["llama.cpp", "llamacpp"],
161710
+ ["ollama_cloud", "openai"]
161711
+ ]);
161712
+ MODEL_HANDLE_PROVIDER_PREFIXES = new Set(models2.map((model) => providerPrefix(model.handle)).filter((provider) => provider !== null));
161713
+ LOCAL_MODEL_PROVIDER_PREFIXES = new Set(LOCAL_MODEL_HANDLE_PREFIXES.map((prefix) => prefix.slice(0, -1)));
161714
+ });
161715
+
161543
161716
  // src/agent/model.ts
161544
161717
  var exports_model = {};
161545
161718
  __export(exports_model, {
161546
161719
  shouldPreserveContextWindowForModelSelection: () => shouldPreserveContextWindowForModelSelection,
161720
+ resolveModelHandleFromLlmConfig: () => resolveModelHandleFromLlmConfig,
161547
161721
  resolveModelByLlmConfig: () => resolveModelByLlmConfig,
161548
161722
  resolveModel: () => resolveModel,
161549
161723
  normalizeModelHandleForRegistry: () => normalizeModelHandleForRegistry,
161724
+ normalizeKnownModelHandle: () => normalizeKnownModelHandle,
161550
161725
  models: () => models2,
161726
+ mapModelHandleToLlmConfigPatch: () => mapModelHandleToLlmConfigPatch,
161551
161727
  isLocalModelHandle: () => isLocalModelHandle,
161552
161728
  isLocalChatGptOAuthModelHandle: () => isLocalChatGptOAuthModelHandle,
161553
161729
  getResumeRefreshArgs: () => getResumeRefreshArgs,
@@ -161569,34 +161745,12 @@ function isLocalModelHandle(modelHandle) {
161569
161745
  return LOCAL_MODEL_HANDLE_PREFIXES.some((prefix) => modelHandle.startsWith(prefix));
161570
161746
  }
161571
161747
  function getLocalModelLabel(modelHandle) {
161572
- const providerPrefix = LOCAL_MODEL_HANDLE_PREFIXES.find((prefix) => modelHandle.startsWith(prefix));
161573
- return providerPrefix ? modelHandle.slice(providerPrefix.length) : modelHandle;
161748
+ const providerPrefix2 = LOCAL_MODEL_HANDLE_PREFIXES.find((prefix) => modelHandle.startsWith(prefix));
161749
+ return providerPrefix2 ? modelHandle.slice(providerPrefix2.length) : modelHandle;
161574
161750
  }
161575
161751
  function isModelReasoningEffort(value) {
161576
161752
  return typeof value === "string" && REASONING_EFFORT_ORDER.includes(value);
161577
161753
  }
161578
- function normalizeModelHandleForRegistry(modelHandle) {
161579
- if (!modelHandle)
161580
- return null;
161581
- const [provider, ...modelParts] = modelHandle.split("/");
161582
- const model = modelParts.join("/");
161583
- if (provider === CHATGPT_OAUTH_LLM_CONFIG_PROVIDER && model.length > 0) {
161584
- return `${OPENAI_CODEX_PROVIDER_NAME}/${model}`;
161585
- }
161586
- if (provider === LOCAL_CHATGPT_OAUTH_HANDLE_PREFIX.slice(0, -1) && model.length > 0 && !model.endsWith("-fast")) {
161587
- return `${OPENAI_CODEX_PROVIDER_NAME}/${model}`;
161588
- }
161589
- if (provider === "lc-anthropic" && model.length > 0) {
161590
- return `anthropic/${model}`;
161591
- }
161592
- return modelHandle;
161593
- }
161594
- function modelPortion(modelHandle) {
161595
- const slashIndex = modelHandle.indexOf("/");
161596
- if (slashIndex === -1)
161597
- return null;
161598
- return modelHandle.slice(slashIndex + 1);
161599
- }
161600
161754
  function isLocalChatGptOAuthModelHandle(modelHandle) {
161601
161755
  return modelHandle.startsWith(LOCAL_CHATGPT_OAUTH_HANDLE_PREFIX);
161602
161756
  }
@@ -161608,7 +161762,7 @@ function getChatGptFastRegistryHandleForModelHandle(modelHandle) {
161608
161762
  const normalized = normalizeModelHandleForRegistry(modelHandle);
161609
161763
  if (!normalized?.startsWith(`${OPENAI_CODEX_PROVIDER_NAME}/`))
161610
161764
  return null;
161611
- const model = modelPortion(normalized);
161765
+ const model = modelPortionFromHandle(normalized);
161612
161766
  if (!model || model.endsWith("-fast"))
161613
161767
  return null;
161614
161768
  const fastHandle = `${OPENAI_CODEX_PROVIDER_NAME}/${model}-fast`;
@@ -161782,17 +161936,17 @@ function findModelByHandle(handle) {
161782
161936
  return exactMatch;
161783
161937
  const [provider, ...rest3] = registryHandle.split("/");
161784
161938
  if (provider && rest3.length > 0) {
161785
- const modelPortion2 = rest3.join("/");
161939
+ const modelPortion = rest3.join("/");
161786
161940
  const providerMatches = models2.filter((m2) => {
161787
161941
  if (!m2.handle.startsWith(`${provider}/`))
161788
161942
  return false;
161789
161943
  const mModelPortion = m2.handle.slice(provider.length + 1);
161790
- return mModelPortion.includes(modelPortion2) || modelPortion2.includes(mModelPortion);
161944
+ return mModelPortion.includes(modelPortion) || modelPortion.includes(mModelPortion);
161791
161945
  });
161792
161946
  const providerMatch = pickPreferred(providerMatches);
161793
161947
  if (providerMatch)
161794
161948
  return providerMatch;
161795
- const suffixMatches = models2.filter((m2) => m2.handle.endsWith(`/${modelPortion2}`));
161949
+ const suffixMatches = models2.filter((m2) => m2.handle.endsWith(`/${modelPortion}`));
161796
161950
  const suffixMatch = pickPreferred(suffixMatches);
161797
161951
  if (suffixMatch)
161798
161952
  return suffixMatch;
@@ -161821,10 +161975,11 @@ function resolveModelByLlmConfig(llmConfigModel) {
161821
161975
  return exactMatch.id;
161822
161976
  return null;
161823
161977
  }
161824
- var REASONING_EFFORT_ORDER, LOCAL_REASONING_EFFORT_ORDER, LOCAL_MODEL_HANDLE_PREFIXES, LOCAL_CHATGPT_OAUTH_HANDLE_PREFIX = "openai-codex/", CHATGPT_OAUTH_LLM_CONFIG_PROVIDER = "chatgpt_oauth", CHATGPT_FAST_SERVICE_TIER = "priority", RESUME_REFRESH_FIELDS;
161978
+ var REASONING_EFFORT_ORDER, LOCAL_REASONING_EFFORT_ORDER, CHATGPT_FAST_SERVICE_TIER = "priority", RESUME_REFRESH_FIELDS;
161825
161979
  var init_model = __esm(() => {
161826
- init_openai_codex_provider();
161827
161980
  init_model_catalog();
161981
+ init_model_handles();
161982
+ init_model_handles();
161828
161983
  REASONING_EFFORT_ORDER = [
161829
161984
  "none",
161830
161985
  "minimal",
@@ -161840,13 +161995,6 @@ var init_model = __esm(() => {
161840
161995
  "medium",
161841
161996
  "high"
161842
161997
  ];
161843
- LOCAL_MODEL_HANDLE_PREFIXES = [
161844
- "ollama/",
161845
- "ollama-cloud/",
161846
- "lmstudio/",
161847
- "llama.cpp/",
161848
- "llama-cpp/"
161849
- ];
161850
161998
  RESUME_REFRESH_FIELDS = [
161851
161999
  "max_output_tokens",
161852
162000
  "parallel_tool_calls"
@@ -179033,16 +179181,8 @@ var init_subagent_state = __esm(() => {
179033
179181
  });
179034
179182
 
179035
179183
  // src/mods/context.ts
179036
- function buildModelHandleFromLlmConfig(llmConfig) {
179037
- if (!llmConfig)
179038
- return null;
179039
- if (llmConfig.model_endpoint_type && llmConfig.model) {
179040
- return `${llmConfig.model_endpoint_type}/${llmConfig.model}`;
179041
- }
179042
- return llmConfig.model ?? null;
179043
- }
179044
179184
  function resolveModelContext(options3) {
179045
- const modelHandle = options3.modelIdentifier ?? options3.agent?.model ?? buildModelHandleFromLlmConfig(options3.agent?.llm_config) ?? options3.base?.model.id ?? null;
179185
+ const modelHandle = options3.modelIdentifier ?? options3.agent?.model ?? resolveModelHandleFromLlmConfig(options3.agent?.llm_config) ?? options3.base?.model.id ?? null;
179046
179186
  const modelInfo = modelHandle ? getModelInfo(modelHandle) : null;
179047
179187
  const provider = modelInfo?.handle.split("/")[0] ?? modelHandle?.split("/")[0] ?? null;
179048
179188
  return {
@@ -179106,6 +179246,7 @@ function buildModInvocationContext(options3 = {}) {
179106
179246
  }
179107
179247
  var init_context2 = __esm(() => {
179108
179248
  init_model();
179249
+ init_model_handles();
179109
179250
  init_subagent_state();
179110
179251
  init_runtime_context();
179111
179252
  init_version();
@@ -382464,8 +382605,125 @@ var init_context_budget = __esm(() => {
382464
382605
  REFLECTION_STARTUP_CONTEXT_CHAR_LIMIT = REFLECTION_STARTUP_CONTEXT_TOKEN_LIMIT * STARTUP_CONTEXT_ESTIMATED_CHARS_PER_TOKEN;
382465
382606
  });
382466
382607
 
382467
- // src/agent/subagents/manager.ts
382468
- import { spawn as spawn8 } from "node:child_process";
382608
+ // src/agent/subagents/subagent-launcher.ts
382609
+ function resolveSubagentWorkingDirectory(env3 = process.env, fallbackCwd = getCurrentWorkingDirectory(), options3 = {}) {
382610
+ if (options3.subagentType === "reflection" && options3.launchProfile === "memory-subagent" && options3.memoryScope) {
382611
+ return env3.USER_CWD || fallbackCwd;
382612
+ }
382613
+ const primaryRoot = options3.memoryScope?.primaryRoot ?? options3.inheritedPrimaryRoot;
382614
+ if (options3.subagentType === "reflection" && options3.launchProfile === "memory-subagent" && primaryRoot) {
382615
+ return primaryRoot;
382616
+ }
382617
+ return env3.USER_CWD || fallbackCwd;
382618
+ }
382619
+ function resolveSubagentLauncher(cliArgs, options3 = {}) {
382620
+ const env3 = options3.env ?? process.env;
382621
+ const argv = options3.argv ?? process.argv;
382622
+ const execPath = options3.execPath ?? process.execPath;
382623
+ const platform3 = options3.platform ?? process.platform;
382624
+ const cwd = options3.cwd ?? process.cwd();
382625
+ const invocation = resolveLettaInvocation(env3, argv, execPath, cwd);
382626
+ if (invocation) {
382627
+ return {
382628
+ command: invocation.command,
382629
+ args: [...invocation.args, ...cliArgs]
382630
+ };
382631
+ }
382632
+ const currentScript = argv[1] || "";
382633
+ const resolvedCurrentScript = resolveEntryScriptPath(currentScript, cwd);
382634
+ if (currentScript.endsWith(".ts")) {
382635
+ return {
382636
+ command: execPath,
382637
+ args: [resolvedCurrentScript, ...cliArgs]
382638
+ };
382639
+ }
382640
+ if (currentScript.endsWith(".js") && platform3 === "win32") {
382641
+ return {
382642
+ command: execPath,
382643
+ args: [resolvedCurrentScript, ...cliArgs]
382644
+ };
382645
+ }
382646
+ if (currentScript.endsWith(".js")) {
382647
+ return {
382648
+ command: resolvedCurrentScript,
382649
+ args: cliArgs
382650
+ };
382651
+ }
382652
+ return {
382653
+ command: "letta",
382654
+ args: cliArgs
382655
+ };
382656
+ }
382657
+ function buildInheritedChannelContextPayload(runtimeContext) {
382658
+ const channelToolScope = runtimeContext?.channelToolScope;
382659
+ const channelTurnSources = runtimeContext?.channelTurnSources ?? [];
382660
+ if (!channelToolScope?.channels.length && channelTurnSources.length === 0) {
382661
+ return null;
382662
+ }
382663
+ return {
382664
+ ...channelToolScope?.channels.length ? { channelToolScope } : {},
382665
+ ...channelTurnSources.length ? { channelTurnSources: [...channelTurnSources] } : {}
382666
+ };
382667
+ }
382668
+ function composeSubagentChildEnv(options3) {
382669
+ const {
382670
+ parentProcessEnv,
382671
+ backendMode,
382672
+ localBackendStorageDir,
382673
+ parentAgentId,
382674
+ launchProfile,
382675
+ inheritedPrimaryRoot,
382676
+ memoryScope,
382677
+ inheritedApiKey,
382678
+ inheritedBaseUrl,
382679
+ transcriptPath,
382680
+ inheritedChannelContext
382681
+ } = options3;
382682
+ const childEnv = {
382683
+ ...parentProcessEnv,
382684
+ ...inheritedApiKey && { LETTA_API_KEY: inheritedApiKey },
382685
+ ...inheritedBaseUrl && { LETTA_BASE_URL: inheritedBaseUrl },
382686
+ LETTA_CODE_AGENT_ROLE: "subagent",
382687
+ ...parentAgentId && { LETTA_PARENT_AGENT_ID: parentAgentId },
382688
+ ...transcriptPath && { TRANSCRIPT_PATH: transcriptPath },
382689
+ ...inheritedChannelContext && {
382690
+ [LETTA_INHERITED_CHANNEL_CONTEXT_ENV]: JSON.stringify(inheritedChannelContext)
382691
+ }
382692
+ };
382693
+ if (backendMode === "local") {
382694
+ childEnv.LETTA_LOCAL_BACKEND_EXPERIMENTAL = "1";
382695
+ if (localBackendStorageDir) {
382696
+ childEnv.LETTA_LOCAL_BACKEND_DIR = localBackendStorageDir;
382697
+ }
382698
+ } else if (backendMode === "api") {
382699
+ childEnv.LETTA_LOCAL_BACKEND_EXPERIMENTAL = "0";
382700
+ }
382701
+ if (launchProfile === "memory-subagent") {
382702
+ const primaryRoot = memoryScope?.primaryRoot ?? inheritedPrimaryRoot;
382703
+ if (primaryRoot) {
382704
+ childEnv.MEMORY_DIR = primaryRoot;
382705
+ childEnv.LETTA_MEMORY_DIR = primaryRoot;
382706
+ } else {
382707
+ delete childEnv.MEMORY_DIR;
382708
+ delete childEnv.LETTA_MEMORY_DIR;
382709
+ }
382710
+ }
382711
+ return childEnv;
382712
+ }
382713
+ function resolveSubagentInheritedPrimaryRoot(options3) {
382714
+ if (options3.backendMode === "local" && options3.parentAgentId) {
382715
+ return getLocalBackendMemoryFilesystemRoot(options3.parentAgentId, options3.localBackendStorageDir ?? getLocalBackendStorageDir2());
382716
+ }
382717
+ return options3.inheritedPrimaryRoot;
382718
+ }
382719
+ var init_subagent_launcher = __esm(() => {
382720
+ init_backend2();
382721
+ init_paths();
382722
+ init_runtime_context();
382723
+ init_shell_env();
382724
+ });
382725
+
382726
+ // src/agent/subagents/subagent-model.ts
382469
382727
  function getModelHandleFromAgent(agent2) {
382470
382728
  const directModel = agent2.model;
382471
382729
  if (directModel?.includes("/")) {
@@ -382504,9 +382762,6 @@ async function getPrimaryAgentModelHandle(scope = {}) {
382504
382762
  async function getCurrentBillingTier() {
382505
382763
  return getBillingTier();
382506
382764
  }
382507
- function isProviderNotSupportedError(errorOutput) {
382508
- return errorOutput.includes("Provider") && errorOutput.includes("is not supported") && errorOutput.includes("supported providers:");
382509
- }
382510
382765
  function getProviderPrefix(handle) {
382511
382766
  const slashIndex = handle.indexOf("/");
382512
382767
  if (slashIndex === -1)
@@ -382523,8 +382778,8 @@ function swapProviderPrefix(parentHandle, recommendedHandle) {
382523
382778
  const recommendedProvider = getProviderPrefix(recommendedHandle);
382524
382779
  if (!recommendedProvider || recommendedProvider !== baseProvider)
382525
382780
  return null;
382526
- const modelPortion2 = recommendedHandle.slice(recommendedProvider.length + 1);
382527
- return `${parentProvider}/${modelPortion2}`;
382781
+ const modelPortion = recommendedHandle.slice(recommendedProvider.length + 1);
382782
+ return `${parentProvider}/${modelPortion}`;
382528
382783
  }
382529
382784
  function isInheritModel(model) {
382530
382785
  return model?.trim().toLowerCase() === "inherit";
@@ -382608,6 +382863,26 @@ async function resolveSubagentModel(options3) {
382608
382863
  }
382609
382864
  return recommendedHandle;
382610
382865
  }
382866
+ var BYOK_PROVIDER_TO_BASE;
382867
+ var init_subagent_model = __esm(() => {
382868
+ init_available_models();
382869
+ init_context();
382870
+ init_model();
382871
+ init_backend2();
382872
+ init_metadata();
382873
+ BYOK_PROVIDER_TO_BASE = {
382874
+ "lc-anthropic": "anthropic",
382875
+ "lc-openai": "openai",
382876
+ "lc-zai": "zai",
382877
+ "lc-gemini": "google_ai",
382878
+ "lc-openrouter": "openrouter",
382879
+ "lc-minimax": "minimax",
382880
+ "lc-bedrock": "bedrock",
382881
+ "chatgpt-plus-pro": "chatgpt-plus-pro"
382882
+ };
382883
+ });
382884
+
382885
+ // src/agent/subagents/subagent-stream.ts
382611
382886
  function recordToolCall(subagentId, toolCallId, toolName, toolArgs, displayedToolCalls) {
382612
382887
  if (!toolCallId || !toolName || displayedToolCalls.has(toolCallId))
382613
382888
  return;
@@ -382711,115 +382986,16 @@ function parseResultFromStdout(stdout, agentId) {
382711
382986
  };
382712
382987
  }
382713
382988
  }
382714
- function resolveSubagentWorkingDirectory(env3 = process.env, fallbackCwd = getCurrentWorkingDirectory(), options3 = {}) {
382715
- if (options3.subagentType === "reflection" && options3.launchProfile === "memory-subagent" && options3.memoryScope) {
382716
- return env3.USER_CWD || fallbackCwd;
382717
- }
382718
- const primaryRoot = options3.memoryScope?.primaryRoot ?? options3.inheritedPrimaryRoot;
382719
- if (options3.subagentType === "reflection" && options3.launchProfile === "memory-subagent" && primaryRoot) {
382720
- return primaryRoot;
382721
- }
382722
- return env3.USER_CWD || fallbackCwd;
382723
- }
382724
- function resolveSubagentLauncher(cliArgs, options3 = {}) {
382725
- const env3 = options3.env ?? process.env;
382726
- const argv = options3.argv ?? process.argv;
382727
- const execPath = options3.execPath ?? process.execPath;
382728
- const platform3 = options3.platform ?? process.platform;
382729
- const cwd = options3.cwd ?? process.cwd();
382730
- const invocation = resolveLettaInvocation(env3, argv, execPath, cwd);
382731
- if (invocation) {
382732
- return {
382733
- command: invocation.command,
382734
- args: [...invocation.args, ...cliArgs]
382735
- };
382736
- }
382737
- const currentScript = argv[1] || "";
382738
- const resolvedCurrentScript = resolveEntryScriptPath(currentScript, cwd);
382739
- if (currentScript.endsWith(".ts")) {
382740
- return {
382741
- command: execPath,
382742
- args: [resolvedCurrentScript, ...cliArgs]
382743
- };
382744
- }
382745
- if (currentScript.endsWith(".js") && platform3 === "win32") {
382746
- return {
382747
- command: execPath,
382748
- args: [resolvedCurrentScript, ...cliArgs]
382749
- };
382750
- }
382751
- if (currentScript.endsWith(".js")) {
382752
- return {
382753
- command: resolvedCurrentScript,
382754
- args: cliArgs
382755
- };
382756
- }
382757
- return {
382758
- command: "letta",
382759
- args: cliArgs
382760
- };
382761
- }
382762
- function buildInheritedChannelContextPayload(runtimeContext) {
382763
- const channelToolScope = runtimeContext?.channelToolScope;
382764
- const channelTurnSources = runtimeContext?.channelTurnSources ?? [];
382765
- if (!channelToolScope?.channels.length && channelTurnSources.length === 0) {
382766
- return null;
382767
- }
382768
- return {
382769
- ...channelToolScope?.channels.length ? { channelToolScope } : {},
382770
- ...channelTurnSources.length ? { channelTurnSources: [...channelTurnSources] } : {}
382771
- };
382772
- }
382773
- function composeSubagentChildEnv(options3) {
382774
- const {
382775
- parentProcessEnv,
382776
- backendMode,
382777
- localBackendStorageDir,
382778
- parentAgentId,
382779
- launchProfile,
382780
- inheritedPrimaryRoot,
382781
- memoryScope,
382782
- inheritedApiKey,
382783
- inheritedBaseUrl,
382784
- transcriptPath,
382785
- inheritedChannelContext
382786
- } = options3;
382787
- const childEnv = {
382788
- ...parentProcessEnv,
382789
- ...inheritedApiKey && { LETTA_API_KEY: inheritedApiKey },
382790
- ...inheritedBaseUrl && { LETTA_BASE_URL: inheritedBaseUrl },
382791
- LETTA_CODE_AGENT_ROLE: "subagent",
382792
- ...parentAgentId && { LETTA_PARENT_AGENT_ID: parentAgentId },
382793
- ...transcriptPath && { TRANSCRIPT_PATH: transcriptPath },
382794
- ...inheritedChannelContext && {
382795
- [LETTA_INHERITED_CHANNEL_CONTEXT_ENV]: JSON.stringify(inheritedChannelContext)
382796
- }
382797
- };
382798
- if (backendMode === "local") {
382799
- childEnv.LETTA_LOCAL_BACKEND_EXPERIMENTAL = "1";
382800
- if (localBackendStorageDir) {
382801
- childEnv.LETTA_LOCAL_BACKEND_DIR = localBackendStorageDir;
382802
- }
382803
- } else if (backendMode === "api") {
382804
- childEnv.LETTA_LOCAL_BACKEND_EXPERIMENTAL = "0";
382805
- }
382806
- if (launchProfile === "memory-subagent") {
382807
- const primaryRoot = memoryScope?.primaryRoot ?? inheritedPrimaryRoot;
382808
- if (primaryRoot) {
382809
- childEnv.MEMORY_DIR = primaryRoot;
382810
- childEnv.LETTA_MEMORY_DIR = primaryRoot;
382811
- } else {
382812
- delete childEnv.MEMORY_DIR;
382813
- delete childEnv.LETTA_MEMORY_DIR;
382814
- }
382815
- }
382816
- return childEnv;
382817
- }
382818
- function resolveSubagentInheritedPrimaryRoot(options3) {
382819
- if (options3.backendMode === "local" && options3.parentAgentId) {
382820
- return getLocalBackendMemoryFilesystemRoot(options3.parentAgentId, options3.localBackendStorageDir ?? getLocalBackendStorageDir2());
382821
- }
382822
- return options3.inheritedPrimaryRoot;
382989
+ var init_subagent_stream = __esm(() => {
382990
+ init_subagent_state();
382991
+ init_app_urls();
382992
+ init_debug();
382993
+ });
382994
+
382995
+ // src/agent/subagents/manager.ts
382996
+ import { spawn as spawn8 } from "node:child_process";
382997
+ function isProviderNotSupportedError(errorOutput) {
382998
+ return errorOutput.includes("Provider") && errorOutput.includes("is not supported") && errorOutput.includes("supported providers:");
382823
382999
  }
382824
383000
  function getReflectionStartupNotice() {
382825
383001
  return `[Reflection startup context truncated: system prompt + initial message are capped at ~${REFLECTION_STARTUP_CONTEXT_TOKEN_LIMIT.toLocaleString()} estimated tokens. Some parent memory preview content was omitted; read files directly from MEMORY_DIR if needed.]`;
@@ -383257,18 +383433,14 @@ async function spawnSubagent(type3, prompt, userModel, subagentId, signal, exist
383257
383433
  const result = await executeSubagent(type3, config3, model, finalPrompt, baseURL, subagentId, false, signal, existingAgentId, existingConversationId, maxTurns, resolvedParentAgentId, transcriptPath, memoryScope);
383258
383434
  return result;
383259
383435
  }
383260
- var NO_BASE_TOOL_SUBAGENT_TYPES, BYOK_PROVIDER_TO_BASE;
383436
+ var NO_BASE_TOOL_SUBAGENT_TYPES;
383261
383437
  var init_manager3 = __esm(() => {
383262
- init_available_models();
383263
383438
  init_context();
383264
- init_model();
383265
383439
  init_recall_subagent();
383266
383440
  init_recall_subagent_local();
383267
383441
  init_subagent_state();
383268
383442
  init_sandbox();
383269
383443
  init_backend2();
383270
- init_metadata();
383271
- init_paths();
383272
383444
  init_app_urls();
383273
383445
  init_constants2();
383274
383446
  init_cli_permissions_instance();
@@ -383276,26 +383448,18 @@ var init_manager3 = __esm(() => {
383276
383448
  init_session2();
383277
383449
  init_runtime_context();
383278
383450
  init_settings_manager();
383279
- init_shell_env();
383280
383451
  init_debug();
383281
383452
  init_subagents();
383282
383453
  init_context_budget();
383454
+ init_subagent_launcher();
383455
+ init_subagent_model();
383456
+ init_subagent_stream();
383283
383457
  NO_BASE_TOOL_SUBAGENT_TYPES = new Set([
383284
383458
  "reflection",
383285
383459
  "memory",
383286
383460
  "history-analyzer",
383287
383461
  "init"
383288
383462
  ]);
383289
- BYOK_PROVIDER_TO_BASE = {
383290
- "lc-anthropic": "anthropic",
383291
- "lc-openai": "openai",
383292
- "lc-zai": "zai",
383293
- "lc-gemini": "google_ai",
383294
- "lc-openrouter": "openrouter",
383295
- "lc-minimax": "minimax",
383296
- "lc-bedrock": "bedrock",
383297
- "chatgpt-plus-pro": "chatgpt-plus-pro"
383298
- };
383299
383463
  });
383300
383464
 
383301
383465
  // src/utils/message-queue-bridge.ts
@@ -391175,21 +391339,13 @@ function providerTypeFromModelSettings(modelSettings) {
391175
391339
  const providerType = modelSettings.provider_type;
391176
391340
  return typeof providerType === "string" ? providerType : null;
391177
391341
  }
391178
- function buildModelHandleFromLlmConfig2(llmConfig) {
391179
- if (!llmConfig)
391180
- return null;
391181
- if (llmConfig.model_endpoint_type && llmConfig.model) {
391182
- return `${llmConfig.model_endpoint_type}/${llmConfig.model}`;
391183
- }
391184
- return llmConfig.model ?? null;
391185
- }
391186
391342
  function getPreferredAgentModelHandle(agent2) {
391187
391343
  if (!agent2)
391188
391344
  return null;
391189
391345
  if (typeof agent2.model === "string" && agent2.model.length > 0) {
391190
391346
  return agent2.model;
391191
391347
  }
391192
- return buildModelHandleFromLlmConfig2(agent2.llm_config);
391348
+ return resolveModelHandleFromLlmConfig(agent2.llm_config);
391193
391349
  }
391194
391350
  function getToolNamesForToolset(toolsetName, channelToolScope) {
391195
391351
  let tools;
@@ -391601,6 +391757,7 @@ async function switchToolsetForModel(modelIdentifier, agentId, providerType) {
391601
391757
  var ARTIFACT_TOOL_NAMES2, MEMORY_TOOL_NAMES;
391602
391758
  var init_toolset = __esm(async () => {
391603
391759
  init_model();
391760
+ init_model_handles();
391604
391761
  init_backend2();
391605
391762
  init_client2();
391606
391763
  init_plugin_registry();
@@ -393755,6 +393912,67 @@ function mergeSnapshotContentWithExistingToolCalls(snapshotContent, existingCont
393755
393912
  }
393756
393913
  var LOCAL_REPAIRED_TOOL_RESULT_TEXT_MAX_CHARS = 40000;
393757
393914
 
393915
+ // src/backend/local/local-model-normalization.ts
393916
+ function supportedModelSettingsFromBody(bodyRecord) {
393917
+ const modelSettings = isRecord(bodyRecord.model_settings) ? { ...bodyRecord.model_settings } : {};
393918
+ if (typeof bodyRecord.context_window_limit === "number") {
393919
+ modelSettings.context_window_limit = bodyRecord.context_window_limit;
393920
+ }
393921
+ if (typeof bodyRecord.parallel_tool_calls === "boolean") {
393922
+ modelSettings.parallel_tool_calls = bodyRecord.parallel_tool_calls;
393923
+ }
393924
+ if (typeof bodyRecord.max_tokens === "number" || bodyRecord.max_tokens === null) {
393925
+ modelSettings.max_tokens = bodyRecord.max_tokens;
393926
+ }
393927
+ return modelSettings;
393928
+ }
393929
+ function providerTypeFromModelSettings2(modelSettings) {
393930
+ const providerType = modelSettings?.provider_type;
393931
+ return typeof providerType === "string" && providerType.length > 0 ? providerType : null;
393932
+ }
393933
+ function normalizeLocalModelHandle(model, modelSettings, legacyLlmConfig) {
393934
+ const providerType = providerTypeFromModelSettings2(modelSettings);
393935
+ const legacyEndpointType = legacyLlmConfig?.model_endpoint_type;
393936
+ return resolveModelHandleFromLlmConfig({
393937
+ model,
393938
+ model_endpoint_type: providerType ?? (typeof legacyEndpointType === "string" ? legacyEndpointType : null)
393939
+ }) ?? model;
393940
+ }
393941
+ function modelHandleFromLegacyLlmConfig(legacyLlmConfig) {
393942
+ const model = legacyLlmConfig.model;
393943
+ if (typeof model !== "string")
393944
+ return null;
393945
+ const modelEndpointType = legacyLlmConfig.model_endpoint_type;
393946
+ return resolveModelHandleFromLlmConfig({
393947
+ model,
393948
+ model_endpoint_type: typeof modelEndpointType === "string" ? modelEndpointType : null
393949
+ });
393950
+ }
393951
+ function supportedConversationModelSettingsFromBody(bodyRecord) {
393952
+ const rawSettings = bodyRecord.model_settings;
393953
+ const modelSettings = rawSettings === null ? null : isRecord(rawSettings) ? { ...rawSettings } : undefined;
393954
+ if (modelSettings === null)
393955
+ return null;
393956
+ const next = modelSettings ?? {};
393957
+ if (typeof bodyRecord.max_tokens === "number" || bodyRecord.max_tokens === null) {
393958
+ next.max_tokens = bodyRecord.max_tokens;
393959
+ }
393960
+ return Object.keys(next).length > 0 ? next : modelSettings;
393961
+ }
393962
+ function normalizeStoredLocalModelRecord(record5) {
393963
+ if (typeof record5.model !== "string")
393964
+ return record5;
393965
+ const modelSettings = isRecord(record5.model_settings) ? record5.model_settings : {};
393966
+ const normalizedModel = normalizeLocalModelHandle(record5.model, modelSettings);
393967
+ return normalizedModel === record5.model ? record5 : { ...record5, model: normalizedModel };
393968
+ }
393969
+ function localLlmConfigModelPatch(model, modelSettings) {
393970
+ return mapModelHandleToLlmConfigPatch(model, providerTypeFromModelSettings2(modelSettings));
393971
+ }
393972
+ var init_local_model_normalization = __esm(() => {
393973
+ init_model_handles();
393974
+ });
393975
+
393758
393976
  // src/backend/local/local-stream-chunks.ts
393759
393977
  function attachLocalMessage(target2, message) {
393760
393978
  Object.defineProperty(target2, LOCAL_MESSAGE, {
@@ -393829,19 +394047,6 @@ function optionalString(value) {
393829
394047
  function optionalStringOrNull(value) {
393830
394048
  return typeof value === "string" || value === null ? value : undefined;
393831
394049
  }
393832
- function supportedModelSettingsFromBody(bodyRecord) {
393833
- const modelSettings = isRecord(bodyRecord.model_settings) ? { ...bodyRecord.model_settings } : {};
393834
- if (typeof bodyRecord.context_window_limit === "number") {
393835
- modelSettings.context_window_limit = bodyRecord.context_window_limit;
393836
- }
393837
- if (typeof bodyRecord.parallel_tool_calls === "boolean") {
393838
- modelSettings.parallel_tool_calls = bodyRecord.parallel_tool_calls;
393839
- }
393840
- if (typeof bodyRecord.max_tokens === "number" || bodyRecord.max_tokens === null) {
393841
- modelSettings.max_tokens = bodyRecord.max_tokens;
393842
- }
393843
- return modelSettings;
393844
- }
393845
394050
  function createDefaultAgentRecord(agentId, defaultAgentName, defaultAgentModel) {
393846
394051
  return {
393847
394052
  id: agentId,
@@ -393857,14 +394062,16 @@ function createLocalAgentRecord(body, defaultAgentName, defaultAgentModel) {
393857
394062
  const bodyRecord = body;
393858
394063
  const tags = isStringArray2(bodyRecord.tags) ? bodyRecord.tags : [];
393859
394064
  const hidden = normalizeAgentHiddenFlag(bodyRecord.hidden, tags);
394065
+ const modelSettings = supportedModelSettingsFromBody(bodyRecord);
394066
+ const requestedModel = optionalString(bodyRecord.model) ?? defaultAgentModel;
393860
394067
  return {
393861
394068
  id: `agent-local-${randomUUID18()}`,
393862
394069
  name: optionalString(bodyRecord.name) ?? defaultAgentName,
393863
394070
  description: optionalStringOrNull(bodyRecord.description) ?? null,
393864
394071
  system: optionalString(bodyRecord.system) ?? "",
393865
394072
  tags,
393866
- model: optionalString(bodyRecord.model) ?? defaultAgentModel,
393867
- model_settings: supportedModelSettingsFromBody(bodyRecord),
394073
+ model: normalizeLocalModelHandle(requestedModel, modelSettings),
394074
+ model_settings: modelSettings,
393868
394075
  ...hidden !== undefined ? { hidden } : {}
393869
394076
  };
393870
394077
  }
@@ -393891,19 +394098,6 @@ function optionalRecordOrNull(value) {
393891
394098
  return null;
393892
394099
  return isRecord(value) ? { ...value } : undefined;
393893
394100
  }
393894
- function conversationModelSettings(value) {
393895
- return optionalRecordOrNull(value);
393896
- }
393897
- function supportedConversationModelSettingsFromBody(bodyRecord) {
393898
- const modelSettings = conversationModelSettings(bodyRecord.model_settings);
393899
- if (modelSettings === null)
393900
- return null;
393901
- const next = modelSettings ?? {};
393902
- if (typeof bodyRecord.max_tokens === "number" || bodyRecord.max_tokens === null) {
393903
- next.max_tokens = bodyRecord.max_tokens;
393904
- }
393905
- return Object.keys(next).length > 0 ? next : modelSettings;
393906
- }
393907
394101
  function createLocalConversationRecord(conversationId, agentId, _sequence, body = {}) {
393908
394102
  const bodyRecord = body;
393909
394103
  const now = currentIsoTimestamp();
@@ -393918,7 +394112,9 @@ function createLocalConversationRecord(conversationId, agentId, _sequence, body
393918
394112
  last_message_at: null,
393919
394113
  summary: optionalStringOrNull(bodyRecord.summary) ?? null,
393920
394114
  in_context_message_ids: [],
393921
- ...typeof bodyRecord.model === "string" || bodyRecord.model === null ? { model: bodyRecord.model } : {},
394115
+ ...typeof bodyRecord.model === "string" || bodyRecord.model === null ? {
394116
+ model: bodyRecord.model === null ? null : normalizeLocalModelHandle(bodyRecord.model, modelSettings ?? {})
394117
+ } : {},
393922
394118
  ...modelSettings !== undefined ? { model_settings: modelSettings } : {},
393923
394119
  ...typeof bodyRecord.context_window_limit === "number" ? { context_window_limit: bodyRecord.context_window_limit } : {},
393924
394120
  ...typeof bodyRecord.hidden === "boolean" ? { hidden: bodyRecord.hidden } : {}
@@ -393930,6 +394126,7 @@ function updateLocalConversationRecord(current, body, updatedAt) {
393930
394126
  ...current,
393931
394127
  updated_at: updatedAt
393932
394128
  };
394129
+ const modelSettings = supportedConversationModelSettingsFromBody(bodyRecord);
393933
394130
  if (typeof bodyRecord.archived === "boolean") {
393934
394131
  next.archived = bodyRecord.archived;
393935
394132
  next.archived_at = bodyRecord.archived ? current.archived_at ?? updatedAt : null;
@@ -393942,9 +394139,8 @@ function updateLocalConversationRecord(current, body, updatedAt) {
393942
394139
  next.last_message_at = bodyRecord.last_message_at;
393943
394140
  }
393944
394141
  if (typeof bodyRecord.model === "string" || bodyRecord.model === null) {
393945
- next.model = bodyRecord.model;
394142
+ next.model = bodyRecord.model === null ? null : normalizeLocalModelHandle(bodyRecord.model, modelSettings ?? {});
393946
394143
  }
393947
- const modelSettings = supportedConversationModelSettingsFromBody(bodyRecord);
393948
394144
  if (modelSettings !== undefined) {
393949
394145
  next.model_settings = modelSettings;
393950
394146
  }
@@ -393973,13 +394169,16 @@ function normalizeAgentRecord(value, defaultAgentModel) {
393973
394169
  const compactionSettings = optionalRecordOrNull(value.compaction_settings);
393974
394170
  const tags = isStringArray2(value.tags) ? value.tags : [];
393975
394171
  const hidden = normalizeAgentHiddenFlag(value.hidden, tags);
394172
+ const storedModel = optionalString(value.model);
394173
+ const legacyModel = modelHandleFromLegacyLlmConfig(legacyLlmConfig);
394174
+ const model = storedModel ? normalizeLocalModelHandle(storedModel, modelSettings, legacyLlmConfig) : legacyModel ?? defaultAgentModel;
393976
394175
  return {
393977
394176
  id: value.id,
393978
394177
  name: optionalString(value.name) ?? "Letta Code",
393979
394178
  description: optionalStringOrNull(value.description) ?? null,
393980
394179
  system: optionalString(value.system) ?? "",
393981
394180
  tags,
393982
- model: optionalString(value.model) ?? optionalString(legacyLlmConfig.model) ?? defaultAgentModel,
394181
+ model,
393983
394182
  model_settings: modelSettings,
393984
394183
  ...hidden !== undefined ? { hidden } : {},
393985
394184
  ...compactionSettings !== undefined ? { compaction_settings: compactionSettings } : {}
@@ -393990,6 +394189,7 @@ function projectLocalAgentState(record5, messageIds = [], inContextMessageIds =
393990
394189
  const nestedReasoning = isRecord(record5.model_settings.reasoning) ? record5.model_settings.reasoning : undefined;
393991
394190
  const reasoningEffort = typeof nestedReasoning?.reasoning_effort === "string" ? nestedReasoning.reasoning_effort : typeof record5.model_settings.effort === "string" ? record5.model_settings.effort : typeof record5.model_settings.reasoning_effort === "string" ? record5.model_settings.reasoning_effort : undefined;
393992
394191
  const enableReasoner = isRecord(record5.model_settings.thinking) && record5.model_settings.thinking.type === "disabled" ? false : typeof record5.model_settings.enable_reasoner === "boolean" ? record5.model_settings.enable_reasoner : undefined;
394192
+ const llmConfigModelPatch = localLlmConfigModelPatch(record5.model, record5.model_settings);
393993
394193
  return {
393994
394194
  id: record5.id,
393995
394195
  name: record5.name,
@@ -394005,8 +394205,7 @@ function projectLocalAgentState(record5, messageIds = [], inContextMessageIds =
394005
394205
  in_context_message_ids: inContextMessageIds,
394006
394206
  ...lastRunCompletion ? { last_run_completion: lastRunCompletion } : {},
394007
394207
  llm_config: {
394008
- model: record5.model,
394009
- model_endpoint_type: "openai",
394208
+ ...llmConfigModelPatch,
394010
394209
  model_endpoint: "https://example.invalid/v1",
394011
394210
  context_window: typeof record5.model_settings.context_window_limit === "number" ? record5.model_settings.context_window_limit : 128000,
394012
394211
  ...reasoningEffort && { reasoning_effort: reasoningEffort },
@@ -394521,12 +394720,13 @@ class LocalStore {
394521
394720
  const nextSystem = typeof bodyRecord.system === "string" ? bodyRecord.system : undefined;
394522
394721
  const systemChanged = nextSystem !== undefined && nextSystem !== existingRecord.system;
394523
394722
  const requestedModel = bodyRecord.model;
394524
- const nextModel = typeof requestedModel === "string" && !shouldUseDefaultLocalModel(requestedModel) ? requestedModel : typeof requestedModel === "string" && this.defaultAgentModel ? this.defaultAgentModel : undefined;
394723
+ const requestedModelSettings = supportedModelSettingsFromBody(bodyRecord);
394724
+ const nextModel = typeof requestedModel === "string" && !shouldUseDefaultLocalModel(requestedModel) ? normalizeLocalModelHandle(requestedModel, requestedModelSettings) : typeof requestedModel === "string" && this.defaultAgentModel ? this.defaultAgentModel : undefined;
394525
394725
  const modelChanged = nextModel !== undefined && nextModel !== existingRecord.model;
394526
394726
  const nextModelDefaults = nextModel ? this.modelSettingsDefaultsForModel(nextModel) : undefined;
394527
394727
  const nextModelSettings = {
394528
394728
  ...modelChanged ? {} : existingRecord.model_settings,
394529
- ...supportedModelSettingsFromBody(bodyRecord),
394729
+ ...requestedModelSettings,
394530
394730
  ...modelChanged ? nextModelDefaults ?? {} : {}
394531
394731
  };
394532
394732
  const updated = {
@@ -394687,9 +394887,10 @@ class LocalStore {
394687
394887
  const requestedModel = body.model;
394688
394888
  if (typeof requestedModel !== "string")
394689
394889
  return conversation;
394690
- if (previousConversation.model === requestedModel)
394890
+ const normalizedRequestedModel = normalizeLocalModelHandle(requestedModel, isRecord(conversation.model_settings) ? conversation.model_settings : {});
394891
+ if (previousConversation.model === normalizedRequestedModel)
394691
394892
  return conversation;
394692
- const defaults5 = this.modelSettingsDefaultsForModel(requestedModel);
394893
+ const defaults5 = this.modelSettingsDefaultsForModel(normalizedRequestedModel);
394693
394894
  if (!defaults5 || Object.keys(defaults5).length === 0)
394694
394895
  return conversation;
394695
394896
  const existingSettings = isRecord(conversation.model_settings) ? conversation.model_settings : {};
@@ -395593,9 +395794,10 @@ class LocalStore {
395593
395794
  const existing = this.conversations.get(key);
395594
395795
  if (existing && options3.forceRefresh !== true)
395595
395796
  return existing;
395797
+ const normalizedInput = normalizeStoredLocalModelRecord(input);
395596
395798
  const timing = transcriptTimingForConversationDir(conversationDir);
395597
- const requiresFullTimestampRepair = isSyntheticLocalTimestamp(input.created_at) || isSyntheticLocalTimestamp(input.updated_at) || isSyntheticLocalTimestamp(input.last_message_at);
395598
- const conversation = requiresFullTimestampRepair ? input : repairSyntheticConversationTimestamps(input, [], timing);
395799
+ const requiresFullTimestampRepair = isSyntheticLocalTimestamp(normalizedInput.created_at) || isSyntheticLocalTimestamp(normalizedInput.updated_at) || isSyntheticLocalTimestamp(normalizedInput.last_message_at);
395800
+ const conversation = requiresFullTimestampRepair ? normalizedInput : repairSyntheticConversationTimestamps(normalizedInput, [], timing);
395599
395801
  let compiledSystemPrompt;
395600
395802
  try {
395601
395803
  compiledSystemPrompt = readJsonFile2(join39(conversationDir, "system-prompt.json"));
@@ -396012,6 +396214,7 @@ class LocalStore {
396012
396214
  var DEFAULT_LOCAL_AGENT_NAME = "Letta Code", DEFAULT_LOCAL_MODEL = "local/default", LEGACY_LOCAL_CONTEXT_WINDOW_LIMIT = 128000, DEFAULT_LOCAL_CONVERSATION_ID_PREFIX = "local-conv-", DEFAULT_LOCAL_STORED_MESSAGE_ID_PREFIX = "letta-msg-", DEFAULT_LOCAL_UI_MESSAGE_ID_PREFIX = "ui-msg-", LocalBackendNotFoundError, LOCAL_TRANSCRIPT_LEGACY_SCHEMA_VERSION = 1, LOCAL_TRANSCRIPT_SCHEMA_VERSION = 2, LOCAL_TRANSCRIPT_LEGACY_MESSAGE_FORMAT = "pi-ai-message-jsonl", LOCAL_TRANSCRIPT_MESSAGE_FORMAT = "pi-session-entry-jsonl", LOCAL_TRANSCRIPT_PROVIDER_STACK = "pi-ai", LocalTranscriptMigrationRequiredError, LocalTranscriptRepairRequiredError;
396013
396215
  var init_local_store = __esm(() => {
396014
396216
  init_constants2();
396217
+ init_local_model_normalization();
396015
396218
  init_local_stream_chunks();
396016
396219
  LocalBackendNotFoundError = class LocalBackendNotFoundError extends Error {
396017
396220
  status = 404;
@@ -397462,13 +397665,13 @@ function localStopReasonChunk(stopReason) {
397462
397665
  }
397463
397666
  function effectiveAgentForConversation(agent2, conversation) {
397464
397667
  const conversationRecord = conversation;
397465
- const conversationModelSettings2 = isRecord(conversationRecord.model_settings) ? conversationRecord.model_settings : undefined;
397668
+ const conversationModelSettings = isRecord(conversationRecord.model_settings) ? conversationRecord.model_settings : undefined;
397466
397669
  return {
397467
397670
  ...agent2,
397468
397671
  ...typeof conversationRecord.model === "string" ? { model: conversationRecord.model } : {},
397469
397672
  model_settings: {
397470
397673
  ...agent2.model_settings,
397471
- ...conversationModelSettings2 ?? {},
397674
+ ...conversationModelSettings ?? {},
397472
397675
  ...typeof conversationRecord.context_window_limit === "number" ? { context_window_limit: conversationRecord.context_window_limit } : {}
397473
397676
  }
397474
397677
  };
@@ -397599,11 +397802,12 @@ class HeadlessBackend {
397599
397802
  };
397600
397803
  }
397601
397804
  async listModels() {
397805
+ const llmConfigPatch = mapModelHandleToLlmConfigPatch(this.modelHandle);
397602
397806
  return [
397603
397807
  {
397604
397808
  handle: this.modelHandle,
397605
- model: this.modelHandle,
397606
- model_endpoint_type: "openai"
397809
+ model: llmConfigPatch.model ?? this.modelHandle,
397810
+ model_endpoint_type: llmConfigPatch.model_endpoint_type ?? "openai"
397607
397811
  }
397608
397812
  ];
397609
397813
  }
@@ -397855,6 +398059,7 @@ class HeadlessBackend {
397855
398059
  }
397856
398060
  var FAKE_HEADLESS_MODEL = "dev/fake-headless";
397857
398061
  var init_fake_headless_backend = __esm(() => {
398062
+ init_model_handles();
397858
398063
  init_local_store();
397859
398064
  init_local_stream_chunks();
397860
398065
  init_constants2();
@@ -397991,6 +398196,15 @@ var init_registered_pi_provider_runtime = __esm(() => {
397991
398196
  function isUnselectedLocalModelHandle(model) {
397992
398197
  return typeof model !== "string" || model.length === 0 || model === "auto" || model === UNSELECTED_LOCAL_MODEL_HANDLE || model.startsWith("letta/");
397993
398198
  }
398199
+ function normalizeOpenAICompatibleLocalModelHandle(model) {
398200
+ if (!model?.startsWith("openai/"))
398201
+ return model;
398202
+ const nestedHandle = model.slice("openai/".length);
398203
+ const nestedProvider = resolveProviderFromModelHandle(nestedHandle);
398204
+ if (!nestedProvider)
398205
+ return model;
398206
+ return getPiProviderSpec(nestedProvider).localModelDiscovery === "openai-compatible" ? nestedHandle : model;
398207
+ }
397994
398208
  function settingString(value) {
397995
398209
  return typeof value === "string" && value.length > 0 ? value : undefined;
397996
398210
  }
@@ -398248,7 +398462,7 @@ function bedrockLocalProviderOptions(record5) {
398248
398462
  };
398249
398463
  }
398250
398464
  async function resolvePiModelForAgent(modelHandle, modelSettings = {}, options3 = {}) {
398251
- const concreteModelHandle = isUnselectedLocalModelHandle(modelHandle) ? undefined : modelHandle;
398465
+ const concreteModelHandle = normalizeOpenAICompatibleLocalModelHandle(isUnselectedLocalModelHandle(modelHandle) ? undefined : modelHandle);
398252
398466
  const provider = options3.provider ? resolvePiProvider(options3.provider) : resolvePiProviderFromAgent(concreteModelHandle, modelSettings);
398253
398467
  const registeredProvider = getRegisteredPiProvider(provider);
398254
398468
  const spec = isPiProvider(provider) ? getPiProviderSpec(provider) : undefined;
@@ -398612,6 +398826,10 @@ async function resolveAvailableLocalModelForTurn(input) {
398612
398826
  }
398613
398827
  };
398614
398828
  }
398829
+ function shouldIncludeLocalModel(provider, model) {
398830
+ const modelId = isPiProvider(provider) ? stripProviderHandlePrefix(model, provider) ?? model : model;
398831
+ return !(localProviderTypeForModelConfig(provider) === "chatgpt_oauth" && UNSUPPORTED_LOCAL_CHATGPT_OAUTH_MODELS.has(modelId));
398832
+ }
398615
398833
  async function listLocalModels(storageDir, options3 = {}) {
398616
398834
  const records = listLocalProviderRecords(storageDir);
398617
398835
  const providerNames = localProviderNamesFromRecords(records);
@@ -398620,6 +398838,8 @@ async function listLocalModels(storageDir, options3 = {}) {
398620
398838
  const registeredProviders2 = listRegisteredPiProviders();
398621
398839
  const registeredProvidersWithModels = new Set(registeredProviders2.filter((provider) => provider.config.models !== undefined).map((provider) => provider.providerName));
398622
398840
  const addModel = (provider, model, options4 = {}) => {
398841
+ if (!shouldIncludeLocalModel(provider, model))
398842
+ return;
398623
398843
  const handle = options4.handle ?? (typeof provider === "string" && !isPiProviderForLocalModelHandle(provider) ? `${provider}/${model}` : localModelHandle(provider, model));
398624
398844
  if (models3.some((entry) => entry.handle === handle))
398625
398845
  return;
@@ -398692,7 +398912,7 @@ async function listLocalModels(storageDir, options3 = {}) {
398692
398912
  }
398693
398913
  return models3;
398694
398914
  }
398695
- var LOCAL_MODEL_DISCOVERY_TIMEOUT_MS = 2000, LOCAL_MODEL_AUTODETECT_DISCOVERY_TIMEOUT_MS = 500;
398915
+ var LOCAL_MODEL_DISCOVERY_TIMEOUT_MS = 2000, LOCAL_MODEL_AUTODETECT_DISCOVERY_TIMEOUT_MS = 500, UNSUPPORTED_LOCAL_CHATGPT_OAUTH_MODELS;
398696
398916
  var init_local_model_config = __esm(() => {
398697
398917
  init_compat2();
398698
398918
  init_pi_model_factory();
@@ -398700,6 +398920,25 @@ var init_local_model_config = __esm(() => {
398700
398920
  init_pi_provider_registry();
398701
398921
  init_registered_pi_provider_runtime();
398702
398922
  init_local_provider_auth_store();
398923
+ UNSUPPORTED_LOCAL_CHATGPT_OAUTH_MODELS = new Set(["gpt-5.6-luna"]);
398924
+ });
398925
+
398926
+ // src/backend/dev/pi-output-budget.ts
398927
+ function assertViablePiOutputBudget(model, context3, requestedMaxTokens) {
398928
+ if (model.provider !== "llama-cpp")
398929
+ return;
398930
+ const requested = requestedMaxTokens ?? model.maxTokens;
398931
+ if (!Number.isFinite(requested) || requested <= 0)
398932
+ return;
398933
+ const clamped = clampMaxTokensToContext(model, context3, requested);
398934
+ const minimum3 = Math.min(requested, MIN_VIABLE_OUTPUT_TOKENS);
398935
+ if (clamped >= minimum3)
398936
+ return;
398937
+ throw new Error(`Context window of ${model.contextWindow} tokens leaves only ${clamped} output token${clamped === 1 ? "" : "s"}; at least ${minimum3} are required. Compact the conversation or increase the context window.`);
398938
+ }
398939
+ var MIN_VIABLE_OUTPUT_TOKENS = 1024;
398940
+ var init_pi_output_budget = __esm(() => {
398941
+ init_simple_options();
398703
398942
  });
398704
398943
 
398705
398944
  // src/backend/local/local-context-estimate.ts
@@ -399546,6 +399785,7 @@ class PiStreamAdapter {
399546
399785
  messageCount: context3.messages.length,
399547
399786
  contextWindow: resolved.model.contextWindow
399548
399787
  });
399788
+ assertViablePiOutputBudget(resolved.model, context3, options3.maxTokens);
399549
399789
  const result = this.runStream(resolved.model, context3, options3);
399550
399790
  let streamError;
399551
399791
  let finalMessage;
@@ -399686,6 +399926,7 @@ var init_pi_stream_adapter = __esm(() => {
399686
399926
  init_context_window_overflow();
399687
399927
  init_local_provider_errors();
399688
399928
  init_pi_model_factory();
399929
+ init_pi_output_budget();
399689
399930
  init_provider_turn_executor();
399690
399931
  LOCAL_PROVIDER_ADAPTIVE_IMAGE_ELISION_AFTER_RETRIES = LOCAL_PROVIDER_MAX_RETRIES - 1;
399691
399932
  PiProviderError = class PiProviderError extends Error {
@@ -400818,9 +401059,9 @@ var init_local_backend = __esm(() => {
400818
401059
  if (typeof conversation.context_window_limit === "number") {
400819
401060
  return conversation.context_window_limit;
400820
401061
  }
400821
- const conversationModelSettings2 = conversation.model_settings;
400822
- if (conversationModelSettings2 && typeof conversationModelSettings2 === "object" && !Array.isArray(conversationModelSettings2) && typeof conversationModelSettings2.context_window_limit === "number") {
400823
- return conversationModelSettings2.context_window_limit;
401062
+ const conversationModelSettings = conversation.model_settings;
401063
+ if (conversationModelSettings && typeof conversationModelSettings === "object" && !Array.isArray(conversationModelSettings) && typeof conversationModelSettings.context_window_limit === "number") {
401064
+ return conversationModelSettings.context_window_limit;
400824
401065
  }
400825
401066
  const agent2 = this.store.retrieveAgentRecord(agentId);
400826
401067
  return typeof agent2.model_settings.context_window_limit === "number" ? agent2.model_settings.context_window_limit : undefined;
@@ -400829,17 +401070,17 @@ var init_local_backend = __esm(() => {
400829
401070
  const agent2 = this.store.retrieveAgentRecord(agentId);
400830
401071
  const conversation = this.store.retrieveConversation(conversationId, agentId);
400831
401072
  const model = typeof conversation.model === "string" ? conversation.model : undefined;
400832
- const conversationModelSettings2 = isRecord(conversation.model_settings) ? conversation.model_settings : undefined;
400833
- if (model === undefined && conversationModelSettings2 === undefined) {
401073
+ const conversationModelSettings = isRecord(conversation.model_settings) ? conversation.model_settings : undefined;
401074
+ if (model === undefined && conversationModelSettings === undefined) {
400834
401075
  return agent2;
400835
401076
  }
400836
401077
  return {
400837
401078
  ...agent2,
400838
401079
  ...model !== undefined ? { model } : {},
400839
- ...conversationModelSettings2 !== undefined ? {
401080
+ ...conversationModelSettings !== undefined ? {
400840
401081
  model_settings: {
400841
401082
  ...agent2.model_settings,
400842
- ...conversationModelSettings2
401083
+ ...conversationModelSettings
400843
401084
  }
400844
401085
  } : {}
400845
401086
  };
@@ -401260,10 +401501,13 @@ var init_backend2 = __esm(() => {
401260
401501
  var exports_model2 = {};
401261
401502
  __export(exports_model2, {
401262
401503
  shouldPreserveContextWindowForModelSelection: () => shouldPreserveContextWindowForModelSelection2,
401504
+ resolveModelHandleFromLlmConfig: () => resolveModelHandleFromLlmConfig,
401263
401505
  resolveModelByLlmConfig: () => resolveModelByLlmConfig2,
401264
401506
  resolveModel: () => resolveModel,
401265
- normalizeModelHandleForRegistry: () => normalizeModelHandleForRegistry2,
401507
+ normalizeModelHandleForRegistry: () => normalizeModelHandleForRegistry,
401508
+ normalizeKnownModelHandle: () => normalizeKnownModelHandle,
401266
401509
  models: () => models2,
401510
+ mapModelHandleToLlmConfigPatch: () => mapModelHandleToLlmConfigPatch,
401267
401511
  isLocalModelHandle: () => isLocalModelHandle2,
401268
401512
  isLocalChatGptOAuthModelHandle: () => isLocalChatGptOAuthModelHandle2,
401269
401513
  getResumeRefreshArgs: () => getResumeRefreshArgs2,
@@ -401282,49 +401526,27 @@ __export(exports_model2, {
401282
401526
  CHATGPT_FAST_SERVICE_TIER: () => CHATGPT_FAST_SERVICE_TIER2
401283
401527
  });
401284
401528
  function isLocalModelHandle2(modelHandle) {
401285
- return LOCAL_MODEL_HANDLE_PREFIXES2.some((prefix) => modelHandle.startsWith(prefix));
401529
+ return LOCAL_MODEL_HANDLE_PREFIXES.some((prefix) => modelHandle.startsWith(prefix));
401286
401530
  }
401287
401531
  function getLocalModelLabel2(modelHandle) {
401288
- const providerPrefix = LOCAL_MODEL_HANDLE_PREFIXES2.find((prefix) => modelHandle.startsWith(prefix));
401289
- return providerPrefix ? modelHandle.slice(providerPrefix.length) : modelHandle;
401532
+ const providerPrefix2 = LOCAL_MODEL_HANDLE_PREFIXES.find((prefix) => modelHandle.startsWith(prefix));
401533
+ return providerPrefix2 ? modelHandle.slice(providerPrefix2.length) : modelHandle;
401290
401534
  }
401291
401535
  function isModelReasoningEffort2(value) {
401292
401536
  return typeof value === "string" && REASONING_EFFORT_ORDER2.includes(value);
401293
401537
  }
401294
- function normalizeModelHandleForRegistry2(modelHandle) {
401295
- if (!modelHandle)
401296
- return null;
401297
- const [provider, ...modelParts] = modelHandle.split("/");
401298
- const model = modelParts.join("/");
401299
- if (provider === CHATGPT_OAUTH_LLM_CONFIG_PROVIDER2 && model.length > 0) {
401300
- return `${OPENAI_CODEX_PROVIDER_NAME}/${model}`;
401301
- }
401302
- if (provider === LOCAL_CHATGPT_OAUTH_HANDLE_PREFIX2.slice(0, -1) && model.length > 0 && !model.endsWith("-fast")) {
401303
- return `${OPENAI_CODEX_PROVIDER_NAME}/${model}`;
401304
- }
401305
- if (provider === "lc-anthropic" && model.length > 0) {
401306
- return `anthropic/${model}`;
401307
- }
401308
- return modelHandle;
401309
- }
401310
- function modelPortion2(modelHandle) {
401311
- const slashIndex = modelHandle.indexOf("/");
401312
- if (slashIndex === -1)
401313
- return null;
401314
- return modelHandle.slice(slashIndex + 1);
401315
- }
401316
401538
  function isLocalChatGptOAuthModelHandle2(modelHandle) {
401317
- return modelHandle.startsWith(LOCAL_CHATGPT_OAUTH_HANDLE_PREFIX2);
401539
+ return modelHandle.startsWith(LOCAL_CHATGPT_OAUTH_HANDLE_PREFIX);
401318
401540
  }
401319
401541
  function getChatGptFastRegistryHandleForModelHandle2(modelHandle) {
401320
401542
  const [provider] = modelHandle.split("/");
401321
- if (provider !== LOCAL_CHATGPT_OAUTH_HANDLE_PREFIX2.slice(0, -1) && provider !== CHATGPT_OAUTH_LLM_CONFIG_PROVIDER2 && provider !== OPENAI_CODEX_PROVIDER_NAME) {
401543
+ if (provider !== LOCAL_CHATGPT_OAUTH_HANDLE_PREFIX.slice(0, -1) && provider !== CHATGPT_OAUTH_LLM_CONFIG_PROVIDER && provider !== OPENAI_CODEX_PROVIDER_NAME) {
401322
401544
  return null;
401323
401545
  }
401324
- const normalized = normalizeModelHandleForRegistry2(modelHandle);
401546
+ const normalized = normalizeModelHandleForRegistry(modelHandle);
401325
401547
  if (!normalized?.startsWith(`${OPENAI_CODEX_PROVIDER_NAME}/`))
401326
401548
  return null;
401327
- const model = modelPortion2(normalized);
401549
+ const model = modelPortionFromHandle(normalized);
401328
401550
  if (!model || model.endsWith("-fast"))
401329
401551
  return null;
401330
401552
  const fastHandle = `${OPENAI_CODEX_PROVIDER_NAME}/${model}-fast`;
@@ -401334,11 +401556,11 @@ function displayRegistryHandleForServiceTier2(modelHandle, serviceTier) {
401334
401556
  if (serviceTier === CHATGPT_FAST_SERVICE_TIER2) {
401335
401557
  return getChatGptFastRegistryHandleForModelHandle2(modelHandle) ?? modelHandle;
401336
401558
  }
401337
- return normalizeModelHandleForRegistry2(modelHandle) ?? modelHandle;
401559
+ return normalizeModelHandleForRegistry(modelHandle) ?? modelHandle;
401338
401560
  }
401339
401561
  function getReasoningTierOptionsForHandle2(modelHandle, contextWindow) {
401340
401562
  const byEffort = new Map;
401341
- const registryHandle = normalizeModelHandleForRegistry2(modelHandle) ?? modelHandle;
401563
+ const registryHandle = normalizeModelHandleForRegistry(modelHandle) ?? modelHandle;
401342
401564
  const effectiveContextWindow = contextWindow ?? (() => {
401343
401565
  const contextWindows = models2.filter((model) => model.handle === registryHandle).map((model) => model.updateArgs?.context_window).filter((value) => typeof value === "number");
401344
401566
  const uniqueContextWindows = [...new Set(contextWindows)];
@@ -401381,7 +401603,7 @@ function getModelInfo2(modelIdentifier) {
401381
401603
  const byId = models2.find((m2) => m2.id === modelIdentifier);
401382
401604
  if (byId)
401383
401605
  return byId;
401384
- const normalizedHandle = normalizeModelHandleForRegistry2(modelIdentifier);
401606
+ const normalizedHandle = normalizeModelHandleForRegistry(modelIdentifier);
401385
401607
  const byHandle = models2.find((m2) => m2.handle === normalizedHandle);
401386
401608
  if (byHandle)
401387
401609
  return byHandle;
@@ -401433,8 +401655,8 @@ function buildModelHandleFromConfig2(config3) {
401433
401655
  return config3.model ?? null;
401434
401656
  }
401435
401657
  function shouldPreserveContextWindowForModelSelection2(input) {
401436
- const currentRegistryModelHandle = normalizeModelHandleForRegistry2(input.currentModelHandle ?? buildModelHandleFromConfig2(input.currentLlmConfig));
401437
- const selectedRegistryModelHandle = normalizeModelHandleForRegistry2(input.selectedModelHandle);
401658
+ const currentRegistryModelHandle = normalizeModelHandleForRegistry(input.currentModelHandle ?? buildModelHandleFromConfig2(input.currentLlmConfig));
401659
+ const selectedRegistryModelHandle = normalizeModelHandleForRegistry(input.selectedModelHandle);
401438
401660
  if (selectedRegistryModelHandle === null || selectedRegistryModelHandle !== currentRegistryModelHandle) {
401439
401661
  return false;
401440
401662
  }
@@ -401492,23 +401714,23 @@ function getResumeRefreshArgs2(presetUpdateArgs, agent2) {
401492
401714
  }
401493
401715
  function findModelByHandle2(handle) {
401494
401716
  const pickPreferred = (candidates2) => candidates2.find((m2) => m2.isDefault) ?? candidates2.find((m2) => m2.isFeatured) ?? candidates2.find((m2) => m2.updateArgs?.reasoning_effort === "medium") ?? candidates2.find((m2) => m2.updateArgs?.reasoning_effort === "high") ?? candidates2[0] ?? null;
401495
- const registryHandle = normalizeModelHandleForRegistry2(handle) ?? handle;
401717
+ const registryHandle = normalizeModelHandleForRegistry(handle) ?? handle;
401496
401718
  const exactMatch = models2.find((m2) => m2.handle === registryHandle);
401497
401719
  if (exactMatch)
401498
401720
  return exactMatch;
401499
401721
  const [provider, ...rest3] = registryHandle.split("/");
401500
401722
  if (provider && rest3.length > 0) {
401501
- const modelPortion3 = rest3.join("/");
401723
+ const modelPortion = rest3.join("/");
401502
401724
  const providerMatches = models2.filter((m2) => {
401503
401725
  if (!m2.handle.startsWith(`${provider}/`))
401504
401726
  return false;
401505
401727
  const mModelPortion = m2.handle.slice(provider.length + 1);
401506
- return mModelPortion.includes(modelPortion3) || modelPortion3.includes(mModelPortion);
401728
+ return mModelPortion.includes(modelPortion) || modelPortion.includes(mModelPortion);
401507
401729
  });
401508
401730
  const providerMatch = pickPreferred(providerMatches);
401509
401731
  if (providerMatch)
401510
401732
  return providerMatch;
401511
- const suffixMatches = models2.filter((m2) => m2.handle.endsWith(`/${modelPortion3}`));
401733
+ const suffixMatches = models2.filter((m2) => m2.handle.endsWith(`/${modelPortion}`));
401512
401734
  const suffixMatch = pickPreferred(suffixMatches);
401513
401735
  if (suffixMatch)
401514
401736
  return suffixMatch;
@@ -401537,10 +401759,11 @@ function resolveModelByLlmConfig2(llmConfigModel) {
401537
401759
  return exactMatch.id;
401538
401760
  return null;
401539
401761
  }
401540
- var REASONING_EFFORT_ORDER2, LOCAL_REASONING_EFFORT_ORDER2, LOCAL_MODEL_HANDLE_PREFIXES2, LOCAL_CHATGPT_OAUTH_HANDLE_PREFIX2 = "openai-codex/", CHATGPT_OAUTH_LLM_CONFIG_PROVIDER2 = "chatgpt_oauth", CHATGPT_FAST_SERVICE_TIER2 = "priority", RESUME_REFRESH_FIELDS2;
401762
+ var REASONING_EFFORT_ORDER2, LOCAL_REASONING_EFFORT_ORDER2, CHATGPT_FAST_SERVICE_TIER2 = "priority", RESUME_REFRESH_FIELDS2;
401541
401763
  var init_model2 = __esm(() => {
401542
- init_openai_codex_provider();
401543
401764
  init_model_catalog();
401765
+ init_model_handles();
401766
+ init_model_handles();
401544
401767
  REASONING_EFFORT_ORDER2 = [
401545
401768
  "none",
401546
401769
  "minimal",
@@ -401556,13 +401779,6 @@ var init_model2 = __esm(() => {
401556
401779
  "medium",
401557
401780
  "high"
401558
401781
  ];
401559
- LOCAL_MODEL_HANDLE_PREFIXES2 = [
401560
- "ollama/",
401561
- "ollama-cloud/",
401562
- "lmstudio/",
401563
- "llama.cpp/",
401564
- "llama-cpp/"
401565
- ];
401566
401782
  RESUME_REFRESH_FIELDS2 = [
401567
401783
  "max_output_tokens",
401568
401784
  "parallel_tool_calls"
@@ -445436,9 +445652,9 @@ async function applySetMaxContext(params) {
445436
445652
  });
445437
445653
  const updatedConversationRecord = updatedConversation;
445438
445654
  const conversationModel = typeof updatedConversationRecord.model === "string" ? updatedConversationRecord.model : typeof conversationRecord.model === "string" ? conversationRecord.model : null;
445439
- const conversationModelSettings2 = nonEmptyModelSettings(updatedConversationRecord.model_settings) ?? nonEmptyModelSettings(conversationRecord.model_settings);
445655
+ const conversationModelSettings = nonEmptyModelSettings(updatedConversationRecord.model_settings) ?? nonEmptyModelSettings(conversationRecord.model_settings);
445440
445656
  const agentModelHandle = typeof agent2.model === "string" && agent2.model.length > 0 ? agent2.model : buildModelHandleFromConfig3(agent2.llm_config);
445441
- const inheritedModelSettings = conversationModelSettings2 ?? (conversationModel === null || conversationModel === agentModelHandle ? agent2.model_settings ?? null : null);
445657
+ const inheritedModelSettings = conversationModelSettings ?? (conversationModel === null || conversationModel === agentModelHandle ? agent2.model_settings ?? null : null);
445442
445658
  return {
445443
445659
  contextWindow,
445444
445660
  reset,
@@ -459331,7 +459547,7 @@ function buildModelHandleFromConfig4(config3) {
459331
459547
  }
459332
459548
  return config3.model ?? null;
459333
459549
  }
459334
- function providerTypeFromModelSettings2(modelSettings) {
459550
+ function providerTypeFromModelSettings3(modelSettings) {
459335
459551
  const providerType = modelSettings?.provider_type;
459336
459552
  return typeof providerType === "string" ? providerType : null;
459337
459553
  }
@@ -459508,7 +459724,7 @@ async function applyModelUpdateForRuntime(params) {
459508
459724
  agentId,
459509
459725
  conversationId,
459510
459726
  overrideModel: model.handle,
459511
- overrideProviderType: providerTypeFromModelSettings2(modelSettings) ?? inferProviderTypeFromRegistryHandle(model.handle) ?? null,
459727
+ overrideProviderType: providerTypeFromModelSettings3(modelSettings) ?? inferProviderTypeFromRegistryHandle(model.handle) ?? null,
459512
459728
  modEvents: ensureListenerModAdapter(listener).events
459513
459729
  });
459514
459730
  nextToolset = preparedToolContext.toolset;
@@ -477197,7 +477413,7 @@ var init_build7 = __esm(async () => {
477197
477413
 
477198
477414
  // src/agent/conversation-model-carryover.ts
477199
477415
  function normalizeConversationModelCarryoverHandle(rawModelHandle) {
477200
- return normalizeModelHandleForRegistry(rawModelHandle) ?? rawModelHandle;
477416
+ return normalizeKnownModelHandle(rawModelHandle);
477201
477417
  }
477202
477418
  function buildConversationModelCarryoverUpdate(params) {
477203
477419
  const { rawModelHandle, currentLlmConfig } = params;
@@ -477235,6 +477451,7 @@ function buildConversationModelCarryoverUpdate(params) {
477235
477451
  }
477236
477452
  var init_conversation_model_carryover = __esm(() => {
477237
477453
  init_model();
477454
+ init_model_handles();
477238
477455
  });
477239
477456
 
477240
477457
  // src/agent/reconcile-existing-agent-state.ts
@@ -522548,13 +522765,8 @@ function inferReasoningEffortFromModelPreset(modelId, modelHandle) {
522548
522765
  }
522549
522766
  return null;
522550
522767
  }
522551
- function buildModelHandleFromLlmConfig3(llmConfig) {
522552
- if (!llmConfig)
522553
- return null;
522554
- if (llmConfig.model_endpoint_type && llmConfig.model) {
522555
- return `${llmConfig.model_endpoint_type}/${llmConfig.model}`;
522556
- }
522557
- return llmConfig.model ?? null;
522768
+ function buildModelHandleFromLlmConfig(llmConfig) {
522769
+ return resolveModelHandleFromLlmConfig(llmConfig);
522558
522770
  }
522559
522771
  function getPreferredAgentModelHandle2(agent2) {
522560
522772
  if (!agent2)
@@ -522562,9 +522774,9 @@ function getPreferredAgentModelHandle2(agent2) {
522562
522774
  if (typeof agent2.model === "string" && agent2.model.length > 0) {
522563
522775
  return agent2.model;
522564
522776
  }
522565
- return buildModelHandleFromLlmConfig3(agent2.llm_config);
522777
+ return buildModelHandleFromLlmConfig(agent2.llm_config);
522566
522778
  }
522567
- function providerTypeFromModelSettings3(modelSettings) {
522779
+ function providerTypeFromModelSettings4(modelSettings) {
522568
522780
  if (typeof modelSettings !== "object" || modelSettings === null || !("provider_type" in modelSettings)) {
522569
522781
  return null;
522570
522782
  }
@@ -522576,35 +522788,7 @@ function providerTypeFromUpdateArgs(updateArgs) {
522576
522788
  return typeof providerType === "string" && providerType.length > 0 ? providerType : null;
522577
522789
  }
522578
522790
  function mapHandleToLlmConfigPatch(modelHandle, providerType) {
522579
- const [provider, ...modelParts] = modelHandle.split("/");
522580
- const modelName = modelParts.join("/");
522581
- if (!provider || !modelName) {
522582
- return {
522583
- model: modelHandle
522584
- };
522585
- }
522586
- const knownEndpointTypes = new Set([
522587
- "anthropic",
522588
- "bedrock",
522589
- "chatgpt_oauth",
522590
- "google_ai",
522591
- "google_vertex",
522592
- "minimax",
522593
- "moonshot",
522594
- "moonshot_coding",
522595
- "openai",
522596
- "openrouter",
522597
- "zai",
522598
- "zai_coding"
522599
- ]);
522600
- const endpointType = typeof providerType === "string" && providerType.length > 0 ? providerType : provider === OPENAI_CODEX_PROVIDER_NAME || provider === "openai-codex" ? "chatgpt_oauth" : knownEndpointTypes.has(provider) ? provider : null;
522601
- if (!endpointType) {
522602
- return { model: modelHandle };
522603
- }
522604
- return {
522605
- model: modelName,
522606
- model_endpoint_type: endpointType
522607
- };
522791
+ return mapModelHandleToLlmConfigPatch(modelHandle, providerType);
522608
522792
  }
522609
522793
  function getErrorHintForStopReason(stopReason, currentModelId, modelEndpointType) {
522610
522794
  if (stopReason !== "llm_api_error") {
@@ -522625,7 +522809,7 @@ function getErrorHintForStopReason(stopReason, currentModelId, modelEndpointType
522625
522809
  }
522626
522810
  var init_model_config = __esm(() => {
522627
522811
  init_model();
522628
- init_openai_codex_provider();
522812
+ init_model_handles();
522629
522813
  init_constants7();
522630
522814
  });
522631
522815
 
@@ -523722,11 +523906,11 @@ function useConfigurationHandlers(ctx) {
523722
523906
  const {
523723
523907
  getChatGptFastRegistryHandleForModelHandle: getChatGptFastRegistryHandleForModelHandle3,
523724
523908
  getReasoningTierOptionsForHandle: getReasoningTierOptionsForHandle3,
523725
- normalizeModelHandleForRegistry: normalizeModelHandleForRegistry3,
523909
+ normalizeModelHandleForRegistry: normalizeModelHandleForRegistry2,
523726
523910
  models: models3
523727
523911
  } = await Promise.resolve().then(() => (init_model(), exports_model));
523728
523912
  const pickPreferredModelForHandle = (handle2) => {
523729
- const registryHandle2 = normalizeModelHandleForRegistry3(handle2) ?? handle2;
523913
+ const registryHandle2 = normalizeModelHandleForRegistry2(handle2) ?? handle2;
523730
523914
  const candidates2 = models3.filter((m4) => m4.handle === registryHandle2);
523731
523915
  return candidates2.find((m4) => m4.isDefault) ?? candidates2.find((m4) => m4.isFeatured) ?? candidates2.find((m4) => m4.updateArgs?.reasoning_effort === "medium") ?? candidates2.find((m4) => m4.updateArgs?.reasoning_effort === "high") ?? candidates2[0] ?? null;
523732
523916
  };
@@ -523771,7 +523955,7 @@ function useConfigurationHandlers(ctx) {
523771
523955
  ...handleMatch,
523772
523956
  id: modelId,
523773
523957
  handle: modelId,
523774
- registryHandle: normalizeModelHandleForRegistry3(registryCandidate) ?? registryCandidate,
523958
+ registryHandle: normalizeModelHandleForRegistry2(registryCandidate) ?? registryCandidate,
523775
523959
  updateArgs: Object.keys(updateArgs).length > 0 ? updateArgs : undefined
523776
523960
  };
523777
523961
  }
@@ -523810,7 +523994,7 @@ function useConfigurationHandlers(ctx) {
523810
523994
  }
523811
523995
  const model2 = selectedModel;
523812
523996
  const modelHandle = model2.handle ?? model2.id;
523813
- const registryHandle = model2.registryHandle ?? normalizeModelHandleForRegistry3(modelHandle) ?? modelHandle;
523997
+ const registryHandle = model2.registryHandle ?? normalizeModelHandleForRegistry2(modelHandle) ?? modelHandle;
523814
523998
  const modelUpdateArgs = model2.updateArgs;
523815
523999
  const rawReasoningEffort = modelUpdateArgs?.reasoning_effort;
523816
524000
  const usesDistinctXHighLabel = /Fable 5|Opus 4\.[78]|GPT-5\.6/.test(model2.label);
@@ -523885,7 +524069,7 @@ function useConfigurationHandlers(ctx) {
523885
524069
  phase: "running"
523886
524070
  });
523887
524071
  const isDefaultConversation = conversationIdRef.current === "default";
523888
- let conversationModelSettings2;
524072
+ let conversationModelSettings;
523889
524073
  let conversationContextWindowLimit;
523890
524074
  let updatedAgent = null;
523891
524075
  if (isDefaultConversation) {
@@ -523893,17 +524077,17 @@ function useConfigurationHandlers(ctx) {
523893
524077
  updatedAgent = await updateAgentLLMConfig3(agentIdRef.current, modelHandle, modelUpdateArgsForRequest, {
523894
524078
  avoidOverwritingExistingContextWindow: shouldPreserveContextWindow
523895
524079
  });
523896
- conversationModelSettings2 = updatedAgent?.model_settings;
524080
+ conversationModelSettings = updatedAgent?.model_settings;
523897
524081
  } else {
523898
524082
  const { updateConversationLLMConfig: updateConversationLLMConfig2 } = await Promise.resolve().then(() => (init_modify(), exports_modify));
523899
524083
  const updatedConversation = await updateConversationLLMConfig2(conversationIdRef.current, modelHandle, modelUpdateArgsForRequest, {
523900
524084
  avoidOverwritingExistingContextWindow: shouldPreserveContextWindow
523901
524085
  });
523902
- conversationModelSettings2 = updatedConversation.model_settings;
524086
+ conversationModelSettings = updatedConversation.model_settings;
523903
524087
  conversationContextWindowLimit = updatedConversation.context_window_limit;
523904
524088
  }
523905
524089
  const rawEffort = modelUpdateArgs?.reasoning_effort;
523906
- const resolvedReasoningEffort = typeof rawEffort === "string" ? rawEffort : deriveReasoningEffort(conversationModelSettings2, llmConfigRef.current) ?? null;
524090
+ const resolvedReasoningEffort = typeof rawEffort === "string" ? rawEffort : deriveReasoningEffort(conversationModelSettings, llmConfigRef.current) ?? null;
523907
524091
  if (isDefaultConversation) {
523908
524092
  setHasConversationModelOverride(false);
523909
524093
  setConversationOverrideModelSettings(null);
@@ -523913,12 +524097,12 @@ function useConfigurationHandlers(ctx) {
523913
524097
  }
523914
524098
  } else {
523915
524099
  setHasConversationModelOverride(true);
523916
- setConversationOverrideModelSettings(conversationModelSettings2 ?? null);
524100
+ setConversationOverrideModelSettings(conversationModelSettings ?? null);
523917
524101
  }
523918
524102
  const presetContextWindow = modelUpdateArgsForRequest?.context_window;
523919
524103
  const preservedContextWindow = llmConfigRef.current?.context_window;
523920
524104
  const resolvedContextWindow = typeof conversationContextWindowLimit === "number" ? conversationContextWindowLimit : shouldPreserveContextWindow && typeof preservedContextWindow === "number" ? preservedContextWindow : typeof presetContextWindow === "number" ? presetContextWindow : undefined;
523921
- const resolvedProviderType = providerTypeFromModelSettings3(conversationModelSettings2) ?? providerTypeFromUpdateArgs(modelUpdateArgsForRequest) ?? providerTypeFromUpdateArgs(modelUpdateArgs);
524105
+ const resolvedProviderType = providerTypeFromModelSettings4(conversationModelSettings) ?? providerTypeFromUpdateArgs(modelUpdateArgsForRequest) ?? providerTypeFromUpdateArgs(modelUpdateArgs);
523922
524106
  if (!isDefaultConversation) {
523923
524107
  setConversationOverrideContextWindowLimit(typeof resolvedContextWindow === "number" ? resolvedContextWindow : null);
523924
524108
  }
@@ -524312,7 +524496,7 @@ ${guidance}`);
524312
524496
  if (!modelHandle) {
524313
524497
  throw new Error("Could not determine current model for auto toolset");
524314
524498
  }
524315
- const providerType = providerTypeFromModelSettings3(agentState?.model_settings) ?? llmConfig?.model_endpoint_type ?? null;
524499
+ const providerType = providerTypeFromModelSettings4(agentState?.model_settings) ?? llmConfig?.model_endpoint_type ?? null;
524316
524500
  const derivedToolset = await switchToolsetForModel2(modelHandle, agentId, providerType);
524317
524501
  settingsManager.setToolsetPreference(agentId, "auto");
524318
524502
  setCurrentToolsetPreference("auto");
@@ -527222,7 +527406,7 @@ function resolveReasoningCycleTierLookupHandle(modelHandle, modelSettings) {
527222
527406
  if (isLocalModelHandle(modelHandle)) {
527223
527407
  return modelHandle;
527224
527408
  }
527225
- const providerType = providerTypeFromModelSettings3(modelSettings);
527409
+ const providerType = providerTypeFromModelSettings4(modelSettings);
527226
527410
  const modelName = modelNameFromHandle(modelHandle);
527227
527411
  if (!providerType || !modelName) {
527228
527412
  return normalizedHandle ?? modelHandle;
@@ -527290,7 +527474,7 @@ function useReasoningCycle(ctx) {
527290
527474
  const cmd = commandRunner.start("/reasoning", "Setting reasoning...");
527291
527475
  try {
527292
527476
  const isDefaultConversation = conversationIdRef.current === "default";
527293
- let conversationModelSettings2;
527477
+ let conversationModelSettings;
527294
527478
  let conversationContextWindowLimit;
527295
527479
  let updatedAgent = null;
527296
527480
  if (isDefaultConversation) {
@@ -527307,10 +527491,10 @@ function useReasoningCycle(ctx) {
527307
527491
  ...desired.providerType ? { provider_type: desired.providerType } : {},
527308
527492
  ...desired.serviceTier !== undefined ? { service_tier: desired.serviceTier } : {}
527309
527493
  }, { avoidOverwritingExistingContextWindow: true });
527310
- conversationModelSettings2 = updatedConversation.model_settings;
527494
+ conversationModelSettings = updatedConversation.model_settings;
527311
527495
  conversationContextWindowLimit = updatedConversation.context_window_limit;
527312
527496
  }
527313
- const resolvedReasoningEffort = deriveReasoningEffort(isDefaultConversation ? updatedAgent?.model_settings ?? null : conversationModelSettings2, llmConfigRef.current) ?? desired.effort;
527497
+ const resolvedReasoningEffort = deriveReasoningEffort(isDefaultConversation ? updatedAgent?.model_settings ?? null : conversationModelSettings, llmConfigRef.current) ?? desired.effort;
527314
527498
  const resolvedConversationContextWindowLimit = conversationContextWindowLimit === undefined ? typeof llmConfigRef.current?.context_window === "number" ? llmConfigRef.current.context_window : null : conversationContextWindowLimit;
527315
527499
  if (isDefaultConversation) {
527316
527500
  setHasConversationModelOverride(false);
@@ -527321,12 +527505,12 @@ function useReasoningCycle(ctx) {
527321
527505
  }
527322
527506
  } else {
527323
527507
  setHasConversationModelOverride(true);
527324
- setConversationOverrideModelSettings(conversationModelSettings2 ?? null);
527508
+ setConversationOverrideModelSettings(conversationModelSettings ?? null);
527325
527509
  setConversationOverrideContextWindowLimit(resolvedConversationContextWindowLimit);
527326
527510
  }
527327
527511
  setLlmConfig({
527328
527512
  ...updatedAgent?.llm_config ?? llmConfigRef.current ?? {},
527329
- ...mapHandleToLlmConfigPatch(desired.modelHandle, providerTypeFromModelSettings3(isDefaultConversation ? updatedAgent?.model_settings ?? null : conversationModelSettings2)),
527513
+ ...mapHandleToLlmConfigPatch(desired.modelHandle, providerTypeFromModelSettings4(isDefaultConversation ? updatedAgent?.model_settings ?? null : conversationModelSettings)),
527330
527514
  reasoning_effort: resolvedReasoningEffort,
527331
527515
  ...typeof resolvedConversationContextWindowLimit === "number" ? { context_window: resolvedConversationContextWindowLimit } : {}
527332
527516
  });
@@ -527389,7 +527573,7 @@ function useReasoningCycle(ctx) {
527389
527573
  return;
527390
527574
  const current = llmConfigRef.current;
527391
527575
  const modelSettingsForEffort = hasConversationModelOverrideRef.current ? conversationOverrideModelSettingsRef.current : agentStateRef.current?.model_settings;
527392
- const providerType = providerTypeFromModelSettings3(modelSettingsForEffort);
527576
+ const providerType = providerTypeFromModelSettings4(modelSettingsForEffort);
527393
527577
  const modelHandle = resolveReasoningCycleModelHandle(current, hasConversationModelOverrideRef.current ? null : agentStateRef.current?.model ?? null, currentModelHandleRef.current);
527394
527578
  if (!modelHandle)
527395
527579
  return;
@@ -536093,7 +536277,7 @@ function App2({
536093
536277
  if (persistedToolsetPreference === "auto") {
536094
536278
  if (agentModelHandle) {
536095
536279
  const { switchToolsetForModel: switchToolsetForModel2 } = await init_toolset().then(() => exports_toolset);
536096
- const providerType = providerTypeFromModelSettings3(agent2.model_settings) ?? agent2.llm_config?.model_endpoint_type ?? null;
536280
+ const providerType = providerTypeFromModelSettings4(agent2.model_settings) ?? agent2.llm_config?.model_endpoint_type ?? null;
536097
536281
  const derivedToolset = await switchToolsetForModel2(agentModelHandle, agentId, providerType);
536098
536282
  setCurrentToolset(derivedToolset);
536099
536283
  } else {
@@ -536194,7 +536378,7 @@ function App2({
536194
536378
  setConversationOverrideContextWindowLimit(null);
536195
536379
  setLlmConfig(agentState.llm_config);
536196
536380
  setCurrentModelHandle(agentModelHandle ?? null);
536197
- const currentHandle = buildModelHandleFromLlmConfig3(llmConfigRef.current);
536381
+ const currentHandle = buildModelHandleFromLlmConfig(llmConfigRef.current);
536198
536382
  if (agentModelHandle && agentModelHandle === currentHandle) {
536199
536383
  return;
536200
536384
  }
@@ -536217,9 +536401,9 @@ function App2({
536217
536401
  if (cancelled)
536218
536402
  return;
536219
536403
  const conversationModel = conversation.model;
536220
- const conversationModelSettings2 = conversation.model_settings;
536404
+ const conversationModelSettings = conversation.model_settings;
536221
536405
  const conversationContextWindowLimit = conversation.context_window_limit;
536222
- const hasOverride = conversationModel !== undefined && conversationModel !== null ? true : conversationModelSettings2 !== undefined && conversationModelSettings2 !== null ? true : conversationContextWindowLimit !== undefined && conversationContextWindowLimit !== null;
536406
+ const hasOverride = conversationModel !== undefined && conversationModel !== null ? true : conversationModelSettings !== undefined && conversationModelSettings !== null ? true : conversationContextWindowLimit !== undefined && conversationContextWindowLimit !== null;
536223
536407
  if (!hasOverride) {
536224
536408
  applyAgentModelLocally();
536225
536409
  return;
@@ -536230,8 +536414,8 @@ function App2({
536230
536414
  applyAgentModelLocally();
536231
536415
  return;
536232
536416
  }
536233
- const hasConversationModelSettings = conversationModelSettings2 !== undefined && conversationModelSettings2 !== null && Object.keys(conversationModelSettings2).length > 0;
536234
- const resolvedConversationModelSettings = hasConversationModelSettings ? conversationModelSettings2 : conversationModel === undefined || conversationModel === null || conversationModel === agentModelHandle ? agentState.model_settings ?? null : null;
536417
+ const hasConversationModelSettings = conversationModelSettings !== undefined && conversationModelSettings !== null && Object.keys(conversationModelSettings).length > 0;
536418
+ const resolvedConversationModelSettings = hasConversationModelSettings ? conversationModelSettings : conversationModel === undefined || conversationModel === null || conversationModel === agentModelHandle ? agentState.model_settings ?? null : null;
536235
536419
  const reasoningEffort = deriveReasoningEffort(resolvedConversationModelSettings, agentState.llm_config);
536236
536420
  const conversationServiceTier = resolvedConversationModelSettings?.service_tier === CHATGPT_FAST_SERVICE_TIER && getChatGptFastRegistryHandleForModelHandle(effectiveModelHandle) ? CHATGPT_FAST_SERVICE_TIER : null;
536237
536421
  const modelInfo = getModelInfoForLlmConfig(effectiveModelHandle, {
@@ -536249,7 +536433,7 @@ function App2({
536249
536433
  setCurrentModelId(modelInfo?.id ?? effectiveModelHandle);
536250
536434
  setLlmConfig({
536251
536435
  ...agentState.llm_config,
536252
- ...mapHandleToLlmConfigPatch(effectiveModelHandle, providerTypeFromModelSettings3(resolvedConversationModelSettings)),
536436
+ ...mapHandleToLlmConfigPatch(effectiveModelHandle, providerTypeFromModelSettings4(resolvedConversationModelSettings)),
536253
536437
  ...typeof reasoningEffort === "string" ? { reasoning_effort: reasoningEffort } : {},
536254
536438
  ...typeof resolvedConversationContextWindowLimit === "number" ? { context_window: resolvedConversationContextWindowLimit } : {}
536255
536439
  });
@@ -536272,11 +536456,10 @@ function App2({
536272
536456
  setHasConversationModelOverride
536273
536457
  ]);
536274
536458
  const maybeCarryOverActiveConversationModel = import_react122.useCallback(async (targetConversationId) => {
536275
- if (!hasConversationModelOverrideRef.current) {
536459
+ if (!hasConversationModelOverrideRef.current)
536276
536460
  return;
536277
- }
536278
536461
  const currentLlmConfig = llmConfigRef.current;
536279
- const rawModelHandle = buildModelHandleFromLlmConfig3(currentLlmConfig);
536462
+ const rawModelHandle = currentModelHandleRef.current ?? buildModelHandleFromLlmConfig(currentLlmConfig);
536280
536463
  if (!rawModelHandle) {
536281
536464
  return;
536282
536465
  }
@@ -552617,6 +552800,7 @@ ${after}`;
552617
552800
 
552618
552801
  // src/tools/toolset.ts
552619
552802
  init_model();
552803
+ init_model_handles();
552620
552804
  init_backend2();
552621
552805
  init_client2();
552622
552806
  init_plugin_registry();
@@ -554458,4 +554642,4 @@ Error during initialization: ${message}`);
554458
554642
  }
554459
554643
  main2();
554460
554644
 
554461
- //# debugId=A09A03B6B9AA731C64756E2164756E21
554645
+ //# debugId=FBD3E3DABCE593F564756E2164756E21