Files
BoxBrain/src/conversation.ts
2026-05-19 23:24:34 +09:00

72 lines
2.4 KiB
TypeScript

import type {
BoxBrainMemoryStore,
DateTimeInput,
MandatoryConversationContext,
MemorySpace,
PersonaMessage,
ScheduledAvailabilitySnapshot,
} from "./types";
import { addUtcDays, dateKeysAround, startOfUtcDay, toIso } from "./schedule";
export function formatMessageHistory(input: {
personaName: string;
messages: PersonaMessage[];
}): string {
return input.messages
.map((message) => {
const sender = message.sender === "persona" ? input.personaName : "user";
return `${sender}@${toIso(message.time)}: ${message.content}`;
})
.join("\n");
}
export function conversationInstruction(baseSystemPrompt?: string): string {
const parts = [
...(baseSystemPrompt === undefined ? [] : [baseSystemPrompt]),
"You are controlling the persona, not a generic assistant.",
"Use the send_message tool conceptually: return one or more outgoing messages.",
"Unless the persona strongly prefers otherwise, keep each outgoing message to at most one sentence.",
"Prefer short, natural, chat-like wording and allow splitting one thought into multiple messages.",
'If mandatory memory says "기억이 없음", the persona may naturally wonder about missing context instead of pretending to remember.',
];
return parts.join("\n");
}
export async function buildMandatoryConversationContext(input: {
persona: MemorySpace;
now: DateTimeInput;
memory: BoxBrainMemoryStore;
messages: PersonaMessage[];
availability: ScheduledAvailabilitySnapshot;
}): Promise<MandatoryConversationContext> {
const now = startOfUtcDay(input.now);
const from = addUtcDays(now, -1).toISOString();
const to = addUtcDays(now, 2).toISOString();
const scheduleEntries = await input.memory.listScheduleEntries(
input.persona.id,
from,
to,
);
const personaAndUserFacts = await input.memory.findFacts(input.persona.id, [
"persona",
input.persona.displayName,
"user",
]);
const memorySummary =
personaAndUserFacts.length === 0
? "기억이 없음"
: personaAndUserFacts.map((fact) => `- ${fact.statement}`).join("\n");
return {
formattedMessageHistory: formatMessageHistory({
personaName: input.persona.displayName,
messages: input.messages,
}),
conversationWindowLabel: `Required conversation window: yesterday/today. Schedule dates: ${dateKeysAround(input.now).join(", ")}.`,
memorySummary,
personaAndUserFacts,
scheduleEntries,
availability: input.availability,
};
}