From 3f4011a6e8195f880ff469054c581f0dcb8f579c Mon Sep 17 00:00:00 2001 From: Lee Penkman Date: Sat, 18 Jul 2026 07:05:51 +1200 Subject: [PATCH] feat(stage-ui): add OpenPaths provider (#1980) Co-authored-by-agent: Claude Opus 4.8 (1M context) --- packages/i18n/src/locales/en/settings.yaml | 3 ++ .../src/libs/providers/providers/index.ts | 1 + .../providers/providers/openpaths/index.ts | 53 +++++++++++++++++++ .../src/libs/providers/source-metadata.ts | 1 + 4 files changed, 58 insertions(+) create mode 100644 packages/stage-ui/src/libs/providers/providers/openpaths/index.ts diff --git a/packages/i18n/src/locales/en/settings.yaml b/packages/i18n/src/locales/en/settings.yaml index 7a1867c94..6ef389755 100644 --- a/packages/i18n/src/locales/en/settings.yaml +++ b/packages/i18n/src/locales/en/settings.yaml @@ -1361,6 +1361,9 @@ pages: n1n: description: n1n.ai - High-performance AI API provider. title: n1n + openpaths: + description: openpaths.io + title: OpenPaths openrouter: description: openrouter.ai title: OpenRouter diff --git a/packages/stage-ui/src/libs/providers/providers/index.ts b/packages/stage-ui/src/libs/providers/providers/index.ts index 8e519fdab..bcebf2b79 100644 --- a/packages/stage-ui/src/libs/providers/providers/index.ts +++ b/packages/stage-ui/src/libs/providers/providers/index.ts @@ -9,6 +9,7 @@ import './volcengine-coding-plan' import './byteplus' import './byteplus-coding-plan' import './n1n' +import './openpaths' import './openrouter-ai' import './nvidia' import './groq' diff --git a/packages/stage-ui/src/libs/providers/providers/openpaths/index.ts b/packages/stage-ui/src/libs/providers/providers/openpaths/index.ts new file mode 100644 index 000000000..1990b1a0f --- /dev/null +++ b/packages/stage-ui/src/libs/providers/providers/openpaths/index.ts @@ -0,0 +1,53 @@ +import { createOpenAI } from '@xsai-ext/providers/create' +import { z } from 'zod' + +import { ProviderValidationCheck } from '../../types' +import { createOpenAICompatibleValidators } from '../../validators' +import { defineProvider } from '../registry' + +const openPathsConfigSchema = z.object({ + apiKey: z + .string('API Key'), + baseUrl: z + .string('Base URL') + .optional() + .default('https://openpaths.io/v1'), +}) + +type OpenPathsConfig = z.input + +export const providerOpenPaths = defineProvider({ + id: 'openpaths', + name: 'OpenPaths', + nameLocalize: ({ t }) => t('settings.pages.providers.provider.openpaths.title'), + description: 'openpaths.io', + descriptionLocalize: ({ t }) => t('settings.pages.providers.provider.openpaths.description'), + tasks: ['chat'], + icon: 'i-lobe-icons:openai', + + createProviderConfig: ({ t }) => openPathsConfigSchema.extend({ + apiKey: openPathsConfigSchema.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: openPathsConfigSchema.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/source-metadata.ts b/packages/stage-ui/src/libs/providers/source-metadata.ts index c4e08cd2f..ae697ec5d 100644 --- a/packages/stage-ui/src/libs/providers/source-metadata.ts +++ b/packages/stage-ui/src/libs/providers/source-metadata.ts @@ -87,6 +87,7 @@ const providerSourceMetadataById = { 'openai-compatible': false, 'openai-compatible-audio-speech': false, 'openai-compatible-audio-transcription': false, + 'openpaths': paidCloud, 'openrouter-ai': paidCloud, 'openrouter-audio-speech': paidCloud, 'perplexity-ai': paidCloud,