@letta-ai/letta-code 0.28.1 → 0.28.3

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.3",
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();
@@ -393568,7 +393725,8 @@ function projectLocalMessageToStoredMessages(message, fallbackAgentId, fallbackC
393568
393725
  conversation_id: conversationId,
393569
393726
  message_type: "user_message",
393570
393727
  role: "user",
393571
- content: userContentToStoredContent(message.content)
393728
+ content: userContentToStoredContent(message.content),
393729
+ ...message.otid ? { otid: message.otid } : {}
393572
393730
  }
393573
393731
  ];
393574
393732
  }
@@ -393755,6 +393913,67 @@ function mergeSnapshotContentWithExistingToolCalls(snapshotContent, existingCont
393755
393913
  }
393756
393914
  var LOCAL_REPAIRED_TOOL_RESULT_TEXT_MAX_CHARS = 40000;
393757
393915
 
393916
+ // src/backend/local/local-model-normalization.ts
393917
+ function supportedModelSettingsFromBody(bodyRecord) {
393918
+ const modelSettings = isRecord(bodyRecord.model_settings) ? { ...bodyRecord.model_settings } : {};
393919
+ if (typeof bodyRecord.context_window_limit === "number") {
393920
+ modelSettings.context_window_limit = bodyRecord.context_window_limit;
393921
+ }
393922
+ if (typeof bodyRecord.parallel_tool_calls === "boolean") {
393923
+ modelSettings.parallel_tool_calls = bodyRecord.parallel_tool_calls;
393924
+ }
393925
+ if (typeof bodyRecord.max_tokens === "number" || bodyRecord.max_tokens === null) {
393926
+ modelSettings.max_tokens = bodyRecord.max_tokens;
393927
+ }
393928
+ return modelSettings;
393929
+ }
393930
+ function providerTypeFromModelSettings2(modelSettings) {
393931
+ const providerType = modelSettings?.provider_type;
393932
+ return typeof providerType === "string" && providerType.length > 0 ? providerType : null;
393933
+ }
393934
+ function normalizeLocalModelHandle(model, modelSettings, legacyLlmConfig) {
393935
+ const providerType = providerTypeFromModelSettings2(modelSettings);
393936
+ const legacyEndpointType = legacyLlmConfig?.model_endpoint_type;
393937
+ return resolveModelHandleFromLlmConfig({
393938
+ model,
393939
+ model_endpoint_type: providerType ?? (typeof legacyEndpointType === "string" ? legacyEndpointType : null)
393940
+ }) ?? model;
393941
+ }
393942
+ function modelHandleFromLegacyLlmConfig(legacyLlmConfig) {
393943
+ const model = legacyLlmConfig.model;
393944
+ if (typeof model !== "string")
393945
+ return null;
393946
+ const modelEndpointType = legacyLlmConfig.model_endpoint_type;
393947
+ return resolveModelHandleFromLlmConfig({
393948
+ model,
393949
+ model_endpoint_type: typeof modelEndpointType === "string" ? modelEndpointType : null
393950
+ });
393951
+ }
393952
+ function supportedConversationModelSettingsFromBody(bodyRecord) {
393953
+ const rawSettings = bodyRecord.model_settings;
393954
+ const modelSettings = rawSettings === null ? null : isRecord(rawSettings) ? { ...rawSettings } : undefined;
393955
+ if (modelSettings === null)
393956
+ return null;
393957
+ const next = modelSettings ?? {};
393958
+ if (typeof bodyRecord.max_tokens === "number" || bodyRecord.max_tokens === null) {
393959
+ next.max_tokens = bodyRecord.max_tokens;
393960
+ }
393961
+ return Object.keys(next).length > 0 ? next : modelSettings;
393962
+ }
393963
+ function normalizeStoredLocalModelRecord(record5) {
393964
+ if (typeof record5.model !== "string")
393965
+ return record5;
393966
+ const modelSettings = isRecord(record5.model_settings) ? record5.model_settings : {};
393967
+ const normalizedModel = normalizeLocalModelHandle(record5.model, modelSettings);
393968
+ return normalizedModel === record5.model ? record5 : { ...record5, model: normalizedModel };
393969
+ }
393970
+ function localLlmConfigModelPatch(model, modelSettings) {
393971
+ return mapModelHandleToLlmConfigPatch(model, providerTypeFromModelSettings2(modelSettings));
393972
+ }
393973
+ var init_local_model_normalization = __esm(() => {
393974
+ init_model_handles();
393975
+ });
393976
+
393758
393977
  // src/backend/local/local-stream-chunks.ts
