Skip to content

Commit 60aa95a

Browse files
committed
fix(core): update API URL handling and improve request URL construction
1 parent e10c90c commit 60aa95a

File tree

7 files changed

+39
-46
lines changed

7 files changed

+39
-46
lines changed

packages/openai-compatible/src/config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ export const Config: Schema<Config> = Schema.intersect([
5151
Schema.string().role('secret').required(),
5252
Schema.string()
5353
.description('请求 OpenAI API 的地址')
54-
.default('https://api.openai.com/v1')
54+
.default('https://api.openai.com/v1/')
5555
])
5656
)
5757
.description('请求地址的 API Key 和请求地址列表')
58-
.default([['', 'https://api.openai.com/v1']]),
58+
.default([['', 'https://api.openai.com/v1/']]),
5959
additionCookies: Schema.array(
6060
Schema.tuple([
6161
Schema.string().description('Cookie 名称'),

packages/openai-compatible/src/embedding-model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export class OpenAICompatibleEmbeddingModel implements EmbeddingModel<string> {
5454
let providerConfig = this.providerConfig
5555
const generateResponse = async () => {
5656
const response = await this.fetch(
57-
providerConfig.url('embeddings'),
57+
providerConfig.url('/embeddings'),
5858
{
5959
method: 'POST',
6060
headers: Object.assign(

packages/openai-compatible/src/get-latest-models.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export async function getLatestModels(
3232
}).then((res) => res.text())
3333

3434
try {
35-
const models = modelsSchema.parse(JSON.parse(resposeText)).data
35+
const models = listModelSchema.parse(JSON.parse(resposeText)).data
3636

3737
return models
3838
.filter(
@@ -68,7 +68,7 @@ export async function getLatestModels(
6868
retries: currentConfig.config.maxRetries,
6969
maxTimeout: currentConfig.config.timeout,
7070
onRetry(error, attempt, retryInfo) {
71-
console.log(`Retry attempt ${attempt} failed with error: ${error}`)
71+
console.error(`Retry attempt ${attempt} failed with error`, error)
7272
currentConfig.disable()
7373
currentConfig = pool.getProvider()
7474
}
@@ -77,13 +77,13 @@ export async function getLatestModels(
7777
return retry(currentConfig.config)
7878
}
7979

80-
const modelsSchema = z.object({
81-
object: z.literal('list'),
80+
const listModelSchema = z.object({
81+
object: z.literal('list').optional(),
8282
data: z.array(
8383
z.object({
8484
id: z.string(),
85-
object: z.literal('model'),
86-
owned_by: z.string()
85+
object: z.string().optional(),
86+
owned_by: z.string().optional()
8787
})
8888
)
8989
})

packages/openai-compatible/src/index.ts

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Context } from 'cordis'
22
import { Config } from './config.ts'
33
import { createOpenAICompatibleProvider } from './provider.ts'
44
import type {} from '@cordisjs/plugin-http'
5+
import { buildRequestUrl } from './utils.ts'
56

67
export * from './provider.ts'
78
export * from './types.ts'
@@ -37,31 +38,16 @@ export function apply(ctx: Context, config: Config) {
3738
return response.data
3839
},
3940
'weighted-random',
40-
config.apiKeys.map(([apiKey, url]) => ({
41+
config.apiKeys.map(([apiKey, baseURL]) => ({
4142
apiKey,
42-
baseURL: url,
43+
baseURL,
4344
headers: {
4445
Authorization: `Bearer ${apiKey}`,
4546
Cookies: config.additionCookies
4647
.map(([key, value]) => `${key}=${value}`)
4748
.join('; ')
4849
},
49-
url: (subPath: string) => {
50-
// check has v1
51-
if (url.endsWith('/v1')) {
52-
return url + '/' + subPath
53-
} else if (url.endsWith('/v1/')) {
54-
return url + subPath
55-
}
56-
57-
// check has /
58-
if (url.endsWith('/')) {
59-
return url + subPath
60-
}
61-
62-
// add /v1
63-
return url + '/v1/' + subPath
64-
},
50+
url: (subPath: string) => buildRequestUrl(baseURL, subPath),
6551
timeout: 300000
6652
}))
6753
)

packages/openai-compatible/src/language-model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export class OpenAICompatibleLanguageModel implements LanguageModel {
111111
let providerConfig = this.providerConfig
112112
const generateResponse = async () => {
113113
const response = await this.fetch(
114-
providerConfig.url('chat/completions'),
114+
providerConfig.url('/chat/completions'),
115115
{
116116
method: 'POST',
117117
headers: Object.assign(

packages/openai-compatible/src/provider.ts

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { defaultOpenAIModels } from './types.ts'
1515
import { getLatestModels } from './get-latest-models.ts'
1616
import { OpenAICompatibleLanguageModel } from './language-model.ts'
1717
import { OpenAICompatibleEmbeddingModel } from './embedding-model.ts'
18+
import { buildRequestUrl } from './utils.ts'
1819

1920
export function createOpenAICompatibleProvider(
2021
name: string | 'openai-compatible',
@@ -112,29 +113,14 @@ export function createOpenAICompatibleProvider(
112113
provider.concurrencyLimiter = createConcurrencyLimiter(10)
113114

114115
if (process.env.OPENAI_COMPATIBLE_API_KEY) {
115-
const url = process.env.OPENAI_COMPATIBLE_API_URL!
116+
const baseURL = process.env.OPENAI_COMPATIBLE_API_URL!
116117
configPool.addProvider({
117118
apiKey: process.env.OPENAI_COMPATIBLE_API_KEY,
118-
baseURL: url,
119+
baseURL,
119120
headers: {
120121
Authorization: `Bearer ${process.env.OPENAI_COMPATIBLE_API_KEY}`
121122
},
122-
url: (subPath: string) => {
123-
// check has v1
124-
if (url.endsWith('/v1')) {
125-
return url + '/' + subPath
126-
} else if (url.endsWith('/v1/')) {
127-
return url + subPath
128-
}
129-
130-
// check has /
131-
if (url.endsWith('/')) {
132-
return url + subPath
133-
}
134-
135-
// add /v1
136-
return url + '/v1/' + subPath
137-
},
123+
url: (subPath: string) => buildRequestUrl(baseURL, subPath),
138124
timeout: 300000
139125
})
140126
}

packages/openai-compatible/src/utils.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,24 @@ export function isParsableJson(obj: string) {
3939
return false
4040
}
4141
}
42+
43+
export function buildRequestUrl(baseUrl: string, subPath: string) {
44+
const startWithSlash = subPath.startsWith('/')
45+
46+
const subPathWithoutSlash = !startWithSlash ? subPath : subPath.substring(1)
47+
48+
// check has v1
49+
if (baseUrl.endsWith('/v1')) {
50+
return baseUrl + '/' + subPathWithoutSlash
51+
} else if (baseUrl.endsWith('/v1/')) {
52+
return baseUrl + subPathWithoutSlash
53+
}
54+
55+
// check has /
56+
if (baseUrl.endsWith('/')) {
57+
return baseUrl + subPathWithoutSlash
58+
}
59+
60+
// add /v1
61+
return baseUrl + '/v1/' + subPathWithoutSlash
62+
}

0 commit comments

Comments
 (0)