"use server"; import { requireUserId } from "@/lib/auth-helpers"; import { getAllGroupsForUser } from "@/lib/board"; import { formatAllGroupsForPrompt } from "@/lib/ai/context"; import { callChatCompletion } from "@/lib/ai/chat-completion"; export interface ChatMessage { role: "user" | "assistant"; content: string; } export type GlobalChatResult = { content: string } | { error: string }; const SYSTEM_PROMPT_HEADER = `You are a helpful assistant answering questions about the user's personal/team to-do board app. Below is the full current state of every board they own, including completed to-dos and archived groups (kept so you can answer historical questions like "what did we do about X"). Answer only using the information below. If the answer isn't in it, say so plainly instead of guessing. When it's helpful, mention which project/category/group the information came from. `; /** * Free-form Q&A across everything the user owns (Home board + every * Project), for the global Chat page. Re-fetches and re-serializes the * full context on every turn -- simpler and always fresh, and re-checks * the user's own access each call the same way the existing group-scoped * AI actions do (lib/actions/group-ai.ts, lib/actions/todo-ai.ts). * Unlike those, there's no artifact to save, so this returns the model's * plain-text reply directly rather than an ask/finalize JSON contract. */ export async function sendChatMessage(messages: ChatMessage[]): Promise { const userId = await requireUserId(); const groups = await getAllGroupsForUser(userId); const context = formatAllGroupsForPrompt(groups); const systemPrompt = `${SYSTEM_PROMPT_HEADER}${context}`; return callChatCompletion([{ role: "system", content: systemPrompt }, ...messages], { temperature: 0.3, }); }