boxbrain
v0.4.0
Published
Human-like persona harness framework powered by LLMs and IdentityDB.
Maintainers
Readme
BoxBrain
BoxBrain is a TypeScript framework for designing LLM harnesses that make a persona feel like a real person, backed by IdentityDB memory spaces.
This repository was reset from scratch. The current implementation focuses on a clean framework core rather than a concrete chatbot product.
Goals
BoxBrain helps API users build an LLM-driven persona with:
- persona initialization into an isolated IdentityDB-backed space
- realistic schedule generation
- schedule-derived availability (
online,do-not-disturb,offline) - reply and proactive conversation APIs
- sleep-time memory extraction into durable facts
- debug hooks that expose the framework flow and persona reasoning pipeline
Install
bun installCore API
import { Persona, createSqliteIdentityMemoryStore } from 'boxbrain';
const memory = await createSqliteIdentityMemoryStore('.data/mina.sqlite');
const persona = new Persona(
'Mina',
'Mina is a careful student who likes quiet cafes and is preparing for exams.',
{
memory,
models: {
conversation: yourConversationModel,
memoryExtraction: yourMemoryExtractionModel,
},
debug: (event) => console.log(event),
},
);
const space = await persona.ready();A persona can also be loaded from an existing space:
const persona = new Persona(space.id, { memory, models });
await persona.ready();Persona initialization
new Persona(displayName, message, options) creates a new isolated persona space. The seed message is the single freeform place for personality, history, likes, dislikes, relationships, and other facts about the persona.
new Persona(spaceId, options) loads an existing persona space.
If models.initialization is provided, BoxBrain asks it for initial facts. If no initialization model is provided, BoxBrain stores a minimal seed fact about the persona. If the model intentionally returns an empty list, no fallback fact is stored.
Schedule API
await persona.createDailySchedule(now, 'Keep a normal work day.');
await persona.createMonthlySchedule(now, 'Mostly study, with occasional rest.');
await persona.deleteSchedulesBefore(cutoff);
await persona.deleteSchedulesOlderThan(cutoff);createDailySchedule(datetime, message) creates tomorrow's schedule in 10-minute blocks. For example, if datetime is May 1, the generated daily schedule covers May 2 00:00 through May 3 00:00.
createMonthlySchedule(datetime, message) creates day-level schedule outlines for the next 30 days.
Schedules are stored through the configured memory store. The IdentityDB store records schedule entries as facts under schedule-related topics.
Availability API
const availability = await persona.getTodayScheduledAvailability(now);Availability is derived from schedule entries and kept in memory rather than persisted separately. The window covers today 00:00 through tomorrow 24:00. When the date changes, BoxBrain rebuilds the snapshot from schedule entries in memory.
Schedule activities map to availability roughly as:
sleep→offlinework,study,job-search,travel,commute→do-not-disturb- rest, meals, exercise, errands, social time, free time →
online
Conversation API
const reply = await persona.sendMessage({
datetime: now,
messageHistory: [
{ sender: 'persona', time: yesterday, content: 'See you later.' },
{ sender: 'user', time: now, content: 'What are you doing?' },
],
});
const opener = await persona.startConversation({
datetime: now,
messageHistory: [],
});Before generating a reply, BoxBrain always loads mandatory context:
- formatted yesterday/today message history supplied by the API user
- yesterday, today, and tomorrow schedule entries
- current schedule-derived availability
- IdentityDB facts related to the persona and the user
If no relevant mandatory memory is found, the model context explicitly says 기억이 없음 so the persona can react naturally instead of pretending to remember.
Conversation models return one or more outgoing messages. The framework instruction tells the model to behave like a send_message tool and, unless the persona prefers otherwise, keep each message to at most one sentence.
If getLatestMessageHistory and models.rewrite are provided, BoxBrain can detect messages that arrived while a draft was being generated and ask the rewrite model whether to discard and regenerate the stale draft.
sleepMemory
await persona.sleepMemory({
datetime: '2026-05-02T00:00:00.000Z',
messageHistory: messagesFromMay1,
});sleepMemory asks models.memoryExtraction to inspect the provided message history, objectivize durable facts, and persist them through the memory store. The recommended cadence is daily around midnight, passing the previous day's messages.
Debug hooks
Every major pipeline step can emit a debug event:
const persona = new Persona('Mina', seed, {
debug(event) {
// Write to a file, messenger, trace UI, etc.
console.log(event.name, event.data);
},
});Examples include:
persona.initializedpersona.loadedpersona.schedule.daily.generatedpersona.availability.refreshedpersona.conversation.context.loadedpersona.conversation.rewrite.checkedpersona.memory.sleep.persisted
Development
bun run test
bun run check
bun run buildThe current test suite covers persona creation/loading, schedule generation/pruning, availability derivation, conversation context assembly, stale-draft rewrite checks, proactive conversation starts, and sleep-memory persistence.
