***

title: Memory (RAG)
description: Remote NPC memory and local node-backed recall
slug: ue/memory
---------------

The UE plugin exposes two memory layers:

* remote NPC memory backed by the Forboc API
* local node-backed memory backed by SQLite plus local embeddings

This matches the split between `packages/core` and `packages/node`.

<Note>
  During `processNPC(...)`, the API can request memory recall or memory storage. If the runtime does not have local memory configured and the API asks for those steps, the protocol fails fast.
</Note>

## Memory Item Shape

```cpp
USTRUCT(BlueprintType)
struct FMemoryItem {
  UPROPERTY(BlueprintReadOnly) FString Id;
  UPROPERTY(BlueprintReadOnly) FString Text;
  UPROPERTY(BlueprintReadOnly) TArray<float> Embedding;
  UPROPERTY(BlueprintReadOnly) int64 Timestamp;
  UPROPERTY(BlueprintReadOnly) FString Type;
  UPROPERTY(BlueprintReadOnly) float Importance;
  UPROPERTY(BlueprintReadOnly) float Similarity;
};
```

## Local Node Memory

Use local memory when you want the UE runtime to satisfy protocol recall/store instructions directly.

```cpp
#include "RuntimeStore.h"
#include "CLI/CliOperations.h"

auto Store = createSDKStore();

SDKOps::InitNodeMemory(Store, TEXT("/tmp/merchant.db"));
SDKOps::StoreNodeMemory(Store, TEXT("Player bought the old key"), 0.9f);

TArray<FMemoryItem> Recalled =
    SDKOps::RecallNodeMemory(Store, TEXT("key"), 5, 0.7f);

SDKOps::ClearNodeMemory(Store);
```

`initNodeMemoryThunk(DatabasePath)` tracks the active database path, and `clearNodeMemoryThunk()` clears that same resolved path. Custom database locations are supported.

## Remote NPC Memory

Use the remote thunks when you want the API-backed per-NPC memory endpoints.

```cpp
#include "RuntimeStore.h"
#include "CLI/CliOperations.h"
#include "RuntimeConfig.h"

auto Store = createSDKStore();
SDKConfig::SetApiConfig(TEXT("https://api.forboc.ai"), ApiKey);

TArray<FMemoryItem> Listed = SDKOps::MemoryList(Store, TEXT("npc_1"));
TArray<FMemoryItem> RemoteRecall =
    SDKOps::MemoryRecall(Store, TEXT("npc_1"), TEXT("key"), 10, 0.7f);

SDKOps::MemoryStore(Store, TEXT("npc_1"),
                    TEXT("Player bought the old key"), 0.9f);
SDKOps::MemoryClear(Store, TEXT("npc_1"));
```

## Slice State

`MemorySlice` tracks:

* entity-backed memory items
* `StorageStatus`
* `RecallStatus`
* `Error`
* `LastRecalledIds`

Useful selectors:

* `MemorySlice::SelectAllMemories(State)`
* `MemorySlice::SelectLastRecalledMemories(State)`
* `MemorySlice::SelectMemoryById(State, Id)`

## Direct Thunks

For parity with the TypeScript SDKs, dispatch:

* `rtk::initNodeMemoryThunk(DatabasePath)`
* `rtk::storeNodeMemoryThunk(Text, Type, Importance)`
* `rtk::recallNodeMemoryThunk(Query, Limit, Threshold)`
* `rtk::clearNodeMemoryThunk()`
* `rtk::listMemoryRemoteThunk(NpcId)`
* `rtk::recallMemoryRemoteThunk(NpcId, Query, Similarity)`
* `rtk::storeMemoryRemoteThunk(NpcId, Observation, Importance)`
* `rtk::clearMemoryRemoteThunk(NpcId)`
