From a880ea2a64958455887d0bca5b5688b734cb13ff Mon Sep 17 00:00:00 2001 From: binyangzhu000-sudo <224954946+binyangzhu000-sudo@users.noreply.github.com> Date: Fri, 23 Oct 2026 17:42:19 +0800 Subject: [PATCH] feat(providers): add Atlas Cloud as an OpenAI-compatible gateway provider Register `atlascloud` in the provider registry, mirroring the existing Novita / SiliconFlow gateway entries: OpenAI-compatible backend, `ATLASCLOUD_API_KEY` env var, default base `https://api.atlascloud.ai/v1`, and base-URL detection by the `atlascloud` keyword. Add a provider test modelled on the Novita one. Co-Authored-By: Claude Sonnet 5.5 Signed-off-by: binyangzhu000-sudo <224954946+binyangzhu000-sudo@users.noreply.github.com> --- App/memmy-agent/src/providers/registry.ts | 9 ++ .../providers/atlascloud-provider.test.ts | 95 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 App/memmy-agent/tests/providers/atlascloud-provider.test.ts diff --git a/App/memmy-agent/src/providers/registry.ts b/App/memmy-agent/src/providers/registry.ts index fe6656a27..cf01cf41e 100644 --- a/App/memmy-agent/src/providers/registry.ts +++ b/App/memmy-agent/src/providers/registry.ts @@ -226,6 +226,15 @@ export const PROVIDERS: ProviderSpec[] = [ detectByBaseKeyword: "novita", defaultApiBase: "https://api.novita.ai/openai", }), + new ProviderSpec({ + name: "atlascloud", + keywords: ["atlascloud"], + envKey: "ATLASCLOUD_API_KEY", + displayName: "Atlas Cloud", + isGateway: true, + detectByBaseKeyword: "atlascloud", + defaultApiBase: "https://api.atlascloud.ai/v1", + }), new ProviderSpec({ name: "volcengine", keywords: ["volcengine", "volces", "ark"], diff --git a/App/memmy-agent/tests/providers/atlascloud-provider.test.ts b/App/memmy-agent/tests/providers/atlascloud-provider.test.ts new file mode 100644 index 000000000..be00e7799 --- /dev/null +++ b/App/memmy-agent/tests/providers/atlascloud-provider.test.ts @@ -0,0 +1,95 @@ +import { describe, expect, it } from "vitest"; +import { Config, ProvidersConfig } from "../../src/config/schema.js"; +import { OpenAICompatProvider } from "../../src/providers/openai-compat-provider.js"; +import { PROVIDERS, findByName } from "../../src/providers/registry.js"; + +describe("Atlas Cloud provider", () => { + it("has a Atlas Cloud config field", () => { + const config = new ProvidersConfig(); + + expect(config.atlascloud).toBeDefined(); + }); + + it("registers Atlas Cloud as an OpenAI-compatible gateway", () => { + const specs = Object.fromEntries(PROVIDERS.map((spec) => [spec.name, spec])); + + expect(specs.atlascloud).toBeDefined(); + expect(specs.atlascloud.backend).toBe("openai_compat"); + expect(specs.atlascloud.envKey).toBe("ATLASCLOUD_API_KEY"); + expect(specs.atlascloud.displayName).toBe("Atlas Cloud"); + expect(specs.atlascloud.isGateway).toBe(true); + expect(specs.atlascloud.detectByBaseKeyword).toBe("atlascloud"); + expect(specs.atlascloud.defaultApiBase).toBe("https://api.atlascloud.ai/v1"); + expect(specs.atlascloud.stripModelPrefix).toBe(false); + }); + + it("finds Atlas Cloud by provider name", () => { + const spec = findByName("atlascloud"); + + expect(spec).not.toBeNull(); + expect(spec?.name).toBe("atlascloud"); + }); + + it("uses the default API base when Atlas Cloud is forced", () => { + const config = Config.fromObject({ + providers: { + atlascloud: { + apiKey: "atlascloud-key", + }, + }, + agents: { + defaults: { + model: "deepseek-ai/deepseek-v4-flash", + provider: "atlascloud", + }, + }, + }); + + expect(config.getProviderName("deepseek-ai/deepseek-v4-flash")).toBe("atlascloud"); + expect(config.getApiKey("deepseek-ai/deepseek-v4-flash")).toBe("atlascloud-key"); + expect(config.getApiBase("deepseek-ai/deepseek-v4-flash")).toBe("https://api.atlascloud.ai/v1"); + }); + + it("routes unprefixed models through the Atlas Cloud gateway when configured", () => { + const config = Config.fromObject({ + providers: { + atlascloud: { + apiKey: "atlascloud-key", + }, + }, + agents: { + defaults: { + model: "deepseek-ai/deepseek-v4-flash", + }, + }, + }); + + expect(config.getProviderName("deepseek-ai/deepseek-v4-flash")).toBe("atlascloud"); + expect(config.getApiKey("deepseek-ai/deepseek-v4-flash")).toBe("atlascloud-key"); + expect(config.getApiBase("deepseek-ai/deepseek-v4-flash")).toBe("https://api.atlascloud.ai/v1"); + }); + + it("preserves the Atlas Cloud model API id in OpenAI-compatible kwargs", () => { + const spec = findByName("atlascloud"); + const provider = new OpenAICompatProvider( + "atlascloud-key", + null, + "deepseek-ai/deepseek-v4-flash", + spec, + ); + + const kwargs = provider.buildKwargs({ + messages: [{ role: "user", content: "hi" }], + tools: null, + model: "deepseek-ai/deepseek-v4-flash", + maxTokens: 1024, + temperature: 0.7, + reasoningEffort: null, + toolChoice: null, + }); + + expect(kwargs.model).toBe("deepseek-ai/deepseek-v4-flash"); + expect(kwargs.max_tokens).toBe(1024); + expect(kwargs).not.toHaveProperty("max_completion_tokens"); + }); +});