Harden Homarr provider integration
This commit is contained in:
1 parent
165201632d
commit
4ebaea29fd
23 files changed
+427
-159
No files matched your search
@@ -480,7 +480,7 @@ export const assistantRouter = createTRPCRouter({
|
||||
const configuration = await getConfigurationAsync(ctx.db);
|
||||
if (isDemoMode) {
|
||||
return {
|
||||
provider: "homarr",
|
||||
provider: "custom" as const,
|
||||
defaultModelId: "homarr-assistant",
|
||||
models: [
|
||||
{
|
||||
|
||||
@@ -121,6 +121,30 @@ describe("assistantRouter.updateConnection", () => {
|
||||
modelId: "example/model",
|
||||
});
|
||||
});
|
||||
|
||||
test("never stores administrator credentials for the Homarr provider", async () => {
|
||||
const db = await createConfiguredAssistantAsync();
|
||||
const caller = assistantRouter.createCaller({ db, deviceType: undefined, session: adminSession });
|
||||
|
||||
await caller.updateConnection({
|
||||
provider: "homarr",
|
||||
baseUrl: "https://homarr.dev/api/ai/v1",
|
||||
modelDiscoveryPath: "/models",
|
||||
apiKey: "must-not-be-stored",
|
||||
customHeaders: { "X-Secret": "must-not-be-stored" },
|
||||
clearApiKey: false,
|
||||
clearCustomHeaders: false,
|
||||
});
|
||||
|
||||
const [configuration] = await db.select().from(assistantConfigurations);
|
||||
expect(configuration).toMatchObject({
|
||||
provider: "homarr",
|
||||
encryptedApiKey: null,
|
||||
encryptedHeaders: null,
|
||||
enabled: false,
|
||||
modelId: null,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("assistantRouter.updateConfiguration", () => {
|
||||
@@ -170,6 +194,49 @@ describe("assistantRouter.updateConfiguration", () => {
|
||||
expect(configuration?.webSearchEnabled).toBe(true);
|
||||
});
|
||||
|
||||
test("allows the Homarr OpenRouter proxy to enable web search", async () => {
|
||||
const db = await createConfiguredAssistantAsync();
|
||||
await db
|
||||
.update(assistantConfigurations)
|
||||
.set({
|
||||
provider: "homarr",
|
||||
baseUrl: "https://homarr.dev/api/ai/v1",
|
||||
encryptedApiKey: null,
|
||||
encryptedHeaders: null,
|
||||
modelId: "homarr/deepseek-v4-flash-latest",
|
||||
})
|
||||
.where(eq(assistantConfigurations.id, "default"));
|
||||
const caller = assistantRouter.createCaller({ db, deviceType: undefined, session: adminSession });
|
||||
vi.stubGlobal(
|
||||
"fetch",
|
||||
vi.fn().mockResolvedValue(
|
||||
Response.json({
|
||||
data: [
|
||||
{
|
||||
id: "homarr/deepseek-v4-flash-latest",
|
||||
name: "DeepSeek V4 Flash Latest",
|
||||
supported_parameters: ["tools"],
|
||||
architecture: { output_modalities: ["text"] },
|
||||
},
|
||||
],
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
try {
|
||||
await caller.updateConfiguration({
|
||||
enabled: true,
|
||||
modelId: "homarr/deepseek-v4-flash-latest",
|
||||
webSearchEnabled: true,
|
||||
});
|
||||
} finally {
|
||||
vi.unstubAllGlobals();
|
||||
}
|
||||
|
||||
const [configuration] = await db.select().from(assistantConfigurations);
|
||||
expect(configuration?.webSearchEnabled).toBe(true);
|
||||
});
|
||||
|
||||
test("rejects OpenRouter server tools for an incompatible provider", async () => {
|
||||
const db = await createConfiguredAssistantAsync();
|
||||
await db
|
||||
|
||||
Reference in new issue
Block a user