fix(stage-ui): incorrect DeepSeek provider instance normalized (#2287)
## Summary - show the DeepSeek thinking-mode control for configured provider instances whose id is generated - compare provider configs after filling omitted schema defaults so new defaults like `thinkingMode: auto` do not mark old empty DeepSeek configs as configured ## Tests - `pnpm -rF @proj-airi/stage-ui run test:run src/stores/providers/config-defaults.test.ts src/libs/providers/providers/deepseek/index.test.ts` - `pnpm exec moeru-lint packages/stage-ui/src/stores/providers/config-defaults.ts packages/stage-ui/src/stores/providers/config-defaults.test.ts packages/stage-ui/src/stores/providers/provider.ts packages/stage-pages/src/pages/settings/providers/chat/[providerId].vue` - `git diff --check` Co-authored-by: 冼健聪 <mark.xian@evenrealities.com>
This commit is contained in:
@@ -14,6 +14,7 @@ import { useProviderValidation } from '@proj-airi/stage-ui/composables/use-provi
|
||||
import { getDefinedProvider } from '@proj-airi/stage-ui/libs'
|
||||
import { useConsciousnessStore } from '@proj-airi/stage-ui/stores/modules/consciousness'
|
||||
import { useProviderConfigStore } from '@proj-airi/stage-ui/stores/providers/config'
|
||||
import { useProviderStore } from '@proj-airi/stage-ui/stores/providers/provider'
|
||||
import { FieldCombobox } from '@proj-airi/ui'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { computed } from 'vue'
|
||||
@@ -21,10 +22,12 @@ import { useRoute } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
const providerId = route.params.providerId as string
|
||||
const providerStore = useProviderConfigStore()
|
||||
const providerConfigStore = useProviderConfigStore()
|
||||
const providersStore = useProviderStore()
|
||||
const consciousnessStore = useConsciousnessStore()
|
||||
const { configs: providers } = storeToRefs(providerStore) as { configs: RemovableRef<Record<string, any>> }
|
||||
const { configs: providers } = storeToRefs(providerConfigStore) as { configs: RemovableRef<Record<string, any>> }
|
||||
const { activeProvider } = storeToRefs(consciousnessStore)
|
||||
const providerDefinition = computed(() => providersStore.findProviderDefinition(providerId))
|
||||
|
||||
// Define computed properties for credentials
|
||||
const apiKey = computed({
|
||||
@@ -54,7 +57,7 @@ const thinkingMode = computed({
|
||||
},
|
||||
})
|
||||
|
||||
const supportsDeepSeekThinkingMode = computed(() => providerId === 'deepseek')
|
||||
const supportsDeepSeekThinkingMode = computed(() => providerDefinition.value?.id === 'deepseek')
|
||||
|
||||
// Use the composable to get validation logic and state
|
||||
const {
|
||||
@@ -74,7 +77,7 @@ const {
|
||||
} = useProviderValidation(providerId)
|
||||
|
||||
const apiKeyPlaceholder = computed(() => {
|
||||
const definition = getDefinedProvider(providerId)
|
||||
const definition = providerDefinition.value ?? getDefinedProvider(providerId)
|
||||
if (!definition?.createProviderConfig)
|
||||
return 'sk-...'
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { normalizeProviderConfigDefaults } from './config-defaults'
|
||||
|
||||
describe('normalizeProviderConfigDefaults', () => {
|
||||
it('treats omitted schema defaults as unchanged provider config', () => {
|
||||
expect(normalizeProviderConfigDefaults(
|
||||
{ baseUrl: 'https://api.deepseek.com/' },
|
||||
{ baseUrl: 'https://api.deepseek.com/', thinkingMode: 'auto' },
|
||||
)).toEqual({
|
||||
baseUrl: 'https://api.deepseek.com/',
|
||||
thinkingMode: 'auto',
|
||||
})
|
||||
})
|
||||
|
||||
it('keeps explicit non-default values dirty', () => {
|
||||
expect(normalizeProviderConfigDefaults(
|
||||
{ baseUrl: 'https://api.deepseek.com/', thinkingMode: 'disable' },
|
||||
{ baseUrl: 'https://api.deepseek.com/', thinkingMode: 'auto' },
|
||||
)).toEqual({
|
||||
baseUrl: 'https://api.deepseek.com/',
|
||||
thinkingMode: 'disable',
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,9 @@
|
||||
export function normalizeProviderConfigDefaults(config: Record<string, unknown>, defaultOptions: Record<string, unknown>) {
|
||||
const keys = [...new Set([...Object.keys(defaultOptions), ...Object.keys(config)])]
|
||||
return Object.fromEntries(keys.map((key) => {
|
||||
if (Object.hasOwn(config, key))
|
||||
return [key, config[key]]
|
||||
|
||||
return [key, defaultOptions[key]]
|
||||
}))
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import {
|
||||
} from '../../libs/providers'
|
||||
import { selectProviderMetadata, selectProvidersMetadata } from '../../libs/providers/metadata'
|
||||
import { useProviderConfigStore } from './config'
|
||||
import { normalizeProviderConfigDefaults } from './config-defaults'
|
||||
|
||||
export type { ModelInfo, VoiceInfo } from '../../libs/providers/types'
|
||||
|
||||
@@ -836,7 +837,7 @@ export const useProviderStore = defineStore('provider', () => {
|
||||
return false
|
||||
|
||||
const defaultOptions = getDefaultProviderConfig(providerId)
|
||||
return JSON.stringify(config) !== JSON.stringify(defaultOptions)
|
||||
return JSON.stringify(normalizeProviderConfigDefaults(config, defaultOptions)) !== JSON.stringify(defaultOptions)
|
||||
}
|
||||
|
||||
function shouldListProvider(providerId: string) {
|
||||
|
||||
Reference in New Issue
Block a user