72 lines
2.4 KiB
TypeScript
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,
|
|
};
|
|
}
|