fix: preserve meta.custom_endpoints on update and persist preset candidates on create
- Preserve and merge meta.custom_endpoints in update_provider to avoid losing custom endpoints added via Tauri commands during edit/save. Merge old and incoming meta; keep existing entries and timestamps, add new URLs only. - Persist endpoint candidates when creating a provider: union of user-added custom endpoints, selected base URL (Claude/Codex), and preset.endpointCandidates; normalize and de-duplicate. Ensures PackyCode keeps all 5 nodes after saving. Files: - src-tauri/src/commands.rs - src/components/ProviderForm.tsx Validation: - cargo check passes - Manual: create from PackyCode preset -> save -> reopen edit -> Manage & Test lists all preset nodes; edit existing provider -> add endpoint -> save -> reopen -> endpoint persists.
This commit is contained in:
@@ -615,19 +615,61 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
|
||||
...(category ? { category } : {}),
|
||||
};
|
||||
|
||||
// 若为"新建供应商",且已在弹窗中添加了自定义端点,则随提交一并落盘
|
||||
if (!initialData && draftCustomEndpoints.length > 0) {
|
||||
const now = Date.now();
|
||||
const customMap: Record<string, CustomEndpoint> = {};
|
||||
for (const raw of draftCustomEndpoints) {
|
||||
const url = raw.trim().replace(/\/+$/, "");
|
||||
if (!url) continue;
|
||||
if (!customMap[url]) {
|
||||
customMap[url] = { url, addedAt: now, lastUsed: undefined };
|
||||
// 若为"新建供应商",将端点候选一并随提交落盘到 meta.custom_endpoints:
|
||||
// - 用户在弹窗中新增的自定义端点(draftCustomEndpoints,已去重)
|
||||
// - 预设中的 endpointCandidates(若存在)
|
||||
// - 当前选中的基础 URL(baseUrl/codexBaseUrl)
|
||||
if (!initialData) {
|
||||
const urlSet = new Set<string>();
|
||||
const push = (raw?: string) => {
|
||||
const url = (raw || "").trim().replace(/\/+$/, "");
|
||||
if (url) urlSet.add(url);
|
||||
};
|
||||
|
||||
// 自定义端点(仅来自用户新增)
|
||||
for (const u of draftCustomEndpoints) push(u);
|
||||
|
||||
// 预设端点候选
|
||||
if (!isCodex) {
|
||||
if (
|
||||
selectedPreset !== null &&
|
||||
selectedPreset >= 0 &&
|
||||
selectedPreset < providerPresets.length
|
||||
) {
|
||||
const preset = providerPresets[selectedPreset] as any;
|
||||
if (Array.isArray(preset?.endpointCandidates)) {
|
||||
for (const u of preset.endpointCandidates as string[]) push(u);
|
||||
}
|
||||
}
|
||||
// 当前 Claude 基础地址
|
||||
push(baseUrl);
|
||||
} else {
|
||||
if (
|
||||
selectedCodexPreset !== null &&
|
||||
selectedCodexPreset >= 0 &&
|
||||
selectedCodexPreset < codexProviderPresets.length
|
||||
) {
|
||||
const preset = codexProviderPresets[selectedCodexPreset] as any;
|
||||
if (Array.isArray(preset?.endpointCandidates)) {
|
||||
for (const u of preset.endpointCandidates as string[]) push(u);
|
||||
}
|
||||
}
|
||||
// 当前 Codex 基础地址
|
||||
push(codexBaseUrl);
|
||||
}
|
||||
|
||||
const urls = Array.from(urlSet.values());
|
||||
if (urls.length > 0) {
|
||||
const now = Date.now();
|
||||
const customMap: Record<string, CustomEndpoint> = {};
|
||||
for (const url of urls) {
|
||||
if (!customMap[url]) {
|
||||
customMap[url] = { url, addedAt: now, lastUsed: undefined };
|
||||
}
|
||||
}
|
||||
onSubmit({ ...basePayload, meta: { custom_endpoints: customMap } });
|
||||
return;
|
||||
}
|
||||
onSubmit({ ...basePayload, meta: { custom_endpoints: customMap } });
|
||||
return;
|
||||
}
|
||||
|
||||
onSubmit(basePayload);
|
||||
|
||||
Reference in New Issue
Block a user