feat: expand assistant interaction capabilities

This commit is contained in:
ajnart committed 2026-07-30 14:09:15 +02:00
1 parent 9e6a0c7748
commit 33e23021ae
12 files changed
+2046 -81

No files matched your search

+66 -1
View File
@@ -1,10 +1,20 @@
// @vitest-environment node
import { describe, expect, test, vi } from "vitest";
import { parse } from "superjson";
import type { Session } from "@homarr/auth";
import { createId } from "@homarr/common";
import { assistantConfigurations } from "@homarr/db/schema";
import {
apps,
assistantConfigurations,
assistantMessages,
boards,
integrations,
integrationUserPermissions,
items,
users,
} from "@homarr/db/schema";
import { createDb } from "@homarr/db/test";
import { assistantRouter } from "../assistant";
@@ -90,3 +100,58 @@ describe("assistantRouter.updateConnection", () => {
});
});
});
describe("assistant conversation features", () => {
test("returns permission-checked entities for composer mentions", async () => {
const db = await createConfiguredAssistantAsync();
await db.insert(users).values({ id: adminSession.user.id });
await db.insert(apps).values({ id: "app-1", name: "Plex", iconUrl: "https://example.com/plex.svg" });
await db.insert(boards).values({ id: "board-1", name: "Home", isPublic: true });
await db.insert(items).values({ id: "widget-1", boardId: "board-1", kind: "clock" });
await db.insert(integrations).values({
id: "integration-1",
name: "Media server",
kind: "plex",
url: "https://example.com",
});
await db.insert(integrationUserPermissions).values({
integrationId: "integration-1",
userId: adminSession.user.id,
permission: "use",
});
const caller = assistantRouter.createCaller({ db, deviceType: undefined, session: adminSession });
const entities = await caller.getContextEntities();
expect(entities).toEqual(
expect.arrayContaining([
expect.objectContaining({ id: "app-1", type: "app", label: "Plex" }),
expect.objectContaining({ id: "board-1", type: "board", label: "Home" }),
expect.objectContaining({ id: "widget-1", type: "widget", boardId: "board-1" }),
expect.objectContaining({ id: "integration-1", type: "integration", label: "Media server" }),
]),
);
});
test("persists feedback on an owned assistant message", async () => {
const db = await createConfiguredAssistantAsync();
await db.insert(users).values({ id: adminSession.user.id });
const caller = assistantRouter.createCaller({ db, deviceType: undefined, session: adminSession });
const thread = await caller.createThread();
await caller.appendMessage({
threadId: thread.id,
id: "message-1",
parentId: null,
format: "ai-sdk/v6",
content: { role: "assistant", parts: [{ type: "text", text: "Hello" }], metadata: { custom: {} } },
});
await caller.submitFeedback({ threadId: thread.id, messageId: "message-1", type: "positive" });
const [message] = await db.select().from(assistantMessages);
expect(message).toBeDefined();
expect(parse(message?.content ?? "")).toMatchObject({
metadata: { submittedFeedback: { type: "positive" } },
});
});
});