Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/source/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,13 @@ Eden AI

* ``API Endpoint``: Sets the Eden AI base URL used for requests. Change it only when your deployment requires another compatible endpoint. Default: ``https://api.edenai.run/v3``.

Atlas Cloud
^^^^^^^^^^^

* ``Atlas Cloud API key``: Supplies the credential used to authenticate Atlas Cloud requests. It is used for models assigned to the Atlas Cloud provider, and can also be supplied through the ``ATLASCLOUD_API_KEY`` environment variable.

* ``API Endpoint``: Sets the Atlas Cloud base URL used for requests. It is an OpenAI-compatible endpoint; change it only when your deployment requires another compatible address. Default: ``https://api.atlascloud.ai/v1``.

Layout
~~~~~~

Expand Down
4 changes: 3 additions & 1 deletion src/pygpt_net/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ def run(**kwargs):
from pygpt_net.provider.llms.litellm import LiteLLMProvider
from pygpt_net.provider.llms.forge import ForgeLLM
from pygpt_net.provider.llms.edenai import EdenAILLM
from pygpt_net.provider.llms.atlas_cloud import AtlasCloudLLM

# vector store providers (llama-index)
from pygpt_net.provider.vector_stores.chroma import ChromaProvider
Expand Down Expand Up @@ -496,6 +497,7 @@ def run(**kwargs):
launcher.add_llm(OpenRouterLLM())
launcher.add_llm(ForgeLLM())
launcher.add_llm(EdenAILLM())
launcher.add_llm(AtlasCloudLLM())
launcher.add_llm(LiteLLMProvider())

# register LLMs
Expand Down Expand Up @@ -586,4 +588,4 @@ def run(**kwargs):


