Skip to content

Commit 70e3569

Browse files
authored
refactor: 使用 OSS 提供配置服务 (#1138)
1 parent 6db0beb commit 70e3569

4 files changed

Lines changed: 211 additions & 156 deletions

File tree

src/lib/ai/notegen-default-models-runtime.ts

Lines changed: 16 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
1-
import { fetch as httpFetch } from '@tauri-apps/plugin-http'
21
import { Store } from '@tauri-apps/plugin-store'
3-
import MD5 from 'crypto-js/md5.js'
42

53
import type { AiConfig, ModelConfig, ModelType } from '@/app/core/setting/config'
6-
7-
const UPGRADE_LINK_CONFIGURATION_KEY = 'Wg_BZFH1WUdx7atKagepXg'
8-
const UPGRADE_LINK_ACCESS_KEY = 'wHi8Tkuc5i6v1UCAuVk48A'
9-
const UPGRADE_LINK_SECRET_KEY = 'eg4upYo7ruJgaDVOtlHJGj4lyzG4Oh9IpLGwOc6Oehw'
10-
const UPGRADE_LINK_UPGRADE_URL = 'https://api.upgrade.toolsetlink.com/v1/configuration/upgrade'
11-
const UPGRADE_LINK_UPGRADE_URI = '/v1/configuration/upgrade'
12-
const INITIAL_NOTEGEN_DEFAULT_MODELS_VERSION_CODE = 1
4+
import { fetchConfigCenterConfig } from '@/lib/config-center/client'
135

146
export const NOTEGEN_DEFAULT_MODELS_CACHE_KEY = 'noteGenDefaultModelsCache'
157

@@ -58,46 +50,6 @@ function parseContentPayload(payload: unknown) {
5850
return null
5951
}
6052

61-
function buildUpgradeLinkSignature({
62-
body,
63-
nonce,
64-
secretKey,
65-
timestamp,
66-
uri,
67-
}: {
68-
body?: string
69-
nonce: string
70-
secretKey: string
71-
timestamp: string
72-
uri: string
73-
}) {
74-
const source = body
75-
? `body=${body}&nonce=${nonce}&secretKey=${secretKey}&timestamp=${timestamp}&url=${uri}`
76-
: `nonce=${nonce}&secretKey=${secretKey}&timestamp=${timestamp}&url=${uri}`
77-
78-
return MD5(source).toString()
79-
}
80-
81-
function buildSignedHeaders(body: string) {
82-
const timestamp = new Date().toISOString()
83-
const nonce = crypto.randomUUID()
84-
const signature = buildUpgradeLinkSignature({
85-
body,
86-
nonce,
87-
secretKey: UPGRADE_LINK_SECRET_KEY,
88-
timestamp,
89-
uri: UPGRADE_LINK_UPGRADE_URI,
90-
})
91-
92-
return {
93-
'Content-Type': 'application/json',
94-
'X-AccessKey': UPGRADE_LINK_ACCESS_KEY,
95-
'X-Timestamp': timestamp,
96-
'X-Nonce': nonce,
97-
'X-Signature': signature,
98-
}
99-
}
100-
10153
function normalizeModelItem(item: Record<string, unknown>): ModelConfig | null {
10254
if (!isNonEmptyString(item.id) || !isNonEmptyString(item.model)) {
10355
return null
@@ -166,39 +118,20 @@ function mergeNoteGenDefaultModels(config: AiConfig, remoteModels: ModelConfig[]
166118
}
167119
}
168120

169-
async function fetchRemoteNoteGenDefaultModels(versionCode?: number | null): Promise<NoteGenDefaultModelsCache | null> {
170-
const body = JSON.stringify({
171-
configurationKey: UPGRADE_LINK_CONFIGURATION_KEY,
172-
versionCode: versionCode || INITIAL_NOTEGEN_DEFAULT_MODELS_VERSION_CODE,
173-
appointVersionCode: 0,
174-
})
175-
176-
const response = await httpFetch(UPGRADE_LINK_UPGRADE_URL, {
177-
method: 'POST',
178-
headers: buildSignedHeaders(body),
179-
body,
180-
})
181-
182-
if (!response.ok) {
183-
throw new Error(`NoteGen default models request failed: ${response.status} ${response.statusText}`)
184-
}
185-
186-
const result = await response.json() as {
187-
data?: {
188-
versionCode?: number
189-
versionName?: string
190-
content?: unknown
191-
}
121+
async function fetchNoteGenDefaultModelsFromConfigCenter(versionCode?: number | null): Promise<NoteGenDefaultModelsCache | null> {
122+
const result = await fetchConfigCenterConfig('noteGenDefaultModels', versionCode)
123+
if (result.status === 'not-modified') {
124+
return null
192125
}
193126

194-
const models = normalizeNoteGenDefaultModelsPayload(result?.data?.content)
127+
const models = normalizeNoteGenDefaultModelsPayload(result.payload)
195128
if (models.length === 0) {
196-
return null
129+
throw new Error('Config center NoteGen default models payload is empty')
197130
}
198131

199132
return {
200-
versionCode: result?.data?.versionCode,
201-
versionName: result?.data?.versionName,
133+
versionCode: result.versionCode,
134+
versionName: result.versionName,
202135
fetchedAt: new Date().toISOString(),
203136
content: {
204137
models,
@@ -211,13 +144,18 @@ export async function loadNoteGenDefaultConfig(builtinConfig: AiConfig): Promise
211144
const cached = await store.get<NoteGenDefaultModelsCache>(NOTEGEN_DEFAULT_MODELS_CACHE_KEY)
212145

213146
try {
214-
const latest = await fetchRemoteNoteGenDefaultModels(cached?.versionCode)
147+
const latest = await fetchNoteGenDefaultModelsFromConfigCenter(cached?.versionCode)
215148
if (latest) {
216149
await store.set(NOTEGEN_DEFAULT_MODELS_CACHE_KEY, latest)
150+
await store.save()
217151
return mergeNoteGenDefaultModels(builtinConfig, normalizeNoteGenDefaultModelsPayload(latest.content))
218152
}
153+
154+
if (cached?.content?.models?.length) {
155+
return mergeNoteGenDefaultModels(builtinConfig, normalizeNoteGenDefaultModelsPayload(cached.content))
156+
}
219157
} catch (error) {
220-
console.error('[notegen-default-models] failed to fetch remote models', error)
158+
console.error('[notegen-default-models] failed to fetch config center models', error)
221159
}
222160

223161
if (cached?.content?.models?.length) {

src/lib/ai/provider-templates-runtime.ts

Lines changed: 16 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
1-
import { fetch as httpFetch } from '@tauri-apps/plugin-http'
21
import { Store } from '@tauri-apps/plugin-store'
3-
import MD5 from 'crypto-js/md5.js'
42

53
import type { AiConfig } from '@/app/core/setting/config'
6-
7-
const UPGRADE_LINK_CONFIGURATION_KEY = 'sLwoVGPpyngsYyubAk2V8g'
8-
const UPGRADE_LINK_ACCESS_KEY = 'wHi8Tkuc5i6v1UCAuVk48A'
9-
const UPGRADE_LINK_SECRET_KEY = 'eg4upYo7ruJgaDVOtlHJGj4lyzG4Oh9IpLGwOc6Oehw'
10-
const UPGRADE_LINK_UPGRADE_URL = 'https://api.upgrade.toolsetlink.com/v1/configuration/upgrade'
11-
const UPGRADE_LINK_UPGRADE_URI = '/v1/configuration/upgrade'
12-
const INITIAL_PROVIDER_TEMPLATE_VERSION_CODE = 1
4+
import { fetchConfigCenterConfig } from '@/lib/config-center/client'
135

146
export const PROVIDER_TEMPLATE_CACHE_KEY = 'providerTemplatesCache'
157

@@ -67,26 +59,6 @@ function parseContentPayload(payload: unknown) {
6759
return null
6860
}
6961

70-
function buildUpgradeLinkSignature({
71-
body,
72-
nonce,
73-
secretKey,
74-
timestamp,
75-
uri,
76-
}: {
77-
body?: string
78-
nonce: string
79-
secretKey: string
80-
timestamp: string
81-
uri: string
82-
}) {
83-
const source = body
84-
? `body=${body}&nonce=${nonce}&secretKey=${secretKey}&timestamp=${timestamp}&url=${uri}`
85-
: `nonce=${nonce}&secretKey=${secretKey}&timestamp=${timestamp}&url=${uri}`
86-
87-
return MD5(source).toString()
88-
}
89-
9062
function normalizeProviderTemplatesPayload(payload: unknown): AiConfig[] {
9163
const parsedPayload = parseContentPayload(payload)
9264
const providers = Array.isArray((parsedPayload as { providers?: unknown[] } | null)?.providers)
@@ -159,59 +131,20 @@ export async function getCachedProviderTemplates(): Promise<AiConfig[]> {
159131
return mapRemoteTemplates(cached.content)
160132
}
161133

162-
function buildSignedHeaders(body: string) {
163-
const timestamp = new Date().toISOString()
164-
const nonce = crypto.randomUUID()
165-
const signature = buildUpgradeLinkSignature({
166-
body,
167-
nonce,
168-
secretKey: UPGRADE_LINK_SECRET_KEY,
169-
timestamp,
170-
uri: UPGRADE_LINK_UPGRADE_URI,
171-
})
172-
173-
return {
174-
'Content-Type': 'application/json',
175-
'X-AccessKey': UPGRADE_LINK_ACCESS_KEY,
176-
'X-Timestamp': timestamp,
177-
'X-Nonce': nonce,
178-
'X-Signature': signature,
179-
}
180-
}
181-
182-
async function fetchRemoteProviderTemplates(versionCode?: number | null): Promise<ProviderTemplateCache | null> {
183-
const body = JSON.stringify({
184-
configurationKey: UPGRADE_LINK_CONFIGURATION_KEY,
185-
versionCode: versionCode || INITIAL_PROVIDER_TEMPLATE_VERSION_CODE,
186-
appointVersionCode: 0,
187-
})
188-
189-
const response = await httpFetch(UPGRADE_LINK_UPGRADE_URL, {
190-
method: 'POST',
191-
headers: buildSignedHeaders(body),
192-
body,
193-
})
194-
195-
if (!response.ok) {
196-
throw new Error(`Provider template request failed: ${response.status} ${response.statusText}`)
197-
}
198-
199-
const result = await response.json() as {
200-
data?: {
201-
versionCode?: number
202-
versionName?: string
203-
content?: unknown
204-
}
134+
async function fetchProviderTemplatesFromConfigCenter(versionCode?: number | null): Promise<ProviderTemplateCache | null> {
135+
const result = await fetchConfigCenterConfig('providerTemplates', versionCode)
136+
if (result.status === 'not-modified') {
137+
return null
205138
}
206139

207-
const templates = normalizeProviderTemplatesPayload(result?.data?.content)
140+
const templates = normalizeProviderTemplatesPayload(result.payload)
208141
if (templates.length === 0) {
209-
return null
142+
throw new Error('Config center provider templates payload is empty')
210143
}
211144

212145
return {
213-
versionCode: result?.data?.versionCode,
214-
versionName: result?.data?.versionName,
146+
versionCode: result.versionCode,
147+
versionName: result.versionName,
215148
fetchedAt: new Date().toISOString(),
216149
content: {
217150
providers: templates,
@@ -224,13 +157,18 @@ export async function loadProviderTemplates(builtinTemplates: AiConfig[]): Promi
224157
const cached = await store.get<ProviderTemplateCache>(PROVIDER_TEMPLATE_CACHE_KEY)
225158

226159
try {
227-
const latest = await fetchRemoteProviderTemplates(cached?.versionCode)
160+
const latest = await fetchProviderTemplatesFromConfigCenter(cached?.versionCode)
228161
if (latest) {
229162
await store.set(PROVIDER_TEMPLATE_CACHE_KEY, latest)
163+
await store.save()
230164
return mapRemoteTemplates(latest.content)
231165
}
166+
167+
if (cached?.content?.providers?.length) {
168+
return mapRemoteTemplates(cached.content)
169+
}
232170
} catch (error) {
233-
console.error('[provider-templates] failed to fetch remote templates', error)
171+
console.error('[provider-templates] failed to fetch config center templates', error)
234172
}
235173

236174
if (cached?.content?.providers?.length) {

0 commit comments

Comments
 (0)