Merge updated DeepSeek onboarding base

# Conflicts:
#	.agents/notes/implemented/feature/2026-07-30-deepseek-onboarding-credential-setup.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-30-deepseek-onboarding-credential-setup.md
#	.agents/notes/implemented/feature/2026-07-30-deepseek-onboarding-credential-setup.zh.md
#	packages/client/ui-models/README.i18n.yaml
#	packages/client/ui-models/README.md
#	packages/client/ui-models/README.zh.md
#	packages/client/ui-models/src/client/DeepSeekOnboardingDialog.module.css
#	packages/client/ui-models/src/client/DeepSeekOnboardingDialog.tsx
#	packages/client/ui-models/tests/onboarding-dialog.spec.tsx
This commit is contained in:
NI0317
2026-07-31 10:29:20 +08:00
90 changed files with 2496 additions and 346 deletions
@@ -24,6 +24,7 @@ function fail<T>(message: string): RpcResponse<T> {
function harness(options: {
provider?: boolean
providerSettingsNs?: string
providerActive?: boolean
settingsNamespace?: boolean
apiKeyEnv?: string | null
@@ -32,25 +33,21 @@ function harness(options: {
credential?: { source?: string; writable: boolean }
describeFailure?: string
settingsWritable?: boolean
providersRejectOnce?: boolean
providersReject?: boolean
} = {}) {
let fileConfigured = false
let rejectProviders = options.providersRejectOnce === true
const configured = options.configured ?? (() => fileConfigured)
const face = {
llm: {
providers: () => {
if (rejectProviders) {
rejectProviders = false
return Promise.reject(new Error('provider transport unavailable'))
}
if (options.providersReject === true) return Promise.reject(new Error('provider transport unavailable'))
return Promise.resolve(ok({
providers: options.provider === false
? []
: [{
provider: 'deepseek-official',
displayName: 'DeepSeek',
settingsNs: 'llm-deepseek',
settingsNs: options.providerSettingsNs ?? 'llm-deepseek',
settingsPath: [],
active: options.providerActive ?? true,
}],
@@ -137,45 +134,21 @@ describe('DeepSeekOnboardingDialog', () => {
expect(h.openSection).not.toHaveBeenCalled()
})
it('routes an unavailable credential deployment to Models with a diagnostic', async () => {
const h = harness({ describeFailure: 'credentials service is absent' })
render(<DeepSeekOnboardingDialog {...h.props} />)
await screen.findByRole('region', { name: en.onboardingUnavailableTitle })
expect(screen.getByText(en.onboardingCredentialsUnavailable)).toBeTruthy()
fireEvent.click(screen.getByRole('button', { name: en.onboardingGoToSettings }))
expect(h.openSection).toHaveBeenCalledWith('models')
})
it('explains read-only credential and settings deployments', async () => {
it('does not block the product when DeepSeek setup is unavailable', async () => {
for (const h of [
harness({ describeFailure: 'credentials service is absent' }),
harness({ credential: { writable: false } }),
harness({ settingsWritable: false }),
]) {
const view = render(<DeepSeekOnboardingDialog {...h.props} />)
await screen.findByRole('region', { name: en.onboardingUnavailableTitle })
expect(screen.getByText(en.onboardingReadOnly)).toBeTruthy()
view.unmount()
}
})
it('distinguishes an initial transport failure from deployment misconfiguration', async () => {
const h = harness({ providersRejectOnce: true })
render(<DeepSeekOnboardingDialog {...h.props} />)
await screen.findByRole('region', { name: en.onboardingUnavailableTitle })
expect(screen.getByText(en.onboardingLoadFailed)).toBeTruthy()
fireEvent.click(screen.getByRole('button', { name: en.onboardingGoToSettings }))
expect(h.openSection).toHaveBeenCalledWith('models')
})
it('uses the configuration diagnostic for inactive or unresolvable adapters', async () => {
for (const h of [
harness({ providersReject: true }),
harness({ providerActive: false }),
harness({ settingsNamespace: false }),
harness({ apiKeyEnv: null }),
]) {
const view = render(<DeepSeekOnboardingDialog {...h.props} />)
await screen.findByRole('region', { name: en.onboardingUnavailableTitle })
expect(screen.getByText(en.onboardingConfigurationUnavailable)).toBeTruthy()
await act(async () => { await h.controller.load() })
expect(screen.queryByRole('region')).toBeNull()
await waitFor(() => { expect(h.complete).toHaveBeenCalledOnce() })
expect(h.openSection).not.toHaveBeenCalled()
view.unmount()
}
})
@@ -183,6 +156,7 @@ describe('DeepSeekOnboardingDialog', () => {
it('skips an absent adapter and already-configured literal or environment credentials', async () => {
for (const h of [
harness({ provider: false }),
harness({ providerSettingsNs: '' }),
harness({ literal: true, describeFailure: 'credential seam absent' }),
harness({ configured: () => true, credential: { source: 'env', writable: false } }),
]) {
@@ -41,6 +41,14 @@ describe('deepSeekReadiness', () => {
expect(deepSeekReadiness(state({ status: 'idle', rows: [] }))).toEqual({ kind: 'loading' })
expect(deepSeekReadiness(state({ status: 'loading', rows: [] }))).toEqual({ kind: 'loading' })
expect(deepSeekReadiness(state({ rows: [] }))).toEqual({ kind: 'adapter-absent' })
expect(deepSeekReadiness(state({
rows: [row({
entry: {
...row().entry,
settingsNs: '',
},
})],
}))).toEqual({ kind: 'adapter-absent' })
})
it('reports a missing writable effective credential', () => {