From e5385e90da95bfe0e13a7dfc1fa85ad837ee6701 Mon Sep 17 00:00:00 2001 From: nb213 Date: Sat, 18 Jul 2026 03:03:54 +0800 Subject: [PATCH] feat(stage-ui): add Atlas Cloud provider definition (#2076) --- Co-authored-by: binyangzhu000-sudo <224954946+binyangzhu000-sudo@users.noreply.github.com> --- .../providers/providers/atlascloud/index.ts | 56 +++++++++++++++++++ .../src/libs/providers/providers/index.ts | 1 + .../src/libs/providers/source-metadata.ts | 1 + .../inference-service-providers.test.ts | 22 ++++++++ 4 files changed, 80 insertions(+) create mode 100644 packages/stage-ui/src/libs/providers/providers/atlascloud/index.ts diff --git a/packages/stage-ui/src/libs/providers/providers/atlascloud/index.ts b/packages/stage-ui/src/libs/providers/providers/atlascloud/index.ts new file mode 100644 index 000000000..8b750ff79 --- /dev/null +++ b/packages/stage-ui/src/libs/providers/providers/atlascloud/index.ts @@ -0,0 +1,56 @@ +import { createOpenAI } from '@xsai-ext/providers/create' +import { z } from 'zod' + +import { ProviderValidationCheck } from '../../types' +import { createOpenAICompatibleValidators } from '../../validators' +import { defineProvider } from '../registry' + +export const ATLASCLOUD_DEFAULT_BASE_URL = 'https://api.atlascloud.ai/v1' + +const atlasCloudConfigSchema = z.object({ + apiKey: z + .string('API Key'), + baseUrl: z + .string('Base URL') + .optional() + .default(ATLASCLOUD_DEFAULT_BASE_URL), +}) + +type AtlasCloudConfig = z.input + +export const providerAtlasCloud = defineProvider({ + id: 'atlascloud', + order: 5, + name: 'Atlas Cloud', + nameLocalize: () => 'Atlas Cloud', + description: 'api.atlascloud.ai', + descriptionLocalize: () => 'api.atlascloud.ai', + tasks: ['chat'], + icon: 'i-lobe-icons:openai', + + createProviderConfig: ({ t }) => atlasCloudConfigSchema.extend({ + apiKey: atlasCloudConfigSchema.shape.apiKey.meta({ + labelLocalized: t('settings.pages.providers.catalog.edit.config.common.fields.field.api-key.label'), + descriptionLocalized: t('settings.pages.providers.catalog.edit.config.common.fields.field.api-key.description'), + placeholderLocalized: t('settings.pages.providers.catalog.edit.config.common.fields.field.api-key.placeholder'), + type: 'password', + }), + baseUrl: atlasCloudConfigSchema.shape.baseUrl.meta({ + labelLocalized: t('settings.pages.providers.catalog.edit.config.common.fields.field.base-url.label'), + descriptionLocalized: t('settings.pages.providers.catalog.edit.config.common.fields.field.base-url.description'), + placeholderLocalized: t('settings.pages.providers.catalog.edit.config.common.fields.field.base-url.placeholder'), + }), + }), + createProvider(config) { + return createOpenAI(config.apiKey, config.baseUrl) + }, + + validationRequiredWhen(config) { + return !!config.apiKey?.trim() + }, + validators: { + ...createOpenAICompatibleValidators({ + checks: [ProviderValidationCheck.Connectivity, ProviderValidationCheck.ModelList, ProviderValidationCheck.ChatCompletions], + }), + }, +}) diff --git a/packages/stage-ui/src/libs/providers/providers/index.ts b/packages/stage-ui/src/libs/providers/providers/index.ts index 52ae97eb0..8e519fdab 100644 --- a/packages/stage-ui/src/libs/providers/providers/index.ts +++ b/packages/stage-ui/src/libs/providers/providers/index.ts @@ -4,6 +4,7 @@ import './aihubmix' import './lm-studio' import './azure-openai' import './openai-compatible' +import './atlascloud' import './volcengine-coding-plan' import './byteplus' import './byteplus-coding-plan' diff --git a/packages/stage-ui/src/libs/providers/source-metadata.ts b/packages/stage-ui/src/libs/providers/source-metadata.ts index e925a3f91..c4e08cd2f 100644 --- a/packages/stage-ui/src/libs/providers/source-metadata.ts +++ b/packages/stage-ui/src/libs/providers/source-metadata.ts @@ -41,6 +41,7 @@ const providerSourceMetadataById = { 'anthropic': paidCloud, 'app-local-audio-speech': freeLocal, 'app-local-audio-transcription': freeLocal, + 'atlascloud': paidCloud, 'azure-ai-foundry': paidCloud, 'azure-openai': paidCloud, 'browser-local-audio-speech': freeLocal, diff --git a/packages/stage-ui/src/services/inference-service-providers.test.ts b/packages/stage-ui/src/services/inference-service-providers.test.ts index f75a48993..122a036d8 100644 --- a/packages/stage-ui/src/services/inference-service-providers.test.ts +++ b/packages/stage-ui/src/services/inference-service-providers.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it, vi } from 'vitest' +import { ATLASCLOUD_DEFAULT_BASE_URL, providerAtlasCloud } from '../libs/providers/providers/atlascloud' import { providerOpenAICompatible } from '../libs/providers/providers/openai-compatible' import { inferenceServiceProvidersService } from './inference-service-providers' @@ -23,6 +24,27 @@ describe('services inference-service-providers', () => { expect(provider.validationBypassed).toBe(false) }) + /** + * @example + * const provider = inferenceServiceProvidersService.buildLocal('atlascloud', { apiKey: '...' }) + */ + it('lists Atlas Cloud as a built-in OpenAI-compatible provider', () => { + const definitions = inferenceServiceProvidersService.listDefinitions() + const definition = definitions.find(definition => definition.id === providerAtlasCloud.id) + const schema = providerAtlasCloud.createProviderConfig({ t: ((key: string) => key) as any }) + + expect(definition?.name).toBe('Atlas Cloud') + expect(schema.parse({ apiKey: 'test-key' })).toEqual({ + apiKey: 'test-key', + baseUrl: ATLASCLOUD_DEFAULT_BASE_URL, + }) + expect(inferenceServiceProvidersService.buildLocal(providerAtlasCloud.id, { apiKey: 'test-key' })).toEqual(expect.objectContaining({ + definitionId: providerAtlasCloud.id, + name: 'Atlas Cloud', + config: { apiKey: 'test-key' }, + })) + }) + /** * @example * expect(() => inferenceServiceProvidersService.buildLocal('missing')).toThrow()