393759
393978
  function attachLocalMessage(target2, message) {
393760
393979
  Object.defineProperty(target2, LOCAL_MESSAGE, {
@@ -393829,19 +394048,6 @@ function optionalString(value) {
393829
394048
  function optionalStringOrNull(value) {
393830
394049
  return typeof value === "string" || value === null ? value : undefined;
393831
394050
  }
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
394051
  function createDefaultAgentRecord(agentId, defaultAgentName, defaultAgentModel) {
393846
394052
  return {
393847
394053
  id: agentId,
@@ -393857,14 +394063,16 @@ function createLocalAgentRecord(body, defaultAgentName, defaultAgentModel) {
393857
394063
  const bodyRecord = body;
393858
394064
  const tags = isStringArray2(bodyRecord.tags) ? bodyRecord.tags : [];
393859
394065
  const hidden = normalizeAgentHiddenFlag(bodyRecord.hidden, tags);
394066
+ const modelSettings = supportedModelSettingsFromBody(bodyRecord);
394067
+ const requestedModel = optionalString(bodyRecord.model) ?? defaultAgentModel;
393860
394068
  return {
393861
394069
  id: `agent-local-${randomUUID18()}`,
393862
394070
  name: optionalString(bodyRecord.name) ?? defaultAgentName,
393863
394071
  description: optionalStringOrNull(bodyRecord.description) ?? null,
393864
394072
  system: optionalString(bodyRecord.system) ?? "",
393865
394073
  tags,
393866
- model: optionalString(bodyRecord.model) ?? defaultAgentModel,
393867
- model_settings: supportedModelSettingsFromBody(bodyRecord),
394074
+ model: normalizeLocalModelHandle(requestedModel, modelSettings),
394075
+ model_settings: modelSettings,
393868
394076
  ...hidden !== undefined ? { hidden } : {}
393869
394077
  };
393870
394078
  }
@@ -393891,19 +394099,6 @@ function optionalRecordOrNull(value) {
393891
394099
  return null;
393892
394100
  return isRecord(value) ? { ...value } : undefined;
393893
394101
  }
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
394102
  function createLocalConversationRecord(conversationId, agentId, _sequence, body = {}) {
393908
394103
  const bodyRecord = body;
393909
394104
  const now = currentIsoTimestamp();
@@ -393918,7 +394113,9 @@ function createLocalConversationRecord(conversationId, agentId, _sequence, body
393918
394113
  last_message_at: null,
393919
394114
  summary: optionalStringOrNull(bodyRecord.summary) ?? null,
393920
394115
  in_context_message_ids: [],
393921
- ...typeof bodyRecord.model === "string" || bodyRecord.model === null ? { model: bodyRecord.model } : {},
394116
+ ...typeof bodyRecord.model === "string" || bodyRecord.model === null ? {
394117
+ model: bodyRecord.model === null ? null : normalizeLocalModelHandle(bodyRecord.model, modelSettings ?? {})
394118
+ } : {},
393922
394119
  ...modelSettings !== undefined ? { model_settings: modelSettings } : {},
393923
394120
  ...typeof bodyRecord.context_window_limit === "number" ? { context_window_limit: bodyRecord.context_window_limit } : {},
393924
394121
  ...typeof bodyRecord.hidden === "boolean" ? { hidden: bodyRecord.hidden } : {}
@@ -393930,6 +394127,7 @@ function updateLocalConversationRecord(current, body, updatedAt) {
393930
394127
  ...current,
393931
394128
  updated_at: updatedAt
393932
394129
  };
394130
+ const modelSettings = supportedConversationModelSettingsFromBody(bodyRecord);
393933
394131
  if (typeof bodyRecord.archived === "boolean") {
393934
394132
  next.archived = bodyRecord.archived;
393935
394133
  next.archived_at = bodyRecord.archived ? current.archived_at ?? updatedAt : null;
@@ -393942,9 +394140,8 @@ function updateLocalConversationRecord(current, body, updatedAt) {
393942
394140
  next.last_message_at = bodyRecord.last_message_at;
393943
394141
  }
393944
394142
  if (typeof bodyRecord.model === "string" || bodyRecord.model === null) {
393945
- next.model = bodyRecord.model;
394143
+ next.model = bodyRecord.model === null ? null : normalizeLocalModelHandle(bodyRecord.model, modelSettings ?? {});
393946
394144
  }
393947
- const modelSettings = supportedConversationModelSettingsFromBody(bodyRecord);
393948
394145
  if (modelSettings !== undefined) {
393949
394146
  next.model_settings = modelSettings;
393950
394147
  }
@@ -393973,13 +394170,16 @@ function normalizeAgentRecord(value, defaultAgentModel) {
393973
394170
  const compactionSettings = optionalRecordOrNull(value.compaction_settings);
393974
394171
  const tags = isStringArray2(value.tags) ? value.tags : [];
393975
394172
  const hidden = normalizeAgentHiddenFlag(value.hidden, tags);
394173
+ const storedModel = optionalString(value.model);
394174
+ const legacyModel = modelHandleFromLegacyLlmConfig(legacyLlmConfig);
394175
+ const model = storedModel ? normalizeLocalModelHandle(storedModel, modelSettings, legacyLlmConfig) : legacyModel ?? defaultAgentModel;
393976
394176
  return {
393977
394177
  id: value.id,
393978
394178
  name: optionalString(value.name) ?? "Letta Code",
393979
394179
  description: optionalStringOrNull(value.description) ?? null,
393980
394180
  system: optionalString(value.system) ?? "",
393981
394181
  tags,
393982
- model: optionalString(value.model) ?? optionalString(legacyLlmConfig.model) ?? defaultAgentModel,
394182
+ model,
393983
394183
  model_settings: modelSettings,
393984
394184
  ...hidden !== undefined ? { hidden } : {},
393985
394185
  ...compactionSettings !== undefined ? { compaction_settings: compactionSettings } : {}
@@ -393990,6 +394190,7 @@ function projectLocalAgentState(record5, messageIds = [], inContextMessageIds =
393990
394190
  const nestedReasoning = isRecord(record5.model_settings.reasoning) ? record5.model_settings.reasoning : undefined;
393991
394191
  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
394192
  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;
394193
+ const llmConfigModelPatch = localLlmConfigModelPatch(record5.model, record5.model_settings);
393993
394194
  return {
393994
394195
  id: record5.id,
393995
394196
  name: record5.name,
@@ -394005,8 +394206,7 @@ function projectLocalAgentState(record5, messageIds = [], inContextMessageIds =
394005
394206
  in_context_message_ids: inContextMessageIds,
394006
394207
  ...lastRunCompletion ? { last_run_completion: lastRunCompletion } : {},
394007
394208
  llm_config: {
394008
- model: record5.model,
394009
- model_endpoint_type: "openai",
394209
+ ...llmConfigModelPatch,
394010
394210
  model_endpoint: "https://example.invalid/v1",
394011
394211
  context_window: typeof record5.model_settings.context_window_limit === "number" ? record5.model_settings.context_window_limit : 128000,
394012
394212
  ...reasoningEffort && { reasoning_effort: reasoningEffort },
@@ -394521,12 +394721,13 @@ class LocalStore {
394521
394721
  const nextSystem = typeof bodyRecord.system === "string" ? bodyRecord.system : undefined;
394522
394722
  const systemChanged = nextSystem !== undefined && nextSystem !== existingRecord.system;
394523
394723
  const requestedModel = bodyRecord.model;
394524
- const nextModel = typeof requestedModel === "string" && !shouldUseDefaultLocalModel(requestedModel) ? requestedModel : typeof requestedModel === "string" && this.defaultAgentModel ? this.defaultAgentModel : undefined;
394724
+ const requestedModelSettings = supportedModelSettingsFromBody(bodyRecord);
394725
+ const nextModel = typeof requestedModel === "string" && !shouldUseDefaultLocalModel(requestedModel) ? normalizeLocalModelHandle(requestedModel, requestedModelSettings) : typeof requestedModel === "string" && this.defaultAgentModel ? this.defaultAgentModel : undefined;
394525
394726
  const modelChanged = nextModel !== undefined && nextModel !== existingRecord.model;
394526
394727
  const nextModelDefaults = nextModel ? this.modelSettingsDefaultsForModel(nextModel) : undefined;
394527
394728
  const nextModelSettings = {
394528
394729
  ...modelChanged ? {} : existingRecord.model_settings,
394529
- ...supportedModelSettingsFromBody(bodyRecord),
394730
+ ...requestedModelSettings,
394530
394731
  ...modelChanged ? nextModelDefaults ?? {} : {}
394531
394732
  };
394532
394733
  const updated = {
@@ -394687,9 +394888,10 @@ class LocalStore {
394687
394888
  const requestedModel = body.model;
394688
394889
  if (typeof requestedModel !== "string")
394689
394890
  return conversation;
394690
- if (previousConversation.model === requestedModel)
394891
+ const normalizedRequestedModel = normalizeLocalModelHandle(requestedModel, isRecord(conversation.model_settings) ? conversation.model_settings : {});
394892
+ if (previousConversation.model === normalizedRequestedModel)
394691
394893
  return conversation;
394692
- const defaults5 = this.modelSettingsDefaultsForModel(requestedModel);
394894
+ const defaults5 = this.modelSettingsDefaultsForModel(normalizedRequestedModel);
394693
394895
  if (!defaults5 || Object.keys(defaults5).length === 0)
394694
394896
  return conversation;
394695
394897
  const existingSettings = isRecord(conversation.model_settings) ? conversation.model_settings : {};
@@ -394908,11 +395110,11 @@ class LocalStore {
394908
395110
  }
394909
395111
  appendUserLocalMessage(conversationId, agentId, message) {
394910
395112
  const conversation = this.ensureConversation(conversationId, agentId);
394911
- const id2 = this.nextLocalMessageId();
394912
395113
  const date6 = this.currentLocalMessageDate();
394913
395114
  const localMessage = {
394914
- id: id2,
395115
+ id: this.nextLocalMessageId(),
394915
395116
  role: "user",
395117
+ otid: optionalString(message.otid ?? message.client_message_id),
394916
395118
  metadata: {
394917
395119
  created_at: date6,
394918
395120
  updated_at: date6,
@@ -395593,9 +395795,10 @@ class LocalStore {
395593
395795
  const existing = this.conversations.get(key);
395594
395796
  if (existing && options3.forceRefresh !== true)
395595
395797
  return existing;
395798
+ const normalizedInput = normalizeStoredLocalModelRecord(input);
395596
395799
  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);
395800
+ const requiresFullTimestampRepair = isSyntheticLocalTimestamp(normalizedInput.created_at) || isSyntheticLocalTimestamp(normalizedInput.updated_at) || isSyntheticLocalTimestamp(normalizedInput.last_message_at);
395801
+ const conversation = requiresFullTimestampRepair ? normalizedInput : repairSyntheticConversationTimestamps(normalizedInput, [], timing);
395599
395802
  let compiledSystemPrompt;
395600
395803
  try {
395601
395804
  compiledSystemPrompt = readJsonFile2(join39(conversationDir, "system-prompt.json"));
@@ -396012,6 +396215,7 @@ class LocalStore {
396012
396215
  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
396216
  var init_local_store = __esm(() => {
396014
396217
  init_constants2();
396218
+ init_local_model_normalization();
396015
396219
  init_local_stream_chunks();
396016
396220
  LocalBackendNotFoundError = class LocalBackendNotFoundError extends Error {
396017
396221
  status = 404;
@@ -397462,13 +397666,13 @@ function localStopReasonChunk(stopReason) {
397462
397666
  }
397463
397667
  function effectiveAgentForConversation(agent2, conversation) {
397464
397668
  const conversationRecord = conversation;
397465
- const conversationModelSettings2 = isRecord(conversationRecord.model_settings) ? conversationRecord.model_settings : undefined;
397669
+ const conversationModelSettings = isRecord(conversationRecord.model_settings) ? conversationRecord.model_settings : undefined;
397466
397670
  return {
397467
397671
  ...agent2,
397468
397672
  ...typeof conversationRecord.model === "string" ? { model: conversationRecord.model } : {},
397469
397673
  model_settings: {
397470
397674
  ...agent2.model_settings,
397471
- ...conversationModelSettings2 ?? {},
397675
+ ...conversationModelSettings ?? {},
397472
397676
  ...typeof conversationRecord.context_window_limit === "number" ? { context_window_limit: conversationRecord.context_window_limit } : {}
397473
397677
  }
397474
397678
  };
@@ -397599,11 +397803,12 @@ class HeadlessBackend {
397599
397803
  };
397600
397804
  }
397601
397805
  async listModels() {
397806
+ const llmConfigPatch = mapModelHandleToLlmConfigPatch(this.modelHandle);
397602
397807
  return [
397603
397808
  {
397604
397809
  handle: this.modelHandle,
397605
- model: this.modelHandle,
397606
- model_endpoint_type: "openai"
397810
+ model: llmConfigPatch.model ?? this.modelHandle,
397811
+ model_endpoint_type: llmConfigPatch.model_endpoint_type ?? "openai"
397607
397812
  }
397608
397813
  ];
397609
397814
  }
@@ -397855,6 +398060,7 @@ class HeadlessBackend {
397855
398060
  }
397856
398061
  var FAKE_HEADLESS_MODEL = "dev/fake-headless";
397857
398062
  var init_fake_headless_backend = __esm(() => {
398063
+ init_model_handles();
397858
398064
  init_local_store();
397859
398065
  init_local_stream_chunks();
397860
398066
  init_constants2();
@@ -397991,6 +398197,15 @@ var init_registered_pi_provider_runtime = __esm(() => {
397991
398197
  function isUnselectedLocalModelHandle(model) {
397992
398198
  return typeof model !== "string" || model.length === 0 || model === "auto" || model === UNSELECTED_LOCAL_MODEL_HANDLE || model.startsWith("letta/");
397993
398199
  }
398200
+ function normalizeOpenAICompatibleLocalModelHandle(model) {
398201
+ if (!model?.startsWith("openai/"))
398202
+ return model;
398203
+ const nestedHandle = model.slice("openai/".length);
398204
+ const nestedProvider = resolveProviderFromModelHandle(nestedHandle);
398205
+ if (!nestedProvider)
398206
+ return model;
398207
+ return getPiProviderSpec(nestedProvider).localModelDiscovery === "openai-compatible" ? nestedHandle : model;
398208
+ }
397994
398209
  function settingString(value) {
397995
398210
  return typeof value === "string" && value.length > 0 ? value : undefined;
397996
398211
  }
@@ -398248,7 +398463,7 @@ function bedrockLocalProviderOptions(record5) {
398248
398463
  };
398249
398464
  }
398250
398465
  async function resolvePiModelForAgent(modelHandle, modelSettings = {}, options3 = {}) {
398251
- const concreteModelHandle = isUnselectedLocalModelHandle(modelHandle) ? undefined : modelHandle;
398466
+ const concreteModelHandle = normalizeOpenAICompatibleLocalModelHandle(isUnselectedLocalModelHandle(modelHandle) ? undefined : modelHandle);
398252
398467
  const provider = options3.provider ? resolvePiProvider(options3.provider) : resolvePiProviderFromAgent(concreteModelHandle, modelSettings);
398253
398468
  const registeredProvider = getRegisteredPiProvider(provider);
398254
398469
  const spec = isPiProvider(provider) ? getPiProviderSpec(provider) : undefined;
@@ -398612,6 +398827,10 @@ async function resolveAvailableLocalModelForTurn(input) {
398612
398827
  }
398613
398828
  };
398614
398829
  }
398830
+ function shouldIncludeLocalModel(provider, model) {
398831
+ const modelId = isPiProvider(provider) ? stripProviderHandlePrefix(model, provider) ?? model : model;
398832
+ return !(localProviderTypeForModelConfig(provider) === "chatgpt_oauth" && UNSUPPORTED_LOCAL_CHATGPT_OAUTH_MODELS.has(modelId));
398833
+ }
398615
398834
  async function listLocalModels(storageDir, options3 = {}) {
398616
398835
  const records = listLocalProviderRecords(storageDir);
398617
398836
  const providerNames = localProviderNamesFromRecords(records);
@@ -398620,6 +398839,8 @@ async function listLocalModels(storageDir, options3 = {}) {
398620
398839
  const registeredProviders2 = listRegisteredPiProviders();
398621
398840
  const registeredProvidersWithModels = new Set(registeredProviders2.filter((provider) => provider.config.models !== undefined).map((provider) => provider.providerName));
398622
398841
  const addModel = (provider, model, options4 = {}) => {
398842
+ if (!shouldIncludeLocalModel(provider, model))
398843
+ return;
398623
398844
  const handle = options4.handle ?? (typeof provider === "string" && !isPiProviderForLocalModelHandle(provider) ? `${provider}/${model}` : localModelHandle(provider, model));
398624
398845
  if (models3.some((entry) => entry.handle === handle))
398625
398846
  return;
@@ -398692,7 +398913,7 @@ async function listLocalModels(storageDir, options3 = {}) {
398692
398913
  }
398693
398914
  return models3;
398694
398915
  }
398695
- var LOCAL_MODEL_DISCOVERY_TIMEOUT_MS = 2000, LOCAL_MODEL_AUTODETECT_DISCOVERY_TIMEOUT_MS = 500;
398916
+ var LOCAL_MODEL_DISCOVERY_TIMEOUT_MS = 2000, LOCAL_MODEL_AUTODETECT_DISCOVERY_TIMEOUT_MS = 500, UNSUPPORTED_LOCAL_CHATGPT_OAUTH_MODELS;
398696
398917
  var init_local_model_config = __esm(() => {
398697
398918
  init_compat2();
398698
398919
  init_pi_model_factory();
@@ -398700,6 +398921,25 @@ var init_local_model_config = __esm(() => {
398700
398921
  init_pi_provider_registry();
398701
398922
  init_registered_pi_provider_runtime();
398702
398923
  init_local_provider_auth_store();
398924
+ UNSUPPORTED_LOCAL_CHATGPT_OAUTH_MODELS = new Set(["gpt-5.6-luna"]);
398925
+ });
398926
+
398927
+ // src/backend/dev/pi-output-budget.ts
398928
+ function assertViablePiOutputBudget(model, context3, requestedMaxTokens) {
398929
+ if (model.provider !== "llama-cpp")
398930
+ return;
398931
+ const requested = requestedMaxTokens ?? model.maxTokens;
398932
+ if (!Number.isFinite(requested) || requested <= 0)
398933
+ return;
398934
+ const clamped = clampMaxTokensToContext(model, context3, requested);
398935
+ const minimum3 = Math.min(requested, MIN_VIABLE_OUTPUT_TOKENS);
398936
+ if (clamped >= minimum3)
398937
+ return;
398938
+ 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.`);
398939
+ }
398940
+ var MIN_VIABLE_OUTPUT_TOKENS = 1024;
398941
+ var init_pi_output_budget = __esm(() => {
398942
+ init_simple_options();
398703
398943
  });
398704
398944
 
398705
398945
  // src/backend/local/local-context-estimate.ts
@@ -399546,6 +399786,7 @@ class PiStreamAdapter {
399546
399786
  messageCount: context3.messages.length,
399547
399787
  contextWindow: resolved.model.contextWindow
399548
399788
  });
399789
+ assertViablePiOutputBudget(resolved.model, context3, options3.maxTokens);
399549
399790
  const result = this.runStream(resolved.model, context3, options3);
399550
399791
  let streamError;
399551
399792
  let finalMessage;
@@ -399686,6 +399927,7 @@ var init_pi_stream_adapter = __esm(() => {
399686
399927
  init_context_window_overflow();
399687
399928
  init_local_provider_errors();
399688
399929
  init_pi_model_factory();
399930
+ init_pi_output_budget();
399689
399931
  init_provider_turn_executor();
399690
399932
  LOCAL_PROVIDER_ADAPTIVE_IMAGE_ELISION_AFTER_RETRIES = LOCAL_PROVIDER_MAX_RETRIES - 1;
399691
399933
  PiProviderError = class PiProviderError extends Error {
@@ -400818,9 +401060,9 @@ var init_local_backend = __esm(() => {
400818
401060
  if (typeof conversation.context_window_limit === "number") {
400819
401061
  return conversation.context_window_limit;
400820
401062
  }
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;
401063
+ const conversationModelSettings = conversation.model_settings;
401064
+ if (conversationModelSettings && typeof conversationModelSettings === "object" && !Array.isArray(conversationModelSettings) && typeof conversationModelSettings.context_window_limit === "number") {
401065
+ return conversationModelSettings.context_window_limit;
400824
401066
  }
400825
401067
  const agent2 = this.store.retrieveAgentRecord(agentId);
400826
401068
  return typeof agent2.model_settings.context_window_limit === "number" ? agent2.model_settings.context_window_limit : undefined;
@@ -400829,17 +401071,17 @@ var init_local_backend = __esm(() => {
400829
401071
  const agent2 = this.store.retrieveAgentRecord(agentId);
400830
401072
  const conversation = this.store.retrieveConversation(conversationId, agentId);
400831
401073
  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) {
401074
+ const conversationModelSettings = isRecord(conversation.model_settings) ? conversation.model_settings : undefined;
401075
+ if (model === undefined && conversationModelSettings === undefined) {
400834
401076
  return agent2;
400835
401077
  }
400836
401078
  return {
400837
401079
  ...agent2,
400838
401080
  ...model !== undefined ? { model } : {},
400839
- ...conversationModelSettings2 !== undefined ? {
401081
+ ...conversationModelSettings !== undefined ? {
400840
401082
  model_settings: {
400841
401083
  ...agent2.model_settings,
400842
- ...conversationModelSettings2
401084
+ ...conversationModelSettings
400843
401085
  }
400844
401086
  } : {}
400845
401087
  };
@@ -401260,10 +401502,13 @@ var init_backend2 = __esm(() => {
401260
401502
  var exports_model2 = {};
401261
401503
  __export(exports_model2, {
401262
401504
  shouldPreserveContextWindowForModelSelection: () => shouldPreserveContextWindowForModelSelection2,
401505
+ resolveModelHandleFromLlmConfig: () => resolveModelHandleFromLlmConfig,
401263
401506
  resolveModelByLlmConfig: () => resolveModelByLlmConfig2,
401264
401507
  resolveModel: () => resolveModel,
401265
- normalizeModelHandleForRegistry: () => normalizeModelHandleForRegistry2,
401508
+ normalizeModelHandleForRegistry: () => normalizeModelHandleForRegistry,
401509
+ normalizeKnownModelHandle: () => normalizeKnownModelHandle,
401266
401510
  models: () => models2,
401511
+ mapModelHandleToLlmConfigPatch: () => mapModelHandleToLlmConfigPatch,
401267
401512
  isLocalModelHandle: () => isLocalModelHandle2,
401268
401513
  isLocalChatGptOAuthModelHandle: () => isLocalChatGptOAuthModelHandle2,
401269
401514
  getResumeRefreshArgs: () => getResumeRefreshArgs2,
@@ -401282,49 +401527,27 @@ __export(exports_model2, {
401282
401527
  CHATGPT_FAST_SERVICE_TIER: () => CHATGPT_FAST_SERVICE_TIER2
401283
401528
  });
401284
401529
  function isLocalModelHandle2(modelHandle) {
401285
- return LOCAL_MODEL_HANDLE_PREFIXES2.some((prefix) => modelHandle.startsWith(prefix));
401530
+ return LOCAL_MODEL_HANDLE_PREFIXES.some((prefix) => modelHandle.startsWith(prefix));
401286
401531
  }
401287
401532
  function getLocalModelLabel2(modelHandle) {
401288
- const providerPrefix = LOCAL_MODEL_HANDLE_PREFIXES2.find((prefix) => modelHandle.startsWith(prefix));
401289
- return providerPrefix ? modelHandle.slice(providerPrefix.length) : modelHandle;
401533
+ const providerPrefix2 = LOCAL_MODEL_HANDLE_PREFIXES.find((prefix) => modelHandle.startsWith(prefix));
401534
+ return providerPrefix2 ? modelHandle.slice(providerPrefix2.length) : modelHandle;
401290
401535
  }
401291
401536
  function isModelReasoningEffort2(value) {
401292
401537
  return typeof value === "string" && REASONING_EFFORT_ORDER2.includes(value);
401293
401538
  }
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
401539
  function isLocalChatGptOAuthModelHandle2(modelHandle) {
401317
- return modelHandle.startsWith(LOCAL_CHATGPT_OAUTH_HANDLE_PREFIX2);
401540
+ return modelHandle.startsWith(LOCAL_CHATGPT_OAUTH_HANDLE_PREFIX);
401318
401541
  }
401319
401542
  function getChatGptFastRegistryHandleForModelHandle2(modelHandle) {
401320
401543
  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) {
401544
+ if (provider !== LOCAL_CHATGPT_OAUTH_HANDLE_PREFIX.slice(0, -1) && provider !== CHATGPT_OAUTH_LLM_CONFIG_PROVIDER && provider !== OPENAI_CODEX_PROVIDER_NAME) {
401322
401545
  return null;
401323
401546
  }
401324
- const normalized = normalizeModelHandleForRegistry2(modelHandle);
401547
+ const normalized = normalizeModelHandleForRegistry(modelHandle);
401325
401548
  if (!normalized?.startsWith(`${OPENAI_CODEX_PROVIDER_NAME}/`))
401326
401549
  return null;
401327
- const model = modelPortion2(normalized);
401550
+ const model = modelPortionFromHandle(normalized);
401328
401551
  if (!model || model.endsWith("-fast"))
401329
401552
  return null;
401330
401553
  const fastHandle = `${OPENAI_CODEX_PROVIDER_NAME}/${model}-fast`;
@@ -401334,11 +401557,11 @@ function displayRegistryHandleForServiceTier2(modelHandle, serviceTier) {
401334
401557
  if (serviceTier === CHATGPT_FAST_SERVICE_TIER2) {
401335
401558
  return getChatGptFastRegistryHandleForModelHandle2(modelHandle) ?? modelHandle;
401336
401559
  }
401337
- return normalizeModelHandleForRegistry2(modelHandle) ?? modelHandle;
401560
+ return normalizeModelHandleForRegistry(modelHandle) ?? modelHandle;
401338
401561
  }
401339
401562
  function getReasoningTierOptionsForHandle2(modelHandle, contextWindow) {
401340
401563
  const byEffort = new Map;
401341
- const registryHandle = normalizeModelHandleForRegistry2(modelHandle) ?? modelHandle;
401564
+ const registryHandle = normalizeModelHandleForRegistry(modelHandle) ?? modelHandle;
401342
401565
  const effectiveContextWindow = contextWindow ?? (() => {
401343
401566
  const contextWindows = models2.filter((model) => model.handle === registryHandle).map((model) => model.updateArgs?.context_window).filter((value) => typeof value === "number");
401344
401567
  const uniqueContextWindows = [...new Set(contextWindows)];
@@ -401381,7 +401604,7 @@ function getModelInfo2(modelIdentifier) {
401381
401604
  const byId = models2.find((m2) => m2.id === modelIdentifier);
401382
401605
  if (byId)
401383
401606
  return byId;
401384
- const normalizedHandle = normalizeModelHandleForRegistry2(modelIdentifier);
401607
+ const normalizedHandle = normalizeModelHandleForRegistry(modelIdentifier);
401385
401608
  const byHandle = models2.find((m2) => m2.handle === normalizedHandle);
401386
401609
  if (byHandle)
401387
401610
  return byHandle;
@@ -401433,8 +401656,8 @@ function buildModelHandleFromConfig2(config3) {
401433
401656
  return config3.model ?? null;
401434
401657
  }
401435
401658
  function shouldPreserveContextWindowForModelSelection2(input) {
401436
- const currentRegistryModelHandle = normalizeModelHandleForRegistry2(input.currentModelHandle ?? buildModelHandleFromConfig2(input.currentLlmConfig));
401437
- const selectedRegistryModelHandle = normalizeModelHandleForRegistry2(input.selectedModelHandle);
401659
+ const currentRegistryModelHandle = normalizeModelHandleForRegistry(input.currentModelHandle ?? buildModelHandleFromConfig2(input.currentLlmConfig));
401660
+ const selectedRegistryModelHandle = normalizeModelHandleForRegistry(input.selectedModelHandle);
401438
401661
  if (selectedRegistryModelHandle === null || selectedRegistryModelHandle !== currentRegistryModelHandle) {
401439
401662
  return false;
401440
401663
  }
@@ -401492,23 +401715,23 @@ function getResumeRefreshArgs2(presetUpdateArgs, agent2) {
401492
401715
  }
401493
401716
  function findModelByHandle2(handle) {
401494
401717
  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;
401718
+ const registryHandle = normalizeModelHandleForRegistry(handle) ?? handle;
401496
401719
  const exactMatch = models2.find((m2) => m2.handle === registryHandle);
401497
401720
  if (exactMatch)
401498
401721
  return exactMatch;
401499
401722
  const [provider, ...rest3] = registryHandle.split("/");
401500
401723
  if (provider && rest3.length > 0) {
401501
- const modelPortion3 = rest3.join("/");
401724
+ const modelPortion = rest3.join("/");
401502
401725
  const providerMatches = models2.filter((m2) => {
401503
401726
  if (!m2.handle.startsWith(`${provider}/`))
401504
401727
  return false;
401505
401728
  const mModelPortion = m2.handle.slice(provider.length + 1);
401506
- return mModelPortion.includes(modelPortion3) || modelPortion3.includes(mModelPortion);
401729
+ return mModelPortion.includes(modelPortion) || modelPortion.includes(mModelPortion);
401507
401730
  });
401508
401731
  const providerMatch = pickPreferred(providerMatches);
401509
401732
  if (providerMatch)
401510
401733
  return providerMatch;
401511
- const suffixMatches = models2.filter((m2) => m2.handle.endsWith(`/${modelPortion3}`));
401734
+ const suffixMatches = models2.filter((m2) => m2.handle.endsWith(`/${modelPortion}`));
401512
401735
  const suffixMatch = pickPreferred(suffixMatches);
401513
401736
  if (suffixMatch)
401514
401737
  return suffixMatch;
@@ -401537,10 +401760,11 @@ function resolveModelByLlmConfig2(llmConfigModel) {
401537
401760
  return exactMatch.id;
401538
401761
  return null;
401539
401762
  }
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;
401763
+ var REASONING_EFFORT_ORDER2, LOCAL_REASONING_EFFORT_ORDER2, CHATGPT_FAST_SERVICE_TIER2 = "priority", RESUME_REFRESH_FIELDS2;
401541
401764
  var init_model2 = __esm(() => {
401542
- init_openai_codex_provider();
401543
401765
  init_model_catalog();
401766
+ init_model_handles();
401767
+ init_model_handles();
401544
401768
  REASONING_EFFORT_ORDER2 = [
401545
401769
  "none",
401546
401770
  "minimal",
@@ -401556,13 +401780,6 @@ var init_model2 = __esm(() => {
401556
401780
  "medium",
401557
401781
  "high"
401558
401782
  ];
401559
- LOCAL_MODEL_HANDLE_PREFIXES2 = [
401560
- "ollama/",
401561
- "ollama-cloud/",
401562
- "lmstudio/",
401563
- "llama.cpp/",
401564
- "llama-cpp/"
401565
- ];
401566
401783
  RESUME_REFRESH_FIELDS2 = [
401567
401784
  "max_output_tokens",
401568
401785
  "parallel_tool_calls"
@@ -445436,9 +445653,9 @@ async function applySetMaxContext(params) {
445436
445653
  });
445437
445654
  const updatedConversationRecord = updatedConversation;
445438
445655
  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);
445656
+ const conversationModelSettings = nonEmptyModelSettings(updatedConversationRecord.model_settings) ?? nonEmptyModelSettings(conversationRecord.model_settings);
445440
445657
  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);
445658
+ const inheritedModelSettings = conversationModelSettings ?? (conversationModel === null || conversationModel === agentModelHandle ? agent2.model_settings ?? null : null);
445442
445659
  return {
445443
445660
  contextWindow,
445444
445661
  reset,
@@ -459331,7 +459548,7 @@ function buildModelHandleFromConfig4(config3) {
459331
459548
  }
459332
459549
  return config3.model ?? null;
459333
459550
  }
459334
- function providerTypeFromModelSettings2(modelSettings) {
459551
+ function providerTypeFromModelSettings3(modelSettings) {
459335
459552
  const providerType = modelSettings?.provider_type;
459336
459553
  return typeof providerType === "string" ? providerType : null;
459337
459554
  }
@@ -459508,7 +459725,7 @@ async function applyModelUpdateForRuntime(params) {
459508
459725
  agentId,
459509
459726
  conversationId,
459510
459727
  overrideModel: model.handle,
459511
- overrideProviderType: providerTypeFromModelSettings2(modelSettings) ?? inferProviderTypeFromRegistryHandle(model.handle) ?? null,
459728
+ overrideProviderType: providerTypeFromModelSettings3(modelSettings) ?? inferProviderTypeFromRegistryHandle(model.handle) ?? null,
459512
459729
  modEvents: ensureListenerModAdapter(listener).events
459513
459730
  });
459514
459731
  nextToolset = preparedToolContext.toolset;
@@ -477197,7 +477414,7 @@ var init_build7 = __esm(async () => {
477197
477414
 
477198
477415
  // src/agent/conversation-model-carryover.ts
477199
477416
  function normalizeConversationModelCarryoverHandle(rawModelHandle) {
477200
- return normalizeModelHandleForRegistry(rawModelHandle) ?? rawModelHandle;
477417
+ return normalizeKnownModelHandle(rawModelHandle);
477201
477418
  }
477202
477419
  function buildConversationModelCarryoverUpdate(params) {
477203
477420
  const { rawModelHandle, currentLlmConfig } = params;
@@ -477235,6 +477452,7 @@ function buildConversationModelCarryoverUpdate(params) {
477235
477452
  }
477236
477453
  var init_conversation_model_carryover = __esm(() => {
477237
477454
  init_model();
477455
+ init_model_handles();
477238
477456
  });
477239
477457
 
477240
477458
  // src/agent/reconcile-existing-agent-state.ts
@@ -522548,13 +522766,8 @@ function inferReasoningEffortFromModelPreset(modelId, modelHandle) {
522548
522766
  }
522549
522767
  return null;
522550
522768
  }
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;
522769
+ function buildModelHandleFromLlmConfig(llmConfig) {
522770
+ return resolveModelHandleFromLlmConfig(llmConfig);
522558
522771
  }
522559
522772
  function getPreferredAgentModelHandle2(agent2) {
522560
522773
  if (!agent2)
@@ -522562,9 +522775,9 @@ function getPreferredAgentModelHandle2(agent2) {
522562
522775
  if (typeof agent2.model === "string" && agent2.model.length > 0) {
522563
522776
  return agent2.model;
522564
522777
  }
522565
- return buildModelHandleFromLlmConfig3(agent2.llm_config);
522778
+ return buildModelHandleFromLlmConfig(agent2.llm_config);
522566
522779
  }
522567
- function providerTypeFromModelSettings3(modelSettings) {
522780
+ function providerTypeFromModelSettings4(modelSettings) {
522568
522781
  if (typeof modelSettings !== "object" || modelSettings === null || !("provider_type" in modelSettings)) {
522569
522782
  return null;
522570
522783
  }
@@ -522576,35 +522789,7 @@ function providerTypeFromUpdateArgs(updateArgs) {
522576
522789
  return typeof providerType === "string" && providerType.length > 0 ? providerType : null;
522577
522790
  }
522578
522791
  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
- };
522792
+ return mapModelHandleToLlmConfigPatch(modelHandle, providerType);
522608
522793
  }
522609
522794
  function getErrorHintForStopReason(stopReason, currentModelId, modelEndpointType) {
522610
522795
  if (stopReason !== "llm_api_error") {
@@ -522625,7 +522810,7 @@ function getErrorHintForStopReason(stopReason, currentModelId, modelEndpointType
522625
522810
  }
522626
522811
  var init_model_config = __esm(() => {
522627
522812
  init_model();
522628
- init_openai_codex_provider();
522813
+ init_model_handles();
522629
522814
  init_constants7();
522630
522815
  });
522631
522816
 
@@ -523722,11 +523907,11 @@ function useConfigurationHandlers(ctx) {
523722
523907
  const {
523723
523908
  getChatGptFastRegistryHandleForModelHandle: getChatGptFastRegistryHandleForModelHandle3,
523724
523909
  getReasoningTierOptionsForHandle: getReasoningTierOptionsForHandle3,
523725
- normalizeModelHandleForRegistry: normalizeModelHandleForRegistry3,
523910
+ normalizeModelHandleForRegistry: normalizeModelHandleForRegistry2,
523726
523911
  models: models3
523727
523912
  } = await Promise.resolve().then(() => (init_model(), exports_model));
523728
523913
  const pickPreferredModelForHandle = (handle2) => {
523729
- const registryHandle2 = normalizeModelHandleForRegistry3(handle2) ?? handle2;
523914
+ const registryHandle2 = normalizeModelHandleForRegistry2(handle2) ?? handle2;
523730
523915
  const candidates2 = models3.filter((m4) => m4.handle === registryHandle2);
523731
523916
  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
523917
  };
@@ -523771,7 +523956,7 @@ function useConfigurationHandlers(ctx) {
523771
523956
  ...handleMatch,
523772
523957
  id: modelId,
523773
523958
  handle: modelId,
523774
- registryHandle: normalizeModelHandleForRegistry3(registryCandidate) ?? registryCandidate,
523959
+ registryHandle: normalizeModelHandleForRegistry2(registryCandidate) ?? registryCandidate,
523775
523960
  updateArgs: Object.keys(updateArgs).length > 0 ? updateArgs : undefined
523776
523961
  };
523777
523962
  }
@@ -523810,7 +523995,7 @@ function useConfigurationHandlers(ctx) {
523810
523995
  }
523811
523996
  const model2 = selectedModel;
523812
523997
  const modelHandle = model2.handle ?? model2.id;
523813
- const registryHandle = model2.registryHandle ?? normalizeModelHandleForRegistry3(modelHandle) ?? modelHandle;
523998
+ const registryHandle = model2.registryHandle ?? normalizeModelHandleForRegistry2(modelHandle) ?? modelHandle;
523814
523999
  const modelUpdateArgs = model2.updateArgs;
523815
524000
  const rawReasoningEffort = modelUpdateArgs?.reasoning_effort;
523816
524001
  const usesDistinctXHighLabel = /Fable 5|Opus 4\.[78]|GPT-5\.6/.test(model2.label);
@@ -523885,7 +524070,7 @@ function useConfigurationHandlers(ctx) {
523885
524070
  phase: "running"
523886
524071
  });
523887
524072
  const isDefaultConversation = conversationIdRef.current === "default";
523888
- let conversationModelSettings2;
524073
+ let conversationModelSettings;
523889
524074
  let conversationContextWindowLimit;
523890
524075
  let updatedAgent = null;
523891
524076
  if (isDefaultConversation) {
@@ -523893,17 +524078,17 @@ function useConfigurationHandlers(ctx) {
523893
524078
  updatedAgent = await updateAgentLLMConfig3(agentIdRef.current, modelHandle, modelUpdateArgsForRequest, {
523894
524079
  avoidOverwritingExistingContextWindow: shouldPreserveContextWindow
523895
524080
  });
523896
- conversationModelSettings2 = updatedAgent?.model_settings;
524081
+ conversationModelSettings = updatedAgent?.model_settings;
523897
524082
  } else {
523898
524083
  const { updateConversationLLMConfig: updateConversationLLMConfig2 } = await Promise.resolve().then(() => (init_modify(), exports_modify));
523899
524084
  const updatedConversation = await updateConversationLLMConfig2(conversationIdRef.current, modelHandle, modelUpdateArgsForRequest, {
523900
524085
  avoidOverwritingExistingContextWindow: shouldPreserveContextWindow
523901
524086
  });
523902
- conversationModelSettings2 = updatedConversation.model_settings;
524087
+ conversationModelSettings = updatedConversation.model_settings;
523903
524088
  conversationContextWindowLimit = updatedConversation.context_window_limit;
523904
524089
  }
523905
524090
  const rawEffort = modelUpdateArgs?.reasoning_effort;
523906
- const resolvedReasoningEffort = typeof rawEffort === "string" ? rawEffort : deriveReasoningEffort(conversationModelSettings2, llmConfigRef.current) ?? null;
524091
+ const resolvedReasoningEffort = typeof rawEffort === "string" ? rawEffort : deriveReasoningEffort(conversationModelSettings, llmConfigRef.current) ?? null;
523907
524092
  if (isDefaultConversation) {
523908
524093
  setHasConversationModelOverride(false);
523909
524094
  setConversationOverrideModelSettings(null);
@@ -523913,12 +524098,12 @@ function useConfigurationHandlers(ctx) {
523913
524098
  }
523914
524099
  } else {
523915
524100
  setHasConversationModelOverride(true);
523916
- setConversationOverrideModelSettings(conversationModelSettings2 ?? null);
524101
+ setConversationOverrideModelSettings(conversationModelSettings ?? null);
523917
524102
  }
523918
524103
  const presetContextWindow = modelUpdateArgsForRequest?.context_window;
523919
524104
  const preservedContextWindow = llmConfigRef.current?.context_window;
523920
524105
  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);
524106
+ const resolvedProviderType = providerTypeFromModelSettings4(conversationModelSettings) ?? providerTypeFromUpdateArgs(modelUpdateArgsForRequest) ?? providerTypeFromUpdateArgs(modelUpdateArgs);
523922
524107
  if (!isDefaultConversation) {
523923
524108
  setConversationOverrideContextWindowLimit(typeof resolvedContextWindow === "number" ? resolvedContextWindow : null);
523924
524109
  }
@@ -524312,7 +524497,7 @@ ${guidance}`);
524312
524497
  if (!modelHandle) {
524313
524498
  throw new Error("Could not determine current model for auto toolset");
524314
524499
  }
524315
- const providerType = providerTypeFromModelSettings3(agentState?.model_settings) ?? llmConfig?.model_endpoint_type ?? null;
524500
+ const providerType = providerTypeFromModelSettings4(agentState?.model_settings) ?? llmConfig?.model_endpoint_type ?? null;
524316
524501
  const derivedToolset = await switchToolsetForModel2(modelHandle, agentId, providerType);
524317
524502
  settingsManager.setToolsetPreference(agentId, "auto");
524318
524503
  setCurrentToolsetPreference("auto");
@@ -527222,7 +527407,7 @@ function resolveReasoningCycleTierLookupHandle(modelHandle, modelSettings) {
527222
527407
  if (isLocalModelHandle(modelHandle)) {
527223
527408
  return modelHandle;
527224
527409
  }
527225
- const providerType = providerTypeFromModelSettings3(modelSettings);
527410
+ const providerType = providerTypeFromModelSettings4(modelSettings);
527226
527411
  const modelName = modelNameFromHandle(modelHandle);
527227
527412
  if (!providerType || !modelName) {
527228
527413
  return normalizedHandle ?? modelHandle;
@@ -527290,7 +527475,7 @@ function useReasoningCycle(ctx) {
527290
527475
  const cmd = commandRunner.start("/reasoning", "Setting reasoning...");
527291
527476
  try {
527292
527477
  const isDefaultConversation = conversationIdRef.current === "default";
527293
- let conversationModelSettings2;
527478
+ let conversationModelSettings;
527294
527479
  let conversationContextWindowLimit;
527295
527480
  let updatedAgent = null;
527296
527481
  if (isDefaultConversation) {
@@ -527307,10 +527492,10 @@ function useReasoningCycle(ctx) {
527307
527492
  ...desired.providerType ? { provider_type: desired.providerType } : {},
527308
527493
  ...desired.serviceTier !== undefined ? { service_tier: desired.serviceTier } : {}
527309
527494
  }, { avoidOverwritingExistingContextWindow: true });
527310
- conversationModelSettings2 = updatedConversation.model_settings;
527495
+ conversationModelSettings = updatedConversation.model_settings;
527311
527496
  conversationContextWindowLimit = updatedConversation.context_window_limit;
527312
527497
  }
527313
- const resolvedReasoningEffort = deriveReasoningEffort(isDefaultConversation ? updatedAgent?.model_settings ?? null : conversationModelSettings2, llmConfigRef.current) ?? desired.effort;
527498
+ const resolvedReasoningEffort = deriveReasoningEffort(isDefaultConversation ? updatedAgent?.model_settings ?? null : conversationModelSettings, llmConfigRef.current) ?? desired.effort;
527314
527499
  const resolvedConversationContextWindowLimit = conversationContextWindowLimit === undefined ? typeof llmConfigRef.current?.context_window === "number" ? llmConfigRef.current.context_window : null : conversationContextWindowLimit;
527315
527500
  if (isDefaultConversation) {
527316
527501
  setHasConversationModelOverride(false);
@@ -527321,12 +527506,12 @@ function useReasoningCycle(ctx) {
527321
527506
  }
527322
527507
  } else {
527323
527508
  setHasConversationModelOverride(true);
527324
- setConversationOverrideModelSettings(conversationModelSettings2 ?? null);
527509
+ setConversationOverrideModelSettings(conversationModelSettings ?? null);
527325
527510
  setConversationOverrideContextWindowLimit(resolvedConversationContextWindowLimit);
527326
527511
  }
527327
527512
  setLlmConfig({
527328
527513
  ...updatedAgent?.llm_config ?? llmConfigRef.current ?? {},
527329
- ...mapHandleToLlmConfigPatch(desired.modelHandle, providerTypeFromModelSettings3(isDefaultConversation ? updatedAgent?.model_settings ?? null : conversationModelSettings2)),
527514
+ ...mapHandleToLlmConfigPatch(desired.modelHandle, providerTypeFromModelSettings4(isDefaultConversation ? updatedAgent?.model_settings ?? null : conversationModelSettings)),
527330
527515
  reasoning_effort: resolvedReasoningEffort,
527331
527516
  ...typeof resolvedConversationContextWindowLimit === "number" ? { context_window: resolvedConversationContextWindowLimit } : {}
527332
527517
  });
@@ -527389,7 +527574,7 @@ function useReasoningCycle(ctx) {
527389
527574
  return;
527390
527575
  const current = llmConfigRef.current;
527391
527576
  const modelSettingsForEffort = hasConversationModelOverrideRef.current ? conversationOverrideModelSettingsRef.current : agentStateRef.current?.model_settings;
527392
- const providerType = providerTypeFromModelSettings3(modelSettingsForEffort);
527577
+ const providerType = providerTypeFromModelSettings4(modelSettingsForEffort);
527393
527578
  const modelHandle = resolveReasoningCycleModelHandle(current, hasConversationModelOverrideRef.current ? null : agentStateRef.current?.model ?? null, currentModelHandleRef.current);
527394
527579
  if (!modelHandle)
527395
527580
  return;
@@ -536093,7 +536278,7 @@ function App2({
536093
536278
  if (persistedToolsetPreference === "auto") {
536094
536279
  if (agentModelHandle) {
536095
536280
  const { switchToolsetForModel: switchToolsetForModel2 } = await init_toolset().then(() => exports_toolset);
536096
- const providerType = providerTypeFromModelSettings3(agent2.model_settings) ?? agent2.llm_config?.model_endpoint_type ?? null;
536281
+ const providerType = providerTypeFromModelSettings4(agent2.model_settings) ?? agent2.llm_config?.model_endpoint_type ?? null;
536097
536282
  const derivedToolset = await switchToolsetForModel2(agentModelHandle, agentId, providerType);
536098
536283
  setCurrentToolset(derivedToolset);
536099
536284
  } else {
@@ -536194,7 +536379,7 @@ function App2({
536194
536379
  setConversationOverrideContextWindowLimit(null);
536195
536380
  setLlmConfig(agentState.llm_config);
536196
536381
  setCurrentModelHandle(agentModelHandle ?? null);
536197
- const currentHandle = buildModelHandleFromLlmConfig3(llmConfigRef.current);
536382
+ const currentHandle = buildModelHandleFromLlmConfig(llmConfigRef.current);
536198
536383
  if (agentModelHandle && agentModelHandle === currentHandle) {
536199
536384
  return;
536200
536385
  }
@@ -536217,9 +536402,9 @@ function App2({
536217
536402
  if (cancelled)
536218
536403
  return;
536219
536404
  const conversationModel = conversation.model;
536220
- const conversationModelSettings2 = conversation.model_settings;
536405
+ const conversationModelSettings = conversation.model_settings;
536221
536406
  const conversationContextWindowLimit = conversation.context_window_limit;
536222
- const hasOverride = conversationModel !== undefined && conversationModel !== null ? true : conversationModelSettings2 !== undefined && conversationModelSettings2 !== null ? true : conversationContextWindowLimit !== undefined && conversationContextWindowLimit !== null;
536407
+ const hasOverride = conversationModel !== undefined && conversationModel !== null ? true : conversationModelSettings !== undefined && conversationModelSettings !== null ? true : conversationContextWindowLimit !== undefined && conversationContextWindowLimit !== null;
536223
536408
  if (!hasOverride) {
536224
536409
  applyAgentModelLocally();
536225
536410
  return;
@@ -536230,8 +536415,8 @@ function App2({
536230
536415
  applyAgentModelLocally();
536231
536416
  return;
536232
536417
  }
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;
536418
+ const hasConversationModelSettings = conversationModelSettings !== undefined && conversationModelSettings !== null && Object.keys(conversationModelSettings).length > 0;
536419
+ const resolvedConversationModelSettings = hasConversationModelSettings ? conversationModelSettings : conversationModel === undefined || conversationModel === null || conversationModel === agentModelHandle ? agentState.model_settings ?? null : null;
536235
536420
  const reasoningEffort = deriveReasoningEffort(resolvedConversationModelSettings, agentState.llm_config);
536236
536421
  const conversationServiceTier = resolvedConversationModelSettings?.service_tier === CHATGPT_FAST_SERVICE_TIER && getChatGptFastRegistryHandleForModelHandle(effectiveModelHandle) ? CHATGPT_FAST_SERVICE_TIER : null;
536237
536422
  const modelInfo = getModelInfoForLlmConfig(effectiveModelHandle, {
@@ -536249,7 +536434,7 @@ function App2({
536249
536434
  setCurrentModelId(modelInfo?.id ?? effectiveModelHandle);
536250
536435
  setLlmConfig({
536251
536436
  ...agentState.llm_config,
536252
- ...mapHandleToLlmConfigPatch(effectiveModelHandle, providerTypeFromModelSettings3(resolvedConversationModelSettings)),
536437
+ ...mapHandleToLlmConfigPatch(effectiveModelHandle, providerTypeFromModelSettings4(resolvedConversationModelSettings)),
536253
536438
  ...typeof reasoningEffort === "string" ? { reasoning_effort: reasoningEffort } : {},
536254
536439
  ...typeof resolvedConversationContextWindowLimit === "number" ? { context_window: resolvedConversationContextWindowLimit } : {}
536255
536440
  });
@@ -536272,11 +536457,10 @@ function App2({
536272
536457
  setHasConversationModelOverride
536273
536458
  ]);
536274
536459
  const maybeCarryOverActiveConversationModel = import_react122.useCallback(async (targetConversationId) => {
536275
- if (!hasConversationModelOverrideRef.current) {
536460
+ if (!hasConversationModelOverrideRef.current)
536276
536461
  return;
536277
- }
536278
536462
  const currentLlmConfig = llmConfigRef.current;
536279
- const rawModelHandle = buildModelHandleFromLlmConfig3(currentLlmConfig);
536463
+ const rawModelHandle = currentModelHandleRef.current ?? buildModelHandleFromLlmConfig(currentLlmConfig);
536280
536464
  if (!rawModelHandle) {
536281
536465
  return;
536282
536466
  }
@@ -552617,6 +552801,7 @@ ${after}`;
552617
552801
 
552618
552802
  // src/tools/toolset.ts
552619
552803
  init_model();
552804
+ init_model_handles();
552620
552805
  init_backend2();
552621
552806
  init_client2();
552622
552807
  init_plugin_registry();
@@ -554458,4 +554643,4 @@ Error during initialization: ${message}`);
554458
554643
  }
554459
554644
  main2();
554460
554645
 
554461
- //# debugId=A09A03B6B9AA731C64756E2164756E21
554646
+ //# debugId=6B7881A097F42D3C64756E2164756E21