feat(costrict): 根据模型列表动态设置 max_tokens 参数
从 /ai-gateway/api/v1/models 返回的模型信息中读取 maxTokensKey 和 maxTokens 字段,发送请求时动态注入对应参数名和参数值。 maxTokensKey 缺失时默认使用 max_tokens,maxTokens 无值时不传该参数。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
d9bc165378
commit
1970c698ea
|
|
@ -33,6 +33,7 @@ import { resolveCoStrictModel } from './modelMapping.js'
|
||||||
import { getCoStrictBaseURL } from './auth.js'
|
import { getCoStrictBaseURL } from './auth.js'
|
||||||
import { loadCoStrictCredentials } from './credentials.js'
|
import { loadCoStrictCredentials } from './credentials.js'
|
||||||
import { isOpenAIThinkingEnabled } from '../../services/api/openai/requestBody.js'
|
import { isOpenAIThinkingEnabled } from '../../services/api/openai/requestBody.js'
|
||||||
|
import { fetchCoStrictModels } from './models.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CoStrict 查询路径
|
* CoStrict 查询路径
|
||||||
|
|
@ -57,10 +58,28 @@ export async function* queryModelCoStrict(
|
||||||
const baseUrl = getCoStrictBaseURL(creds?.base_url)
|
const baseUrl = getCoStrictBaseURL(creds?.base_url)
|
||||||
const chatBaseURL = `${baseUrl}/chat-rag/api/v1`
|
const chatBaseURL = `${baseUrl}/chat-rag/api/v1`
|
||||||
|
|
||||||
// 3. 规范化消息
|
// 3. 从模型列表获取 maxTokens 相关参数
|
||||||
|
let maxTokensParamKey: string = 'max_tokens'
|
||||||
|
let maxTokensValue: number | undefined
|
||||||
|
if (creds?.access_token) {
|
||||||
|
try {
|
||||||
|
const modelList = await fetchCoStrictModels(baseUrl, creds.access_token)
|
||||||
|
const modelInfo = modelList.find(m => m.id === costrictModel)
|
||||||
|
if (modelInfo) {
|
||||||
|
maxTokensParamKey = modelInfo.maxTokensKey || 'max_tokens'
|
||||||
|
if (modelInfo.maxTokens != null) {
|
||||||
|
maxTokensValue = modelInfo.maxTokens
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// 获取模型列表失败,使用默认值
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 规范化消息
|
||||||
const messagesForAPI = normalizeMessagesForAPI(messages, tools)
|
const messagesForAPI = normalizeMessagesForAPI(messages, tools)
|
||||||
|
|
||||||
// 4. 构建工具 schema
|
// 5. 构建工具 schema
|
||||||
const toolSchemas = await Promise.all(
|
const toolSchemas = await Promise.all(
|
||||||
tools.map(tool =>
|
tools.map(tool =>
|
||||||
toolToAPISchema(tool, {
|
toolToAPISchema(tool, {
|
||||||
|
|
@ -81,7 +100,7 @@ export async function* queryModelCoStrict(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
// 5. 转换为 OpenAI 格式
|
// 6. 转换为 OpenAI 格式
|
||||||
// 根据模型名称自动检测是否启用thinking模式
|
// 根据模型名称自动检测是否启用thinking模式
|
||||||
const enableThinking = isOpenAIThinkingEnabled(costrictModel)
|
const enableThinking = isOpenAIThinkingEnabled(costrictModel)
|
||||||
const openaiMessages = anthropicMessagesToOpenAI(
|
const openaiMessages = anthropicMessagesToOpenAI(
|
||||||
|
|
@ -92,7 +111,7 @@ export async function* queryModelCoStrict(
|
||||||
const openaiTools = anthropicToolsToOpenAI(standardTools)
|
const openaiTools = anthropicToolsToOpenAI(standardTools)
|
||||||
const openaiToolChoice = anthropicToolChoiceToOpenAI(options.toolChoice)
|
const openaiToolChoice = anthropicToolChoiceToOpenAI(options.toolChoice)
|
||||||
|
|
||||||
// 6. 创建专用的 CoStrict OpenAI 客户端(不缓存,每次使用新的 fetch)
|
// 7. 创建专用的 CoStrict OpenAI 客户端(不缓存,每次使用新的 fetch)
|
||||||
const costrictFetch = createCoStrictFetch()
|
const costrictFetch = createCoStrictFetch()
|
||||||
const client = new OpenAI({
|
const client = new OpenAI({
|
||||||
apiKey: 'costrict-managed', // 实际 token 由 createCoStrictFetch 注入
|
apiKey: 'costrict-managed', // 实际 token 由 createCoStrictFetch 注入
|
||||||
|
|
@ -111,28 +130,32 @@ export async function* queryModelCoStrict(
|
||||||
`[CoStrict] model=${costrictModel}, baseURL=${chatBaseURL}, messages=${openaiMessages.length}, tools=${openaiTools.length}`,
|
`[CoStrict] model=${costrictModel}, baseURL=${chatBaseURL}, messages=${openaiMessages.length}, tools=${openaiTools.length}`,
|
||||||
)
|
)
|
||||||
|
|
||||||
// 7. 调用 API(流式)
|
// 8. 调用 API(流式)
|
||||||
|
const requestBody: Record<string, unknown> = {
|
||||||
|
model: costrictModel,
|
||||||
|
messages: openaiMessages,
|
||||||
|
...(openaiTools.length > 0 && {
|
||||||
|
tools: openaiTools,
|
||||||
|
...(openaiToolChoice && {
|
||||||
|
tool_choice:
|
||||||
|
openaiToolChoice as OpenAI.Chat.Completions.ChatCompletionToolChoiceOption,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
stream: true,
|
||||||
|
stream_options: { include_usage: true },
|
||||||
|
...(options.temperatureOverride !== undefined && {
|
||||||
|
temperature: options.temperatureOverride,
|
||||||
|
}),
|
||||||
|
...(maxTokensValue != null && {
|
||||||
|
[maxTokensParamKey]: maxTokensValue,
|
||||||
|
}),
|
||||||
|
}
|
||||||
const stream = await client.chat.completions.create(
|
const stream = await client.chat.completions.create(
|
||||||
{
|
requestBody as unknown as OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming,
|
||||||
model: costrictModel,
|
|
||||||
messages: openaiMessages,
|
|
||||||
...(openaiTools.length > 0 && {
|
|
||||||
tools: openaiTools,
|
|
||||||
...(openaiToolChoice && {
|
|
||||||
tool_choice:
|
|
||||||
openaiToolChoice as OpenAI.Chat.Completions.ChatCompletionToolChoiceOption,
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
stream: true,
|
|
||||||
stream_options: { include_usage: true },
|
|
||||||
...(options.temperatureOverride !== undefined && {
|
|
||||||
temperature: options.temperatureOverride,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{ signal },
|
{ signal },
|
||||||
)
|
)
|
||||||
|
|
||||||
// 8. 转换流并 yield 事件
|
// 9. 转换流并 yield 事件
|
||||||
const adaptedStream = adaptOpenAIStreamToAnthropic(stream, costrictModel)
|
const adaptedStream = adaptOpenAIStreamToAnthropic(stream, costrictModel)
|
||||||
|
|
||||||
const contentBlocks: Record<number, any> = {}
|
const contentBlocks: Record<number, any> = {}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ export interface CoStrictModel {
|
||||||
supportsImages?: boolean
|
supportsImages?: boolean
|
||||||
contextWindow?: number
|
contextWindow?: number
|
||||||
maxTokens?: number
|
maxTokens?: number
|
||||||
|
maxTokensKey?: string
|
||||||
creditConsumption?: number
|
creditConsumption?: number
|
||||||
creditDiscount?: number
|
creditDiscount?: number
|
||||||
[key: string]: any
|
[key: string]: any
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user