diff --git a/apps/docs/docs/management/assistant.mdx b/apps/docs/docs/management/assistant.mdx index 7bf6df1fe..47594ad96 100644 --- a/apps/docs/docs/management/assistant.mdx +++ b/apps/docs/docs/management/assistant.mdx @@ -64,7 +64,7 @@ uses. Choose OpenRouter or another provider when you prefer a provider-neutral p ## Conversations and tools Conversations and messages are stored per user in the Homarr database. The assistant stays out of the -page layout until it is opened. Users can start, revisit, archive, and delete conversations from the +page layout until it is opened. Users can start, revisit, and delete conversations from the conversation menu in the floating panel. The assistant can use the same internal tool definitions as the [Homarr MCP server](./mcp). diff --git a/apps/nextjs/src/app/api/assistant/chat/route.ts b/apps/nextjs/src/app/api/assistant/chat/route.ts index b41f4cf85..661a37dd6 100644 --- a/apps/nextjs/src/app/api/assistant/chat/route.ts +++ b/apps/nextjs/src/app/api/assistant/chat/route.ts @@ -142,11 +142,7 @@ export async function POST(request: Request) { } const thread = await db.query.assistantThreads.findFirst({ - where: and( - eq(assistantThreads.id, parsed.data.id), - eq(assistantThreads.userId, session.user.id), - eq(assistantThreads.status, "regular"), - ), + where: and(eq(assistantThreads.id, parsed.data.id), eq(assistantThreads.userId, session.user.id)), }); if (!thread) { return Response.json({ error: "Conversation not found." }, { status: 404 }); diff --git a/apps/nextjs/src/components/assistant/assistant-panel.tsx b/apps/nextjs/src/components/assistant/assistant-panel.tsx index 94149ccb5..ad06d962f 100644 --- a/apps/nextjs/src/components/assistant/assistant-panel.tsx +++ b/apps/nextjs/src/components/assistant/assistant-panel.tsx @@ -34,7 +34,6 @@ import { IconActivityHeartbeat, IconAlertTriangle, IconApps, - IconArchive, IconArrowUp, IconCheck, IconChevronUp, @@ -44,7 +43,6 @@ import { IconPlayerStop, IconPlus, IconRefresh, - IconRestore, IconRobot, IconSearch, IconTrash, @@ -237,45 +235,6 @@ const ThreadListItem = () => { - - - - - - - - - - - - - ); -}; - -const ArchivedThreadListItem = () => { - const t = useScopedI18n("common.assistant"); - const onSelect = useContext(HistorySelectContext); - return ( - - - - - - - - - - @@ -307,10 +266,6 @@ const ThreadHistory = ({ onSelect }: { onSelect: () => void }) => { - - {t("archived")} - - diff --git a/apps/nextjs/src/components/assistant/assistant-provider.tsx b/apps/nextjs/src/components/assistant/assistant-provider.tsx index d9b7e92bb..9e9412822 100644 --- a/apps/nextjs/src/components/assistant/assistant-provider.tsx +++ b/apps/nextjs/src/components/assistant/assistant-provider.tsx @@ -52,6 +52,7 @@ interface AssistantContextValue { } const AssistantContext = createContext(null); +const ignoreUnsupportedArchiveAction = () => Promise.resolve(); export const useHomarrAssistant = () => { const value = useContext(AssistantContext); @@ -69,7 +70,7 @@ const threadAdapter: RemoteThreadListAdapter = { return { threads: threads.map((thread) => ({ remoteId: thread.id, - status: thread.status, + status: "regular", title: thread.title ?? undefined, lastMessageAt: thread.updatedAt, custom: { modelId: thread.modelId }, @@ -84,7 +85,7 @@ const threadAdapter: RemoteThreadListAdapter = { const { thread } = await fetchApi.assistant.getThread.query({ threadId }); return { remoteId: thread.id, - status: thread.status, + status: "regular", title: thread.title ?? undefined, lastMessageAt: thread.updatedAt, custom: { modelId: thread.modelId }, @@ -93,12 +94,9 @@ const threadAdapter: RemoteThreadListAdapter = { async rename(threadId, title) { await fetchApi.assistant.renameThread.mutate({ threadId, title }); }, - async archive(threadId) { - await fetchApi.assistant.setThreadStatus.mutate({ threadId, status: "archived" }); - }, - async unarchive(threadId) { - await fetchApi.assistant.setThreadStatus.mutate({ threadId, status: "regular" }); - }, + // assistant-ui requires these callbacks even when the product does not expose archiving. + archive: ignoreUnsupportedArchiveAction, + unarchive: ignoreUnsupportedArchiveAction, async delete(threadId) { await fetchApi.assistant.deleteThread.mutate({ threadId }); }, diff --git a/packages/api/src/router/assistant.ts b/packages/api/src/router/assistant.ts index 3761e165f..13a669726 100644 --- a/packages/api/src/router/assistant.ts +++ b/packages/api/src/router/assistant.ts @@ -407,16 +407,6 @@ export const assistantRouter = createTRPCRouter({ .where(eq(assistantThreads.id, input.threadId)); }), - setThreadStatus: protectedProcedure - .input(z.object({ threadId: z.string().max(64), status: z.enum(["regular", "archived"]) })) - .mutation(async ({ ctx, input }) => { - await ownedThreadAsync(ctx.db, input.threadId, ctx.session.user.id); - await ctx.db - .update(assistantThreads) - .set({ status: input.status, updatedAt: new Date() }) - .where(eq(assistantThreads.id, input.threadId)); - }), - deleteThread: protectedProcedure .input(z.object({ threadId: z.string().max(64) })) .mutation(async ({ ctx, input }) => { diff --git a/packages/db/migrations/mysql/0044_add_assistant.sql b/packages/db/migrations/mysql/0044_add_assistant.sql index f52838255..511ab6a81 100644 --- a/packages/db/migrations/mysql/0044_add_assistant.sql +++ b/packages/db/migrations/mysql/0044_add_assistant.sql @@ -16,7 +16,6 @@ CREATE TABLE `assistant_thread` ( `user_id` varchar(64) NOT NULL, `title` varchar(256), `model_id` varchar(256), - `status` varchar(16) DEFAULT 'regular' NOT NULL, `created_at` timestamp DEFAULT (now()) NOT NULL, `updated_at` timestamp DEFAULT (now()) NOT NULL, CONSTRAINT `assistant_thread_id` PRIMARY KEY(`id`) diff --git a/packages/db/migrations/postgresql/0010_workable_shard.sql b/packages/db/migrations/postgresql/0010_workable_shard.sql index 706fd1da9..4779e359f 100644 --- a/packages/db/migrations/postgresql/0010_workable_shard.sql +++ b/packages/db/migrations/postgresql/0010_workable_shard.sql @@ -24,7 +24,6 @@ CREATE TABLE "assistant_thread" ( "user_id" varchar(64) NOT NULL, "title" varchar(256), "model_id" varchar(256), - "status" varchar(16) DEFAULT 'regular' NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL, "updated_at" timestamp DEFAULT now() NOT NULL ); diff --git a/packages/db/migrations/postgresql/meta/0010_snapshot.json b/packages/db/migrations/postgresql/meta/0010_snapshot.json index caf783f6f..8c1e26904 100644 --- a/packages/db/migrations/postgresql/meta/0010_snapshot.json +++ b/packages/db/migrations/postgresql/meta/0010_snapshot.json @@ -404,13 +404,6 @@ "primaryKey": false, "notNull": false }, - "status": { - "name": "status", - "type": "varchar(16)", - "primaryKey": false, - "notNull": true, - "default": "'regular'" - }, "created_at": { "name": "created_at", "type": "timestamp", diff --git a/packages/db/migrations/sqlite/0042_bumpy_tattoo.sql b/packages/db/migrations/sqlite/0042_bumpy_tattoo.sql index d4c304d33..d074a979f 100644 --- a/packages/db/migrations/sqlite/0042_bumpy_tattoo.sql +++ b/packages/db/migrations/sqlite/0042_bumpy_tattoo.sql @@ -25,7 +25,6 @@ CREATE TABLE `assistant_thread` ( `user_id` text NOT NULL, `title` text, `model_id` text, - `status` text DEFAULT 'regular' NOT NULL, `created_at` integer DEFAULT (unixepoch()) NOT NULL, `updated_at` integer DEFAULT (unixepoch()) NOT NULL, FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE cascade diff --git a/packages/db/migrations/sqlite/meta/0042_snapshot.json b/packages/db/migrations/sqlite/meta/0042_snapshot.json index 1a5f870cb..73fb43f1b 100644 --- a/packages/db/migrations/sqlite/meta/0042_snapshot.json +++ b/packages/db/migrations/sqlite/meta/0042_snapshot.json @@ -406,14 +406,6 @@ "notNull": false, "autoincrement": false }, - "status": { - "name": "status", - "type": "text", - "primaryKey": false, - "notNull": true, - "autoincrement": false, - "default": "'regular'" - }, "created_at": { "name": "created_at", "type": "integer", diff --git a/packages/db/schema/mysql.ts b/packages/db/schema/mysql.ts index 0fae9143f..5f1b1be61 100644 --- a/packages/db/schema/mysql.ts +++ b/packages/db/schema/mysql.ts @@ -518,7 +518,6 @@ export const assistantThreads = mysqlTable( .references(() => users.id, { onDelete: "cascade" }), title: varchar({ length: 256 }), modelId: varchar({ length: 256 }), - status: varchar({ length: 16 }).$type<"regular" | "archived">().notNull().default("regular"), createdAt: timestamp().notNull().defaultNow(), updatedAt: timestamp().notNull().defaultNow(), }, diff --git a/packages/db/schema/postgresql.ts b/packages/db/schema/postgresql.ts index 0e596db6c..6fb9fc6dc 100644 --- a/packages/db/schema/postgresql.ts +++ b/packages/db/schema/postgresql.ts @@ -517,7 +517,6 @@ export const assistantThreads = pgTable( .references(() => users.id, { onDelete: "cascade" }), title: varchar({ length: 256 }), modelId: varchar({ length: 256 }), - status: varchar({ length: 16 }).$type<"regular" | "archived">().notNull().default("regular"), createdAt: timestamp().notNull().defaultNow(), updatedAt: timestamp().notNull().defaultNow(), }, diff --git a/packages/db/schema/sqlite.ts b/packages/db/schema/sqlite.ts index 60182f818..6d8b1e67b 100644 --- a/packages/db/schema/sqlite.ts +++ b/packages/db/schema/sqlite.ts @@ -505,7 +505,6 @@ export const assistantThreads = sqliteTable( .references(() => users.id, { onDelete: "cascade" }), title: text(), modelId: text(), - status: text().$type<"regular" | "archived">().notNull().default("regular"), createdAt: int({ mode: "timestamp" }) .notNull() .default(sql`(unixepoch())`), diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index 9eccca74b..b587f9648 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -1523,11 +1523,7 @@ "signIn": "Sign in to use Homarr Assistant." }, "newConversation": "New conversation", - "archivedConversation": "Archived conversation", "conversations": "Conversations", - "archived": "Archived", - "archive": "Archive", - "restore": "Restore", "delete": "Delete", "closeHistory": "Close conversation history", "openHistory": "Open conversation history",