diff --git a/gadget-code/src/models/user.ts b/gadget-code/src/models/user.ts index 98c14df..ef8c061 100644 --- a/gadget-code/src/models/user.ts +++ b/gadget-code/src/models/user.ts @@ -25,6 +25,7 @@ export const UserSchema = new Schema({ password: { type: String, required: true, select: false }, displayName: { type: String, minlength: 3, maxlength: 30, required: true }, flags: { type: UserFlagsSchema, required: true }, + persona: { type: String }, }); export const User = model("User", UserSchema); diff --git a/gadget-code/src/services/chat-session.ts b/gadget-code/src/services/chat-session.ts index 584aef3..bee0e81 100644 --- a/gadget-code/src/services/chat-session.ts +++ b/gadget-code/src/services/chat-session.ts @@ -6,6 +6,7 @@ import env from "../config/env.js"; import path from "node:path"; import fs from "node:fs"; +import dayjs from "dayjs"; import { IChatSession, @@ -24,6 +25,7 @@ import ChatSession from "../models/chat-session.js"; import ChatTurn from "../models/chat-turn.js"; import Project from "../models/project.js"; import AiProvider from "../models/ai-provider.js"; +import { IAiProvider } from "@gadget/api"; class ChatSessionService extends DtpService { private populateSession: PopulateOptions[] = [ @@ -279,6 +281,12 @@ class ChatSessionService extends DtpService { } async buildSystemPrompt(session: IChatSession): Promise { + const TIMESTAMP_FORMAT = "YYYY-MM-DD hh:mm a"; + + const user = session.user as IUser; + const provider = session.provider as IAiProvider; + const project = session.project as IProject; + const commonDir = path.join(env.installDir, "data", "prompts", "common"); const promptsDir = path.join( env.installDir, @@ -299,6 +307,33 @@ class ChatSessionService extends DtpService { ), }; + /* + * User Persona + */ + const personaBlock = [ + `USER ID: ${user._id}`, + `NAME: ${user.displayName}`, + `IS ADMIN: ${user.flags.isAdmin ? "YES" : "NO"}`, + `---[BEGIN PERSONA]---`, + user.persona || + "I haven't set a persona. Encourage me to visit Settings and describe myself!", + `---[END PERSONA]---`, + ].join("\n"); + + /* + * Session Information + */ + const sessionBlock = [ + `Session ID: ${session._id}`, + `Session Name: ${session.name}`, + `Session Created At: ${dayjs(session.createdAt).format(TIMESTAMP_FORMAT)}`, + `AI Provider: ${provider.name}`, + `AI API: ${provider.apiType}`, + `Large Language Model: ${session.selectedModel}`, + `Project Name: ${project.name}`, + `Project Created At: ${dayjs(project.createdAt).format(TIMESTAMP_FORMAT)}`, + ].join("\n"); + const templateFilename = path.join(promptsDir, "system.md"); const promptTemplate = await fs.promises.readFile( templateFilename, @@ -307,7 +342,9 @@ class ChatSessionService extends DtpService { let prompt = promptTemplate .replace("{{scope_block}}", common.scopeBlock) - .replace("{{subagent_section}}", common.subagentsBlock); + .replace("{{subagent_section}}", common.subagentsBlock) + .replace("{{session_block}}", sessionBlock) + .replace("{{persona_block}}", personaBlock); return prompt; } diff --git a/packages/api/src/interfaces/user.ts b/packages/api/src/interfaces/user.ts index bdf88ce..d10e028 100644 --- a/packages/api/src/interfaces/user.ts +++ b/packages/api/src/interfaces/user.ts @@ -20,6 +20,7 @@ export interface IUser { password?: string; displayName: string; flags: IUserFlags; + persona?: string; } export type UserDocument = HydratedDocument;