Skip to documentation
Docs navigation
Docs/Personal assistant
Example

Personal assistant

Build an assistant that remembers preferences and routines, recalls only relevant context, and forgets an outdated fact on request.

Estimated time: 10 minutes
Level: Intermediate

Overview

This example stores explicit preferences with remember(), organizes the active assistant session with tags, recalls scheduling context, and demonstrates user-directed forgetting.

MemoGrafter supplies memory; calendar scheduling, reminders, tool execution, and task completion remain application responsibilities.

What this demonstrates

Storing natural-language preferences without an assistant turn.
Organizing an active session with normalized tags.
Targeted recall for a planning request.
Resolving an exact memory ID before forgetting it.
Verifying that forgotten memory leaves active recall but remains auditable.

Architecture

Explicit preferences
Tagged session
Targeted recall
Planning response
Lifecycle control

Memory design

Preferences: meeting time, answer style, and dietary choices.
Routines: stable patterns the assistant may use during planning.
Tasks: remembered context, not executable scheduled jobs.
Tags: broad assistant and planning organization within the current session.

Step 1: Tag the assistant session

Tags are normalized and applied to existing and future topic and memory rows in the current agent session.

assistant.ts
await agent.setSessionTags([
  "assistant",
  "planning",
  "user:alice",
]);

Step 2: Store preferences

assistant.ts
await agent.remember(
  "Alice prefers meetings after 9:30 in the morning.",
  { label: "Scheduling preference", source: "profile-settings" },
);

await agent.remember(
  "Alice prefers concise planning summaries.",
  { label: "Response preference", source: "profile-settings" },
);

Step 3: Recall relevant context

assistant.ts
const context = await agent.recall("Schedule a planning call", {
  tags: ["assistant", "planning"],
  scope: "session-and-tags",
  limit: 5,
});

console.log(context.facts);

Step 4: Forget an outdated preference

assistant.ts
const preferences = await agent.recall("meeting time preference", {
  minSimilarity: 0.4,
});

const outdated = preferences.facts.find((fact) =>
  fact.value.includes("9:30"),
);

if (outdated) {
  await agent.forget(outdated.id);
}

Complete example

src/personal-assistant.ts
import "dotenv/config";

import {
  MemoGrafterAgent,
  OpenAIEmbedAdapter,
  OpenAILLMAdapter,
} from "memo-grafter";

const agent = new MemoGrafterAgent({
  db: { connectionString: process.env.DATABASE_URL! },
  llm: new OpenAILLMAdapter("gpt-4o"),
  embedder: new OpenAIEmbedAdapter("text-embedding-3-small"),
});

await agent.initialize();

try {
  await agent.setSessionTags(["assistant", "planning", "user:alice"]);
  await agent.remember(
    "Alice prefers meetings after 9:30 in the morning.",
    { label: "Scheduling preference", source: "profile-settings" },
  );
  await agent.remember(
    "Alice prefers concise planning summaries.",
    { label: "Response preference", source: "profile-settings" },
  );

  const context = await agent.recall("Plan a morning project meeting", {
    tags: ["assistant", "planning"],
    scope: "session-and-tags",
    limit: 5,
  });

  console.log(context.facts);
  console.log(await agent.invoke("Suggest a time for a planning meeting."));
} finally {
  await agent.close();
}

Expected behavior

Recall returns the meeting-time preference when extraction created a matching memory.
The assistant recommends a time after 9:30 and keeps the answer concise.
After the exact meeting preference is forgotten, active recall no longer includes that memory.
Snapshots and history can still display the forgotten row for audit.

What gets stored

Natural-language profile facts processed through the same extraction pipeline as raw text.
Topic and memory nodes carrying the normalized assistant tags.
Source metadata identifying profile settings.
A forgotten lifecycle flag and timestamp when the user retires a preference.

Inspect it in Studio

Open the agent session and inspect the scheduling topic.
Confirm the meeting-time fact, tags, confidence, and source.
Use Prompt Preview for “Plan a morning meeting.”
After forgetting the preference, confirm the lifecycle state remains visible while active preview excludes it.

Common mistakes

Treating remember() as a deterministic row insert rather than LLM-backed extraction.
Assuming MemoGrafter schedules or executes calendar actions.
Forgetting a memory without resolving and authorizing its exact ID.
Using tags as an authentication boundary.
Expecting forgotten memory to be physically deleted.

Extensions

Add separate planning and wellness tags.
Use memory history for preferences that change over time.
Graft selected preferences into another specialized assistant.
Add a privacy review surface before lifecycle actions.