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.
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
| Scope | Why |
|---|---|
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:emit | notify other apps in real time when a lesson finishes |
ai:host:chat | host the tutor chat on PAMbase (if you have no LLM) |
context:read:app.session.start | fetch 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.
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 },});
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.
// A · grounded tutor chatconst system = await pambase.systemPrompt(); // → a system-prompt stringconst reply = await myLLM.create({ system, messages: history });// B · adapt difficulty with no LLMconst 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.
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
goalscope and standard taxonomy.