chore: reconcile assistant layer after stack rebase
This commit is contained in:
1 parent
83f80eb9a7
commit
87f264a286
13 files changed
+8185
-62
No files matched your search
@@ -1,55 +0,0 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
import { buildAiPrompt } from "./_copy-ai-prompt-button";
|
||||
|
||||
const schema = {
|
||||
type: "object",
|
||||
required: ["name", "url", "displayType", "displayConfig"],
|
||||
};
|
||||
|
||||
describe("buildAiPrompt", () => {
|
||||
test("asks Homarr Assistant to create a definition and includes the user's request", () => {
|
||||
const prompt = buildAiPrompt(
|
||||
schema,
|
||||
'{"status":"online"}',
|
||||
{
|
||||
$schema: "homarr-custom-widget-v2",
|
||||
name: "Status",
|
||||
url: "https://example.com/status",
|
||||
},
|
||||
"Show a compact green status when the service is online.",
|
||||
);
|
||||
|
||||
expect(prompt).toContain("`customWidget_create`");
|
||||
expect(prompt).toContain("`secrets: []`");
|
||||
expect(prompt).toContain("do not ask for typed confirmation");
|
||||
expect(prompt).toContain('```json\n{"status":"online"}\n```');
|
||||
expect(prompt).toContain('"name": "Status"');
|
||||
expect(prompt).toContain("Show a compact green status when the service is online.");
|
||||
});
|
||||
|
||||
test("asks Homarr Assistant to update the selected definition without replacing its secrets", () => {
|
||||
const prompt = buildAiPrompt(
|
||||
schema,
|
||||
null,
|
||||
{
|
||||
name: "Existing widget",
|
||||
authType: "bearer",
|
||||
},
|
||||
"Use a progress bar.",
|
||||
"widget-definition-id",
|
||||
);
|
||||
|
||||
expect(prompt).toContain("custom widget definition `widget-definition-id`");
|
||||
expect(prompt).toContain("`customWidget_update`");
|
||||
expect(prompt).toContain("Preserve configured secrets by omitting the `secrets` field");
|
||||
expect(prompt).not.toContain('"secrets"');
|
||||
});
|
||||
|
||||
test("keeps copy-to-clipboard prompts useful before a request is entered", () => {
|
||||
const prompt = buildAiPrompt(schema);
|
||||
|
||||
expect(prompt).toContain("PASTE_YOUR_API_RESPONSE_HERE");
|
||||
expect(prompt).toContain("Describe what you want the widget to show or change here.");
|
||||
});
|
||||
});
|
||||
@@ -213,6 +213,7 @@ export const AssistantConfigureWidgetTool = ({
|
||||
openModal(
|
||||
{
|
||||
kind: args.kind,
|
||||
definition: widgetImports[args.kind].definition,
|
||||
value: configuration.value,
|
||||
integrationData: configuration.integrationData,
|
||||
integrationSupport: configuration.integrationSupport,
|
||||
|
||||
@@ -16,7 +16,6 @@ import { bazarrRouter } from "./router/widgets/bazarr";
|
||||
import { serverSettingsRouter } from "./router/serverSettings";
|
||||
import { beszelRouter } from "./router/widgets/beszel";
|
||||
import { calendarRouter } from "./router/widgets/calendar";
|
||||
import { customWidgetRouter } from "./router/custom-widget/custom-widget-router";
|
||||
import { dnsHoleRouter } from "./router/widgets/dns-hole";
|
||||
import { downloadsRouter } from "./router/widgets/downloads";
|
||||
import { healthMonitoringRouter } from "./router/widgets/health-monitoring";
|
||||
@@ -40,7 +39,6 @@ export const mcpRouter = createTRPCRouter({
|
||||
serverSettings: serverSettingsRouter,
|
||||
beszel: beszelRouter,
|
||||
calendar: calendarRouter,
|
||||
customWidget: customWidgetRouter,
|
||||
dnsHole: dnsHoleRouter,
|
||||
downloads: downloadsRouter,
|
||||
healthMonitoring: healthMonitoringRouter,
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE `assistant_configuration` ADD `web_search_enabled` boolean DEFAULT false NOT NULL;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1 +0,0 @@
|
||||
ALTER TABLE "assistant_configuration" ADD COLUMN "web_search_enabled" boolean DEFAULT false NOT NULL;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1 +0,0 @@
|
||||
ALTER TABLE `assistant_configuration` ADD `web_search_enabled` integer DEFAULT false NOT NULL;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -536,7 +536,7 @@ export const assistantMessages = pgTable(
|
||||
.references(() => assistantThreads.id, { onDelete: "cascade" }),
|
||||
parentId: varchar({ length: 128 }),
|
||||
format: varchar({ length: 64 }).notNull().default("ai-sdk/v6"),
|
||||
content: text().default(emptySuperJSON).notNull(),
|
||||
content: text().notNull(),
|
||||
createdAt: timestamp().notNull().defaultNow(),
|
||||
},
|
||||
(message) => ({
|
||||
|
||||
@@ -527,7 +527,7 @@ export const assistantMessages = sqliteTable(
|
||||
.references(() => assistantThreads.id, { onDelete: "cascade" }),
|
||||
parentId: text(),
|
||||
format: text().notNull().default("ai-sdk/v6"),
|
||||
content: text().default(emptySuperJSON).notNull(),
|
||||
content: text().notNull(),
|
||||
createdAt: int({ mode: "timestamp" })
|
||||
.notNull()
|
||||
.default(sql`(unixepoch())`),
|
||||
|
||||
@@ -34,6 +34,7 @@ import {
|
||||
IconPhoto,
|
||||
IconReportSearch,
|
||||
IconRocket,
|
||||
IconRobot,
|
||||
IconRoute,
|
||||
IconRss,
|
||||
IconServer2,
|
||||
@@ -56,6 +57,7 @@ export const widgetCatalogIcons: Record<WidgetKind, TablerIcon> = {
|
||||
clock: IconClock,
|
||||
weather: IconCloud,
|
||||
app: IconApps,
|
||||
assistant: IconRobot,
|
||||
iframe: IconBrowser,
|
||||
video: IconDeviceCctv,
|
||||
notebook: IconNotes,
|
||||
|
||||
@@ -25,6 +25,7 @@ const moduleLoaders: Record<WidgetKind, () => Promise<WidgetModule>> = {
|
||||
clock: () => import("./clock") as Promise<WidgetModule>,
|
||||
weather: () => import("./weather") as Promise<WidgetModule>,
|
||||
app: () => import("./app") as Promise<WidgetModule>,
|
||||
assistant: () => import("./assistant") as Promise<WidgetModule>,
|
||||
archiveTeamWarrior: () => import("./archive-team-warrior") as Promise<WidgetModule>,
|
||||
anchorNote: () => import("./anchor-note") as Promise<WidgetModule>,
|
||||
notebook: () => import("./notebook") as Promise<WidgetModule>,
|
||||
@@ -85,6 +86,7 @@ const componentLoaders: Record<WidgetKind, () => Promise<WidgetComponentModule>>
|
||||
clock: () => import("./clock/component") as Promise<WidgetComponentModule>,
|
||||
weather: () => import("./weather/component") as Promise<WidgetComponentModule>,
|
||||
app: () => import("./app/component") as Promise<WidgetComponentModule>,
|
||||
assistant: () => import("./assistant/component") as Promise<WidgetComponentModule>,
|
||||
archiveTeamWarrior: () => import("./archive-team-warrior/component") as Promise<WidgetComponentModule>,
|
||||
anchorNote: () => import("./anchor-note/component") as Promise<WidgetComponentModule>,
|
||||
notebook: () => import("./notebook/component") as Promise<WidgetComponentModule>,
|
||||
|
||||
Reference in new issue
Block a user