fix: invalidate persisted assistant model state
This commit is contained in:
1 parent
6da471d24a
commit
073d9ce127
2 files changed
+96
-2
No files matched your search
@@ -271,6 +271,8 @@ export const assistantRouter = createTRPCRouter({
|
||||
const existing = await getConfigurationAsync(ctx.db);
|
||||
const destinationChanged =
|
||||
existing !== undefined && (existing.provider !== input.provider || existing.baseUrl !== baseUrl);
|
||||
const connectionChanged =
|
||||
existing !== undefined && (destinationChanged || existing.modelDiscoveryPath !== modelDiscoveryPath);
|
||||
const encryptedApiKey = input.apiKey
|
||||
? encryptSecret(input.apiKey)
|
||||
: input.clearApiKey || destinationChanged
|
||||
@@ -291,8 +293,8 @@ export const assistantRouter = createTRPCRouter({
|
||||
modelDiscoveryPath,
|
||||
encryptedApiKey,
|
||||
encryptedHeaders,
|
||||
modelId: destinationChanged ? null : existing.modelId,
|
||||
enabled: destinationChanged ? false : existing.enabled,
|
||||
modelId: connectionChanged ? null : existing.modelId,
|
||||
enabled: connectionChanged ? false : existing.enabled,
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(assistantConfigurations.id, configurationId));
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
// @vitest-environment node
|
||||
|
||||
import { describe, expect, test, vi } from "vitest";
|
||||
|
||||
import type { Session } from "@homarr/auth";
|
||||
import { createId } from "@homarr/common";
|
||||
import { assistantConfigurations } from "@homarr/db/schema";
|
||||
import { createDb } from "@homarr/db/test";
|
||||
|
||||
import { assistantRouter } from "../assistant";
|
||||
|
||||
vi.mock("@homarr/auth", () => ({}));
|
||||
vi.mock("@homarr/common/server", () => ({
|
||||
decryptSecret: vi.fn(),
|
||||
encryptSecret: vi.fn(),
|
||||
}));
|
||||
vi.mock("@homarr/core/infrastructure/logs", () => ({
|
||||
createLogger: () => ({
|
||||
error: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
vi.mock("@homarr/core/infrastructure/db/env", () => ({
|
||||
dbEnv: { DRIVER: "better-sqlite3" },
|
||||
}));
|
||||
|
||||
const adminSession = {
|
||||
user: {
|
||||
id: createId(),
|
||||
permissions: ["admin"],
|
||||
colorScheme: "light",
|
||||
},
|
||||
expires: new Date().toISOString(),
|
||||
} satisfies Session;
|
||||
|
||||
const createConfiguredAssistantAsync = async () => {
|
||||
const db = createDb();
|
||||
await db.insert(assistantConfigurations).values({
|
||||
id: "default",
|
||||
enabled: true,
|
||||
provider: "openrouter",
|
||||
baseUrl: "https://openrouter.ai/api/v1",
|
||||
modelDiscoveryPath: "/models",
|
||||
encryptedApiKey: "encrypted.key",
|
||||
encryptedHeaders: "encrypted.headers",
|
||||
modelId: "example/model",
|
||||
});
|
||||
return db;
|
||||
};
|
||||
|
||||
describe("assistantRouter.updateConnection", () => {
|
||||
test("clears the persisted model when the discovery path changes without clearing credentials", async () => {
|
||||
const db = await createConfiguredAssistantAsync();
|
||||
const caller = assistantRouter.createCaller({ db, deviceType: undefined, session: adminSession });
|
||||
|
||||
await caller.updateConnection({
|
||||
provider: "openrouter",
|
||||
baseUrl: "https://openrouter.ai/api/v1",
|
||||
modelDiscoveryPath: "/catalog",
|
||||
clearApiKey: false,
|
||||
clearCustomHeaders: false,
|
||||
});
|
||||
|
||||
const [configuration] = await db.select().from(assistantConfigurations);
|
||||
expect(configuration).toMatchObject({
|
||||
enabled: false,
|
||||
modelDiscoveryPath: "/catalog",
|
||||
modelId: null,
|
||||
encryptedApiKey: "encrypted.key",
|
||||
encryptedHeaders: "encrypted.headers",
|
||||
});
|
||||
});
|
||||
|
||||
test("preserves the persisted model when the saved connection is unchanged", async () => {
|
||||
const db = await createConfiguredAssistantAsync();
|
||||
const caller = assistantRouter.createCaller({ db, deviceType: undefined, session: adminSession });
|
||||
|
||||
await caller.updateConnection({
|
||||
provider: "openrouter",
|
||||
baseUrl: "https://openrouter.ai/api/v1",
|
||||
modelDiscoveryPath: "/models",
|
||||
clearApiKey: false,
|
||||
clearCustomHeaders: false,
|
||||
});
|
||||
|
||||
const [configuration] = await db.select().from(assistantConfigurations);
|
||||
expect(configuration).toMatchObject({
|
||||
enabled: true,
|
||||
modelDiscoveryPath: "/models",
|
||||
modelId: "example/model",
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user