if __name__ == '__main__':
run()
run()
16 changes: 15 additions & 1 deletion src/pygpt_net/controller/model/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,20 @@ def get_provider_available(self) -> Dict:
'type': 'str'
}
])
elif self.provider == "atlas_cloud":
m.tool_calls = True
m.llama_index['args'].extend([
{
'name': 'api_key',
'value': '{api_key_atlas_cloud}',
'type': 'str'
},
{
'name': 'api_base',
'value': '{api_endpoint_atlas_cloud}',
'type': 'str'
}
])
models[key] = m
provider_name = self.window.core.llm.get_provider_name(self.provider)
self.set_status(trans('models.importer.loaded').replace("{provider}", provider_name))
Expand Down Expand Up @@ -807,4 +821,4 @@ def hook_update(
self.provider = value
self.init(reload=True, on_change=True)
if value == "_":
self.set_status("")
self.set_status("")
8 changes: 8 additions & 0 deletions src/pygpt_net/core/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,14 @@ def prepare_client_args(
args["api_key"] = cfg.get('api_key_edenai', "")
args["base_url"] = cfg.get('api_endpoint_edenai', "")
self.window.core.debug.info("[api] Using client: Eden AI API")
elif model.provider == "atlas_cloud":
args["api_key"] = cfg.get('api_key_atlas_cloud', "") or os.environ.get(
"ATLASCLOUD_API_KEY", ""
)
args["base_url"] = cfg.get('api_endpoint_atlas_cloud', "") or os.environ.get(
"ATLASCLOUD_API_BASE", "https://api.atlascloud.ai/v1"
)
self.window.core.debug.info("[api] Using client: Atlas Cloud API")
elif model.provider == "ollama":
args["api_key"] = "ollama"
args["base_url"] = self.window.core.models.ollama.get_base_url() + "/v1"
Expand Down
1 change: 1 addition & 0 deletions src/pygpt_net/core/types/openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"open_router",
"forge",
"edenai",
"atlas_cloud",
]

OPENAI_DISABLE_TOOLS = [
Expand Down
2 changes: 2 additions & 0 deletions src/pygpt_net/data/config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"api_azure_version": "2023-07-01-preview",
"api_endpoint": "https://api.openai.com/v1",
"api_endpoint_anthropic": "https://api.anthropic.com/v1",
"api_endpoint_atlas_cloud": "https://api.atlascloud.ai/v1",
"api_endpoint_deepseek": "https://api.deepseek.com/v1",
"api_endpoint_edenai": "https://api.edenai.run/v3",
"api_endpoint_forge": "https://api.forge.tensorblock.co/v1",
Expand All @@ -85,6 +86,7 @@
"api_endpoint_xai": "https://api.x.ai/v1",
"api_key": "",
"api_key_anthropic": "",
"api_key_atlas_cloud": "",
"api_key_deepseek": "",
"api_key_edenai": "",
"api_key_forge": "",
Expand Down
37 changes: 37 additions & 0 deletions src/pygpt_net/data/config/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,43 @@
"advanced": false,
"tab": "Eden AI"
},
"api_key_atlas_cloud": {
"section": "api_keys",
"type": "text",
"slider": false,
"label": "settings.api_key.atlas_cloud",
"description": "settings.api_key.atlas_cloud.desc",
"value": "",
"min": null,
"max": null,
"multiplier": null,
"step": null,
"extra": {
"bold": true
},
"urls": {
"API Keys": "https://www.atlascloud.ai/console/api-keys"
},
"secret": true,
"persist": true,
"advanced": false,
"tab": "Atlas Cloud"
},
"api_endpoint_atlas_cloud": {
"section": "api_keys",
"type": "text",
"slider": false,
"label": "settings.api_endpoint_atlas_cloud",
"description": "settings.api_endpoint_atlas_cloud.desc",
"value": "https://api.atlascloud.ai/v1",
"min": null,
"max": null,
"multiplier": null,
"step": null,
"secret": false,
"advanced": false,
"tab": "Atlas Cloud"
},
"api_custom_providers": {
"section": "custom_providers",
"type": "dict",
Expand Down
5 changes: 5 additions & 0 deletions src/pygpt_net/data/locale/locale.en.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1296,6 +1296,8 @@ settings.api_endpoint_open_router = API Endpoint
settings.api_endpoint_open_router.desc = OpenRouter API endpoint URL, default: https://openrouter.ai/api/v1
settings.api_endpoint_edenai = API Endpoint
settings.api_endpoint_edenai.desc = Eden AI API endpoint URL, default: https://api.edenai.run/v3
settings.api_endpoint_atlas_cloud = API Endpoint
settings.api_endpoint_atlas_cloud.desc = Atlas Cloud API endpoint URL, default: https://api.atlascloud.ai/v1
settings.api_endpoint_perplexity = API Endpoint
settings.api_endpoint_perplexity.desc = Perplexity API endpoint URL, default: https://api.perplexity.ai
settings.api_endpoint_xai = API Endpoint
Expand All @@ -1320,6 +1322,8 @@ settings.api_key.open_router = OpenRouter API key
settings.api_key.open_router.desc = Required for the OpenRouter API.
settings.api_key.edenai = Eden AI API key
settings.api_key.edenai.desc = Required for the Eden AI API.
settings.api_key.atlas_cloud = Atlas Cloud API key
settings.api_key.atlas_cloud.desc = Required for the Atlas Cloud API.
settings.api_key.perplexity = Perplexity API key
settings.api_key.perplexity.desc = Required for the Perplexity API.
settings.api_key.voyage = Voyage AI API key
Expand Down Expand Up @@ -1717,6 +1721,7 @@ settings.section.agent.legacy = Legacy
settings.section.api_keys = API Keys
settings.section.api_keys.anthropic = Anthropic
settings.section.api_keys.azure_openai = Azure OpenAI
settings.section.api_keys.atlas_cloud = Atlas Cloud
settings.section.api_keys.eden_ai = Eden AI
settings.section.api_keys.deepseek = DeepSeek
settings.section.api_keys.forge = Forge
Expand Down
57 changes: 57 additions & 0 deletions src/pygpt_net/provider/llms/atlas_cloud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ================================================== #
# This file is a part of PYGPT package #
# Website: https://pygpt.net #
# GitHub: https://github.com/szczyglis-dev/py-gpt #
# MIT License #
# ================================================== #
import os
from typing import Dict, List

from llama_index.core.llms.llm import BaseLLM as LlamaBaseLLM

from pygpt_net.core.types import MODE_LLAMA_INDEX
from pygpt_net.item.model import ModelItem
from pygpt_net.provider.llms.base import BaseLLM


ATLAS_CLOUD_DEFAULT_BASE_URL = "https://api.atlascloud.ai/v1"


class AtlasCloudLLM(BaseLLM):
def __init__(self, *args, **kwargs):
super(AtlasCloudLLM, self).__init__(*args, **kwargs)
self.id = "atlas_cloud"
self.name = "Atlas Cloud"
self.type = [MODE_LLAMA_INDEX]

def _apply_auth(self, args: Dict, window) -> Dict:
if not args.get("api_key"):
args["api_key"] = os.environ.get("ATLASCLOUD_API_KEY") or window.core.config.get(
"api_key_atlas_cloud", ""
)
if not args.get("api_base"):
args["api_base"] = os.environ.get("ATLASCLOUD_API_BASE") or window.core.config.get(
"api_endpoint_atlas_cloud", ""
) or ATLAS_CLOUD_DEFAULT_BASE_URL
return args

def llama(self, window, model: ModelItem, stream: bool = False) -> LlamaBaseLLM:
from llama_index.llms.openai_like import OpenAILike

args = self.parse_args(model.llama_index, window)
args.setdefault("model", model.id)
args = self._apply_auth(args, window)
args.setdefault("is_chat_model", True)
args.setdefault("is_function_calling_model", model.tool_calls)
args = self.inject_llamaindex_http_clients(args, window.core.config)
return OpenAILike(**args)

def get_models(self, window) -> List[Dict]:
client = self.get_client(window)
models_list = client.models.list()
return [
{"id": item.id, "name": item.id}
for item in (models_list.data or [])
]
71 changes: 71 additions & 0 deletions tests/provider/llms/test_llm_atlas_cloud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from types import SimpleNamespace
from unittest.mock import MagicMock, patch

from pygpt_net.item.model import ModelItem
from pygpt_net.provider.llms.atlas_cloud import (
ATLAS_CLOUD_DEFAULT_BASE_URL,
AtlasCloudLLM,
)


def _window():
config = MagicMock()
config.get.side_effect = lambda key, default=None: {
"api_key_atlas_cloud": "CONFIG-KEY",
"api_endpoint_atlas_cloud": ATLAS_CLOUD_DEFAULT_BASE_URL,
}.get(key, default)
return SimpleNamespace(
core=SimpleNamespace(
config=config,
api=SimpleNamespace(openai=MagicMock()),
)
)


def test_llama_uses_atlas_cloud_defaults():
provider = AtlasCloudLLM()
provider.inject_llamaindex_http_clients = MagicMock(side_effect=lambda args, cfg: args)
model = ModelItem("openai/gpt-4.1-mini")
model.tool_calls = True
model.llama_index = {"args": []}

with patch("llama_index.llms.openai_like.OpenAILike", return_value="LLM") as openai_like:
result = provider.llama(_window(), model)

assert result == "LLM"
assert openai_like.call_args.kwargs["model"] == "openai/gpt-4.1-mini"
assert openai_like.call_args.kwargs["api_key"] == "CONFIG-KEY"
assert openai_like.call_args.kwargs["api_base"] == ATLAS_CLOUD_DEFAULT_BASE_URL
assert openai_like.call_args.kwargs["is_chat_model"] is True
assert openai_like.call_args.kwargs["is_function_calling_model"] is True


def test_environment_overrides_empty_config(monkeypatch):
window = _window()
window.core.config.get.side_effect = lambda key, default=None: ""
monkeypatch.setenv("ATLASCLOUD_API_KEY", "ENV-KEY")
monkeypatch.setenv("ATLASCLOUD_API_BASE", "https://atlas.example/v1")

args = AtlasCloudLLM()._apply_auth({}, window)

assert args == {
"api_key": "ENV-KEY",
"api_base": "https://atlas.example/v1",
}


def test_get_models_uses_openai_compatible_endpoint():
provider = AtlasCloudLLM()
client = MagicMock()
client.models.list.return_value = SimpleNamespace(
data=[SimpleNamespace(id="openai/gpt-4.1-mini")]
)
provider.get_client = MagicMock(return_value=client)

assert provider.get_models(_window()) == [
{"id": "openai/gpt-4.1-mini", "name": "openai/gpt-4.1-mini"}
]
client.models.list.assert_called_once_with()