refactor(provider): simplify live_config_managed and deduplicate tolerant live config checks

- Change live_config_managed from Option<bool> to bool with #[serde(default)]
- Extract repeated tolerant live config query into check_live_config_exists helper
- Fix duplicate key generation to also check live-only provider IDs
- Fix updateProvider test to match new { provider, originalId } call signature
- Add streaming_responses test type annotation for compiler inference
This commit is contained in:
YoVinchen
2026-03-30 16:23:50 +08:00
parent dbb943852d
commit 98c8255dbb
8 changed files with 261 additions and 12 deletions
+4 -1
View File
@@ -169,7 +169,10 @@ describe("useProviderActions", () => {
await result.current.updateProvider(provider);
});
expect(updateProviderMutateAsync).toHaveBeenCalledWith(provider);
expect(updateProviderMutateAsync).toHaveBeenCalledWith({
provider,
originalId: undefined,
});
expect(providersApiUpdateTrayMenuMock).toHaveBeenCalledTimes(1);
});
+4 -2
View File
@@ -5,6 +5,7 @@ import { describe, it, expect, beforeEach, vi } from "vitest";
import {
resetProviderState,
setCurrentProviderId,
setLiveProviderIds,
setProviders,
} from "../msw/state";
import { emitTauriEvent } from "../msw/tauriMocks";
@@ -239,7 +240,7 @@ describe("App integration with MSW", () => {
});
});
it("duplicates openclaw providers with a generated provider key", async () => {
it("duplicates openclaw providers with a generated key that avoids live-only ids", async () => {
setProviders("openclaw", {
deepseek: {
id: "deepseek",
@@ -256,6 +257,7 @@ describe("App integration with MSW", () => {
},
});
setCurrentProviderId("openclaw", "deepseek");
setLiveProviderIds("openclaw", ["deepseek-copy"]);
const { default: App } = await import("@/App");
renderApp(App);
@@ -272,7 +274,7 @@ describe("App integration with MSW", () => {
await waitFor(() => {
const providerList = screen.getByTestId("provider-list").textContent;
expect(providerList).toContain("deepseek-copy");
expect(providerList).toContain("deepseek-copy-2");
expect(providerList).toContain("DeepSeek copy");
});
+6 -1
View File
@@ -6,6 +6,7 @@ import {
deleteProvider,
deleteSession,
getCurrentProviderId,
getLiveProviderIds,
getSessionMessages,
getProviders,
listProviders,
@@ -67,8 +68,12 @@ export const handlers = [
http.post(`${TAURI_ENDPOINT}/update_tray_menu`, () => success(true)),
http.post(`${TAURI_ENDPOINT}/get_opencode_live_provider_ids`, () =>
success(getLiveProviderIds("opencode")),
),
http.post(`${TAURI_ENDPOINT}/get_openclaw_live_provider_ids`, () =>
success([]),
success(getLiveProviderIds("openclaw")),
),
http.post(`${TAURI_ENDPOINT}/get_openclaw_default_model`, () =>
+20
View File
@@ -10,6 +10,7 @@ import type {
type ProvidersByApp = Record<AppId, Record<string, Provider>>;
type CurrentProviderState = Record<AppId, string>;
type McpConfigState = Record<AppId, Record<string, McpServer>>;
type LiveProviderIdsByApp = Record<"opencode" | "openclaw", string[]>;
const createDefaultProviders = (): ProvidersByApp => ({
claude: {
@@ -77,6 +78,10 @@ const createDefaultCurrent = (): CurrentProviderState => ({
let providers = createDefaultProviders();
let current = createDefaultCurrent();
let liveProviderIds: LiveProviderIdsByApp = {
opencode: [],
openclaw: [],
};
let settingsState: Settings = {
showInTray: true,
minimizeToTrayOnClose: true,
@@ -184,6 +189,10 @@ const cloneProviders = (value: ProvidersByApp) =>
export const resetProviderState = () => {
providers = createDefaultProviders();
current = createDefaultCurrent();
liveProviderIds = {
opencode: [],
openclaw: [],
};
sessionsState = createDefaultSessions();
sessionMessagesState = createDefaultSessionMessages();
settingsState = {
@@ -243,6 +252,17 @@ export const getProviders = (appType: AppId) =>
export const getCurrentProviderId = (appType: AppId) => current[appType] ?? "";
export const getLiveProviderIds = (appType: "opencode" | "openclaw") => [
...liveProviderIds[appType],
];
export const setLiveProviderIds = (
appType: "opencode" | "openclaw",
ids: string[],
) => {
liveProviderIds[appType] = [...ids];
};
export const setCurrentProviderId = (appType: AppId, providerId: string) => {
current[appType] = providerId;
};