fix formatApiHost (#10236)

* Add .codebuddy and .zed to .gitignore and fix formatApiHost

Prevent formatApiHost from processing undefined/empty host values and
ignore editor-specific directories

* Refactor reasoning tag selection logic for providers

Move gpt-oss model handling from aws-bedrock case to openai case and
consolidate tag selection logic into a single if-else chain.

* Extract reasoning tag name into helper function

* fix test

* Replace array indexing with named object properties for reasoning tags

Improves code readability by using descriptive property names instead of
magic array indices when selecting reasoning tag names by model type.

* Move host validation to start of formatApiHost
This commit is contained in:
SuYao 2025-09-18 15:43:07 +08:00 committed by GitHub
parent ca597b9b9b
commit 1d0fc26025
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 19 additions and 10 deletions

2
.gitignore vendored
View File

@ -54,6 +54,8 @@ local
.qwen/* .qwen/*
.trae/* .trae/*
.claude-code-router/* .claude-code-router/*
.codebuddy/*
.zed/*
CLAUDE.local.md CLAUDE.local.md
# vitest # vitest

View File

@ -140,7 +140,17 @@ export function buildAiSdkMiddlewares(config: AiSdkMiddlewareConfig): LanguageMo
return builder.build() return builder.build()
} }
const tagNameArray = ['think', 'thought', 'reasoning'] const tagName = {
reasoning: 'reasoning',
think: 'think',
thought: 'thought'
}
function getReasoningTagName(modelId: string | undefined): string {
if (modelId?.includes('gpt-oss')) return tagName.reasoning
if (modelId?.includes('gemini')) return tagName.thought
return tagName.think
}
/** /**
* provider特定的中间件 * provider特定的中间件
@ -156,7 +166,7 @@ function addProviderSpecificMiddlewares(builder: AiSdkMiddlewareBuilder, config:
case 'openai': case 'openai':
case 'azure-openai': { case 'azure-openai': {
if (config.enableReasoning) { if (config.enableReasoning) {
const tagName = config.model?.id.includes('gemini') ? tagNameArray[1] : tagNameArray[0] const tagName = getReasoningTagName(config.model?.id.toLowerCase())
builder.add({ builder.add({
name: 'thinking-tag-extraction', name: 'thinking-tag-extraction',
middleware: extractReasoningMiddleware({ tagName }) middleware: extractReasoningMiddleware({ tagName })
@ -168,13 +178,6 @@ function addProviderSpecificMiddlewares(builder: AiSdkMiddlewareBuilder, config:
// Gemini特定中间件 // Gemini特定中间件
break break
case 'aws-bedrock': { case 'aws-bedrock': {
if (config.model?.id.includes('gpt-oss')) {
const tagName = tagNameArray[2]
builder.add({
name: 'thinking-tag-extraction',
middleware: extractReasoningMiddleware({ tagName })
})
}
break break
} }
default: default:

View File

@ -25,7 +25,7 @@ describe('api', () => {
}) })
it('should handle empty string gracefully', () => { it('should handle empty string gracefully', () => {
expect(formatApiHost('')).toBe('/v1/') expect(formatApiHost('')).toBe('')
}) })
}) })

View File

@ -20,6 +20,10 @@ export function formatApiKeys(value: string): string {
* @returns {string} API * @returns {string} API
*/ */
export function formatApiHost(host: string, apiVersion: string = 'v1'): string { export function formatApiHost(host: string, apiVersion: string = 'v1'): string {
if (!host) {
return ''
}
const forceUseOriginalHost = () => { const forceUseOriginalHost = () => {
if (host.endsWith('/')) { if (host.endsWith('/')) {
return true return true