@eminent337/aery 0.1.110 → 0.1.112

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.
@@ -11,9 +11,10 @@ import { CombinedAutocompleteProvider, Container, fuzzyFilter, Loader, Markdown,
11
11
  import { spawn, spawnSync } from "child_process";
12
12
  import { collectCapabilitiesReport, formatCapabilitiesReport } from "../../cli/capabilities.js";
13
13
  import { formatCurrentCoreExtensionsReport } from "../../cli/doctor.js";
14
- import { APP_NAME, getAgentDir, getAuthPath, getDebugLogPath, getShareViewerUrl, getUpdateInstruction, VERSION, } from "../../config.js";
14
+ import { APP_NAME, getAgentDir, getAuthPath, getDebugLogPath, getModelsPath, getShareViewerUrl, getUpdateInstruction, VERSION, } from "../../config.js";
15
15
  import { parseSkillBlock } from "../../core/agent-session.js";
16
16
  import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
17
+ import { CUSTOM_OPENAI_COMPATIBLE_PROVIDER_ID, saveCustomOpenAICompatibleProvider, } from "../../core/custom-openai-compatible.js";
17
18
  import { FooterDataProvider } from "../../core/footer-data-provider.js";
18
19
  import { KeybindingsManager } from "../../core/keybindings.js";
19
20
  import { createCompactionSummaryMessage } from "../../core/messages.js";
@@ -117,6 +118,7 @@ const API_KEY_PROVIDER_NAMES = {
117
118
  zai: "ZAI",
118
119
  };
119
120
  const API_KEY_LOGIN_PROVIDER_BLOCKLIST = new Set(["amazon-bedrock", "llama.cpp", "lmstudio", "ollama"]);
121
+ const CUSTOM_OPENAI_COMPATIBLE_PROVIDER_LABEL = "Custom OpenAI-compatible";
120
122
  export function isApiKeyLoginProvider(providerId, oauthProviderIds, builtInProviderIds = new Set(getProviders())) {
121
123
  if (API_KEY_PROVIDER_NAMES[providerId])
122
124
  return true;
@@ -3687,6 +3689,13 @@ export class InteractiveMode {
3687
3689
  authType: "api_key",
3688
3690
  });
3689
3691
  }
3692
+ if (!authType || authType === "api_key") {
3693
+ options.push({
3694
+ id: CUSTOM_OPENAI_COMPATIBLE_PROVIDER_ID,
3695
+ name: CUSTOM_OPENAI_COMPATIBLE_PROVIDER_LABEL,
3696
+ authType: "api_key",
3697
+ });
3698
+ }
3690
3699
  const filteredOptions = authType ? options.filter((option) => option.authType === authType) : options;
3691
3700
  return filteredOptions.sort((a, b) => a.name.localeCompare(b.name));
3692
3701
  }
@@ -3737,7 +3746,10 @@ export class InteractiveMode {
3737
3746
  if (!providerOption) {
3738
3747
  return;
3739
3748
  }
3740
- if (providerOption.authType === "oauth") {
3749
+ if (providerOption.id === CUSTOM_OPENAI_COMPATIBLE_PROVIDER_ID) {
3750
+ await this.showCustomOpenAICompatibleLoginDialog();
3751
+ }
3752
+ else if (providerOption.authType === "oauth") {
3741
3753
  await this.showLoginDialog(providerOption.id, providerOption.name);
3742
3754
  }
3743
3755
  else {
@@ -3889,6 +3901,72 @@ export class InteractiveMode {
3889
3901
  }
3890
3902
  }
3891
3903
  }
3904
+ async showCustomOpenAICompatibleLoginDialog() {
3905
+ const previousModel = this.session.model;
3906
+ const dialog = new LoginDialogComponent(this.ui, CUSTOM_OPENAI_COMPATIBLE_PROVIDER_ID, (_success, _message) => { }, `Configure ${CUSTOM_OPENAI_COMPATIBLE_PROVIDER_LABEL}`);
3907
+ this.editorContainer.clear();
3908
+ this.editorContainer.addChild(dialog);
3909
+ this.ui.setFocus(dialog);
3910
+ this.ui.requestRender();
3911
+ const restoreEditor = () => {
3912
+ this.editorContainer.clear();
3913
+ this.editorContainer.addChild(this.editor);
3914
+ this.ui.setFocus(this.editor);
3915
+ this.ui.requestRender();
3916
+ };
3917
+ try {
3918
+ const baseUrl = (await dialog.showPrompt("Enter base URL:", "https://api.example.com/v1")).trim();
3919
+ if (!baseUrl) {
3920
+ throw new Error("Base URL cannot be empty.");
3921
+ }
3922
+ const modelId = (await dialog.showPrompt("Enter model ID:", "gpt-4o-mini")).trim();
3923
+ if (!modelId) {
3924
+ throw new Error("Model ID cannot be empty.");
3925
+ }
3926
+ const apiKey = (await dialog.showPrompt("Enter API key:", "sk-...")).trim();
3927
+ if (!apiKey) {
3928
+ throw new Error("API key cannot be empty.");
3929
+ }
3930
+ const saved = saveCustomOpenAICompatibleProvider({
3931
+ modelsPath: getModelsPath(),
3932
+ baseUrl,
3933
+ modelId,
3934
+ });
3935
+ this.session.modelRegistry.authStorage.set(saved.providerId, { type: "api_key", key: apiKey });
3936
+ this.session.modelRegistry.refresh();
3937
+ restoreEditor();
3938
+ await this.updateAvailableProviderCount();
3939
+ this.footer.invalidate();
3940
+ this.updateEditorBorderColor();
3941
+ const model = this.session.modelRegistry.find(saved.providerId, saved.modelId);
3942
+ let selectedModel = false;
3943
+ if (model) {
3944
+ try {
3945
+ await this.session.setModel(model);
3946
+ selectedModel = true;
3947
+ }
3948
+ catch (error) {
3949
+ this.showError(`Saved ${saved.providerId}/${saved.modelId}, but selecting it failed: ${error instanceof Error ? error.message : String(error)}. Use /model to select it manually.`);
3950
+ }
3951
+ }
3952
+ if (selectedModel) {
3953
+ this.showStatus(`Configured ${saved.providerId}/${saved.modelId}. Provider saved to ${saved.modelsPath}; API key saved to ${getAuthPath()}.`);
3954
+ }
3955
+ else {
3956
+ this.showStatus(`Configured ${saved.providerId}/${saved.modelId}. Provider saved to ${saved.modelsPath}; API key saved to ${getAuthPath()}. Use /model to select it.`);
3957
+ }
3958
+ if (isUnknownModel(previousModel) && !selectedModel) {
3959
+ this.showWarning(`Custom provider ${saved.providerId} is available, but no model was selected automatically.`);
3960
+ }
3961
+ }
3962
+ catch (error) {
3963
+ restoreEditor();
3964
+ const errorMsg = error instanceof Error ? error.message : String(error);
3965
+ if (errorMsg !== "Login cancelled") {
3966
+ this.showError(`Failed to configure ${CUSTOM_OPENAI_COMPATIBLE_PROVIDER_LABEL}: ${errorMsg}`);
3967
+ }
3968
+ }
3969
+ }
3892
3970
  async showLoginDialog(providerId, providerName) {
3893
3971
  const providerInfo = this.session.modelRegistry.authStorage
3894
3972
  .getOAuthProviders()