Prompt gallery (#957)
- [x] show prompt instead of app in autocomplete - [x] use proper array/list for db (tags) - [x] don't do <dyad-prompt> - replace inline
This commit is contained in:
@@ -61,6 +61,9 @@ import { FileUploadsState } from "../utils/file_uploads_state";
|
||||
import { OpenAIResponsesProviderOptions } from "@ai-sdk/openai";
|
||||
import { extractMentionedAppsCodebases } from "../utils/mention_apps";
|
||||
import { parseAppMentions } from "@/shared/parse_mention_apps";
|
||||
import { prompts as promptsTable } from "../../db/schema";
|
||||
import { inArray } from "drizzle-orm";
|
||||
import { replacePromptReference } from "../utils/replacePromptReference";
|
||||
|
||||
type AsyncIterableStream<T> = AsyncIterable<T> & ReadableStream<T>;
|
||||
|
||||
@@ -274,6 +277,26 @@ export function registerChatStreamHandlers() {
|
||||
|
||||
// Add user message to database with attachment info
|
||||
let userPrompt = req.prompt + (attachmentInfo ? attachmentInfo : "");
|
||||
// Inline referenced prompt contents for mentions like @prompt:<id>
|
||||
try {
|
||||
const matches = Array.from(userPrompt.matchAll(/@prompt:(\d+)/g));
|
||||
if (matches.length > 0) {
|
||||
const ids = Array.from(new Set(matches.map((m) => Number(m[1]))));
|
||||
const referenced = await db
|
||||
.select()
|
||||
.from(promptsTable)
|
||||
.where(inArray(promptsTable.id, ids));
|
||||
if (referenced.length > 0) {
|
||||
const promptsMap: Record<number, string> = {};
|
||||
for (const p of referenced) {
|
||||
promptsMap[p.id] = p.content;
|
||||
}
|
||||
userPrompt = replacePromptReference(userPrompt, promptsMap);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error("Failed to inline referenced prompts:", e);
|
||||
}
|
||||
if (req.selectedComponent) {
|
||||
let componentSnippet = "[component snippet not available]";
|
||||
try {
|
||||
|
||||
91
src/ipc/handlers/prompt_handlers.ts
Normal file
91
src/ipc/handlers/prompt_handlers.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { IpcMainInvokeEvent } from "electron";
|
||||
import log from "electron-log";
|
||||
import { createLoggedHandler } from "./safe_handle";
|
||||
import { db } from "@/db";
|
||||
import { prompts } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import {
|
||||
CreatePromptParamsDto,
|
||||
PromptDto,
|
||||
UpdatePromptParamsDto,
|
||||
} from "../ipc_types";
|
||||
|
||||
const logger = log.scope("prompt_handlers");
|
||||
const handle = createLoggedHandler(logger);
|
||||
|
||||
export function registerPromptHandlers() {
|
||||
handle("prompts:list", async (): Promise<PromptDto[]> => {
|
||||
const rows = db.select().from(prompts).all();
|
||||
return rows.map((r) => ({
|
||||
id: r.id!,
|
||||
title: r.title,
|
||||
description: r.description ?? null,
|
||||
content: r.content,
|
||||
createdAt: r.createdAt,
|
||||
updatedAt: r.updatedAt,
|
||||
}));
|
||||
});
|
||||
|
||||
handle(
|
||||
"prompts:create",
|
||||
async (
|
||||
_e: IpcMainInvokeEvent,
|
||||
params: CreatePromptParamsDto,
|
||||
): Promise<PromptDto> => {
|
||||
const { title, description, content } = params;
|
||||
if (!title || !content) {
|
||||
throw new Error("Title and content are required");
|
||||
}
|
||||
const result = db
|
||||
.insert(prompts)
|
||||
.values({
|
||||
title,
|
||||
description: description ?? null,
|
||||
content,
|
||||
})
|
||||
.run();
|
||||
|
||||
const id = Number(result.lastInsertRowid);
|
||||
const row = db.select().from(prompts).where(eq(prompts.id, id)).get();
|
||||
if (!row) throw new Error("Failed to fetch created prompt");
|
||||
return {
|
||||
id: row.id!,
|
||||
title: row.title,
|
||||
description: row.description ?? null,
|
||||
content: row.content,
|
||||
createdAt: row.createdAt,
|
||||
updatedAt: row.updatedAt,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
handle(
|
||||
"prompts:update",
|
||||
async (
|
||||
_e: IpcMainInvokeEvent,
|
||||
params: UpdatePromptParamsDto,
|
||||
): Promise<void> => {
|
||||
const { id, title, description, content } = params;
|
||||
if (!id) throw new Error("Prompt id is required");
|
||||
if (!title || !content) throw new Error("Title and content are required");
|
||||
const now = new Date();
|
||||
db.update(prompts)
|
||||
.set({
|
||||
title,
|
||||
description: description ?? null,
|
||||
content,
|
||||
updatedAt: now,
|
||||
})
|
||||
.where(eq(prompts.id, id))
|
||||
.run();
|
||||
},
|
||||
);
|
||||
|
||||
handle(
|
||||
"prompts:delete",
|
||||
async (_e: IpcMainInvokeEvent, id: number): Promise<void> => {
|
||||
if (!id) throw new Error("Prompt id is required");
|
||||
db.delete(prompts).where(eq(prompts.id, id)).run();
|
||||
},
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user