PAMbaseDocs
Guide

Tutor.

What you're building

An education app whose tutor chat already knows what the learner has covered and adapts difficulty accordingly. The payoff: progress is stored as portable memory, so a different learning app the user connects later can pick up exactly where you left off.

Prerequisites

You have a connection token from the connect flow with these scopes (one permission each): memory:write:goal.*, memory:read:goal.*, memory:read:note.*, signal:emit, ai:host:chat (lets PAMbase host the chat if you have no LLM), and context:read:app.session.start.

Scopes to request

ScopeWhy
memory:write:goal.*record learning goals and progress
memory:read:goal.*adapt to what the learner is working toward
memory:read:note.*pull in relevant notes the learner saved
signal:emitnotify other apps in real time when a lesson finishes
ai:host:chathost the tutor chat on PAMbase (if you have no LLM)
context:read:app.session.startfetch a context bundle for this intent

What to write

Remember learning progress as durable memory the learner carries between apps — the content is just natural-language text. To also notify other apps the moment a lesson finishes, emit a signal — that part isn't memory.

typescript
await pambase.remember({
content: "Goal: conversational Spanish by August.",
kind: "goal",
scope: "goal.language",
});
// res → { accepted: true, memoryIds: ["mem_…"] } ← goal memory written
// Optional real-time nudge to subscribers (not stored as memory):
await pambase.emitSignal({
type: "lesson.completed",
payload: { topic: "Spanish · preterite tense", score: 0.82 },
});
Signals notify; remember() persists

A signal is ephemeral — it triggers other apps' agents to react now. If you also want a durable record of completed lessons, remember them in a learning scope alongside the signal.

How to read — ground a chat (A) or adapt (B)

Pattern A grounds your own LLM with systemPrompt(), which returns a ready-made system string built from the user's memory. Pattern B skips the LLM and reads a context bundle — memories selected for a named intent — to set difficulty directly.

typescript
// A · grounded tutor chat
const system = await pambase.systemPrompt(); // → a system-prompt string
const reply = await myLLM.create({ system, messages: history });
// B · adapt difficulty with no LLM
const ctx = await pambase.getContext({ intent: "app.session.start" });
// ctx → { identity: { aiId, name }, memories: [{ id, type, scope, content, importance, … }], suggestions, … }
const ahead = ctx.memories.some(
(m) => m.type === "goal" && /fluent|advanced|conversational/i.test(m.content)
);
lesson.difficulty = ahead ? "advanced" : "core";

Proactive (optional)

Call schedule() to set a spaced-repetition reminder; PAMbase fires a schedule.fired webhook back at that time. See webhooks & scheduling.

Goals are the portable payoff

Storing achievements as goal memories in the standard goal.* scope means another learning app the user connects can recall the same goals and continue seamlessly. See the chat how-to for hosted chat, and the Catalog for the standard scope taxonomy.

Next

  • Request context — the bundle behind Pattern B.
  • Chat — hosted chat with ai:host:chat.
  • Catalog — the goal scope and standard taxonomy.