Skip to content

Guided tour

FabrCore 2.0 · Release and package availability

These guides track the current 2.0 source. Stable 2.0.0 publication is pending; package commands show the release target. Until it is published, follow the source quick start or use a matching available prerelease set. Release migration · Runtime modes

MODULE 09 · LESSON 9.2

Save and recall Memory from C# and tools

Save and recall facts using code or the agent-memory plugin.

Lesson 49 of 86 · FabrCore 2.0

Overview

IAgentMemoryProvider supplies a scope-bound IAgentMemoryService. Direct calls are useful when the application knows a fact is confirmed; model tools are useful when the agent needs retrieval. Using both is fine if each concern has one owner.

A provider binds the service to its scope

Resolve IAgentMemoryService through the trusted IAgentMemoryProvider for the agent's principal/scope. Code can save a confirmed fact directly, while exposed memory tools let the model request retrieval. The service should not accept an arbitrary principal supplied by the prompt as its authority. One clear owner should decide when inferred information becomes durable.

A correction is a lifecycle operation

If a user changes a preference, update or supersede the old fact through the supported lifecycle rather than accumulating contradictory statements indefinitely. Recall should provide the applicable active fact and its context. Memory is useful because it outlives a single chat thread, but its actual process durability still depends on the configured SQL-backed feature and storage.

Save and recall a scoped fact

  1. Enable SQL mode and configure the required models. Resolve Memory through trusted scope selection.
  2. Save a verified preference with source/time metadata and keep its returned ID. Choose Fact, Rule, Instruction, Observation or Procedural intentionally.
  3. Recall before answering; use explicit ID updates for corrections and ForgetMemory for deletion. Select agent-memory tools without registering the same functions twice.
memory-lifecycle.cs
using FabrCore.Services.Memory.Abstractions;
using FabrCore.Services.Memory.Models;

// Call these methods from OnMessage or other application-controlled agent methods.
public static class MemoryLifecycle
{
    public static async Task<Guid> RememberPreferenceAsync(IAgentMemoryService memory, CancellationToken ct = default)
    {
        var entry = await memory.SaveMemoryAsync("Response preference", MemoryType.Instruction,
            "The user prefers concise responses.", metadata: new() { ["source"] = "explicit-user-preference" }, ct: ct);
        return entry.Id; // Persist this ID in application state if later updates need it.
    }

    public static Task<MemoryEntry> ArchiveAsync(IAgentMemoryService memory, Guid id, CancellationToken ct = default)
        => memory.UpdateMemoryAsync(id, temperature: MemoryTemperature.Cold, ct: ct);

    public static Task<MemoryEntry> RestoreAsync(IAgentMemoryService memory, Guid id, CancellationToken ct = default)
        => memory.UpdateMemoryAsync(id, temperature: MemoryTemperature.Warm, ct: ct);

    public static async Task<string> RecallAsync(IAgentMemoryService memory, string query, CancellationToken ct = default)
        => memory.FormatRecallContext(await memory.RecallAsync(query, ct: ct));
}

Recall across threads and test a correction

  1. In a SQL-ready development environment, use the sample to save a confirmed preference for one test principal, such as “Use concise status summaries.” Record its identity and scope.
  2. Start a different conversation for that same principal and retrieve the preference. Verify the returned fact is the one saved, not a fact the model simply repeated from the current prompt.
  3. Correct the preference through the supported API and repeat recall. Also query from another principal without a grant; the first user's preference must not be exposed.

This checks write, cross-thread recall, correction and ownership. A fluent answer alone cannot establish that the scoped Memory service was consulted.

If the result is different

Similarity is not identity. Merge-on-save may preserve conflicting text; use explicit updates for authoritative corrections and point-in-time metadata for snapshots.

Go deeper

Explore the related documentation.