Text Generation
Transformers
Safetensors
PyTorch
English
hfp
causal-lm
linear-attention
long-context
recurrent-memory
o1-memory
custom_code
Instructions to use kayrahan35/HFP-O1-Memory-Model with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use kayrahan35/HFP-O1-Memory-Model with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="kayrahan35/HFP-O1-Memory-Model", trust_remote_code=True)# Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("kayrahan35/HFP-O1-Memory-Model", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use kayrahan35/HFP-O1-Memory-Model with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "kayrahan35/HFP-O1-Memory-Model" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "kayrahan35/HFP-O1-Memory-Model", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/kayrahan35/HFP-O1-Memory-Model
- SGLang
How to use kayrahan35/HFP-O1-Memory-Model with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "kayrahan35/HFP-O1-Memory-Model" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "kayrahan35/HFP-O1-Memory-Model", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "kayrahan35/HFP-O1-Memory-Model" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "kayrahan35/HFP-O1-Memory-Model", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use kayrahan35/HFP-O1-Memory-Model with Docker Model Runner:
docker model run hf.co/kayrahan35/HFP-O1-Memory-Model
| # Hyper Flux Projection (HFP) — O(1)-memory causal language model | |
| # Copyright (C) 2026 Kayrahan Yılmaz | |
| # | |
| # This program is free software: you can redistribute it and/or modify | |
| # it under the terms of the GNU Affero General Public License as published | |
| # by the Free Software Foundation, either version 3 of the License, or | |
| # (at your option) any later version. | |
| # | |
| # This program is distributed in the hope that it will be useful, | |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| # GNU Affero General Public License for more details. | |
| # | |
| # You should have received a copy of the GNU Affero General Public License | |
| # along with this program. If not, see <https://www.gnu.org/licenses/>. | |
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| import logging | |
| logging.basicConfig(level=logging.WARNING, format='[%(levelname)s] %(message)s') | |
| from .hfp_utils import LandmarkBuffer, compute_gate_entropy, coherence_score | |
| from .hfp_config import config as hfp_config | |
| class HFPBulkState(nn.Module): | |
| """ | |
| HFPBulkState V4 (Recurrent Edition): Causal chunkwise linear attention. | |
| [FIX K2 - GRADYAN AKISI] Onceki surumde retrieval, M guncellemesinden ONCE | |
| yapiliyordu; tek-parca egitimde M=0 oldugundan retrieval hep sifirdi ve | |
| W_k/W_v/decay/importance_gate LM loss'tan HIC gradyan alamiyordu (bellek | |
| egitimde olu agirlikti). Bu surum gercek causal lineer attention'dir: | |
| her token, o ana KADARKI kumulatif M/z'den okur (kendi KV'si dahil), | |
| per-token decay ile. Boylece bellek yolu ayni forward icinde ciktiya | |
| baglanir ve TUM bellek parametreleri gradyan alir. | |
| Matematik (RetNet/GLA tarzi chunkwise form, tum usler >= 0 -> stabil): | |
| lam = sigmoid(decay) (K-kanali basina, 0..1) | |
| M_t = lam (.) M_{t-1} + k_t v_t^T , z_t = lam (.) z_{t-1} + k_t | |
| out_t = (q_t M_t) / (q_t . z_t) | |
| Blok ici (m token): | |
| cross: (q_i * lam^i) M_0 intra: S_ij = q_i . (lam^{i-j} (.) k_j), j<=i | |
| Uretim yolu (1 token/cagri) ayni formulun m=1 halidir -> egitim/uretim | |
| decay semantigi artik TUTARLI (eski surum decay'i cagri basina 1 kez | |
| uyguluyordu; 256-token chunk ile 1-token generate farkli davraniyordu). | |
| Onceki yapisal duzeltmeler korunur: | |
| - Matrix blowup: decay init sigmoid(2.19)~0.9 + retrieval LayerNorm. | |
| - Gate collapse: importance_gate bias -2.0. | |
| - Ring buffer: sabit boyutlu, vektorize yazim (Python token-dongusu kaldirildi). | |
| [FIX K4] max_short_len artik parametre: config.short_len > 32 sessizce | |
| kirpilmiyor (1B profili short_len=64 gercekten 64 slot alir). | |
| [FIX D3] batch>16'da sessiz half() donusumu kaldirildi. | |
| """ | |
| def __init__(self, hidden_size, short_len=8, max_short_len=None, | |
| rec_block=64, use_mixed_precision=False, clip_value=1.0, | |
| decay_mode="exp", conv_kernel=3, key_feature_map="elu", dpfp_nu=2): | |
| super(HFPBulkState, self).__init__() | |
| self.hidden_size = hidden_size | |
| self.base_short_len = short_len | |
| # [HFP-CAP] Anahtar ozellik-haritasi ve efektif anahtar boyutu (key_dim). | |
| # "elu": elu(x)+1, key_dim=H (baseline). "dpfp": Deterministic Parameter-Free | |
| # Projection, key_dim=2*H*nu -> daha yuksek efektif boyut, rank-collapse | |
| # geciktirilir, bellek KAPASITESI (kac ayri olgu) artar. M artik (key_dim, H), | |
| # z (key_dim); deger (V) boyutu H olarak kalir. Retention (exp/cubic) ve | |
| # binding conv'dan BAGIMSIZ eksen. | |
| self.key_feature_map = key_feature_map | |
| self.dpfp_nu = max(1, dpfp_nu) | |
| self.key_dim = hidden_size if key_feature_map != "dpfp" else 2 * hidden_size * self.dpfp_nu | |
| # [HFP-CORE] Retention yasasi. "exp" = standart geometrik decay (RetNet/GLA | |
| # ailesi, baseline). "cubic_flux" = makalenin dth/dtau=-eta*th^3 kubik | |
| # akisinin birebir ayriklastirmasi: state-buyuklugune bagli, plato+power-law | |
| # unutma. Ailedeki hicbir modelde olmayan ayirt edici mekanizma. | |
| self.decay_mode = decay_mode | |
| # [FIX K4] Kapasite en az short_len; eskisi gibi sessizce 32'ye kirpma yok. | |
| if max_short_len is None: | |
| max_short_len = max(short_len, getattr(hfp_config, 'MAX_SHORT_LEN', 32)) | |
| assert max_short_len >= short_len, \ | |
| f"max_short_len ({max_short_len}) < short_len ({short_len})" | |
| self.max_short_len = max_short_len | |
| # [K2] Chunk-ici recurrence blok boyutu (dogruluk degil hiz/bellek dengesi; | |
| # sonuc blok boyutundan BAGIMSIZDIR - bkz. smoke_test.py tutarlilik testi). | |
| self.rec_block = max(1, rec_block) | |
| self.landmark_max = hfp_config.LANDMARK_MAX | |
| self.gate_temperature = nn.Parameter(torch.tensor(1.0), requires_grad=False) | |
| self.use_mixed_precision = use_mixed_precision # [D3] no-op; geriye uyumluluk icin duruyor | |
| self.clip_value = clip_value | |
| self.dynamic_short_thresh = hfp_config.ENTROPY_THRESH | |
| # Selective Scan Gating (Information Bottleneck) | |
| self.importance_gate = nn.Linear(hidden_size, hidden_size) | |
| # [GATE COLLAPSE FIX] sigmoid(-2.0) ~ 0.12 baslangici | |
| nn.init.constant_(self.importance_gate.bias, -2.0) | |
| self.gate_dropout = nn.Dropout(0.1) | |
| # [FIX K8 - KISA CAUSAL CONV / BINDING] Lineer-attention BELLEGININ | |
| # associative-recall yapabilmesi icin sart olan token-karisimi. Onceki | |
| # surumde her token bellege KENDI key(x_t)⊗value(x_t)'sini yaziyordu; | |
| # v1'in anahtari onu ONCELEYEN k1'i kodlamadigindan sorgu=k1 ile v1 | |
| # GETIRILEMIYORDU (MQAR loss ln(val_space)'te sabit, full-attention %100). | |
| # Depthwise causal conv (kernel=3) Q/K yoluna uygulanir -> K[v1-pozisyonu] | |
| # artik onceki token k1'i kodlar, Q[k1] ile eslesir. V ORIJINAL x'ten | |
| # (temiz deger). Mamba/H3/Based hepsi bu kisa conv'u icerir. Retention | |
| # yasasindan (exp/cubic_flux) BAGIMSIZ - kimlige dokunmaz. Chunk-tutarlilik | |
| # icin conv state chunk'lar arasi tasinir (T4 korunur). | |
| self.conv_kernel = max(1, conv_kernel) | |
| self.short_conv = nn.Conv1d(hidden_size, hidden_size, kernel_size=self.conv_kernel, | |
| groups=hidden_size, bias=True, padding=0) | |
| # Linear Attention Projections | |
| self.W_q = nn.Linear(hidden_size, hidden_size, bias=False) | |
| self.W_k = nn.Linear(hidden_size, hidden_size, bias=False) | |
| self.W_v = nn.Linear(hidden_size, hidden_size, bias=False) | |
| # [FIX K2b - COK-OLCEKLI DECAY] Eskiden tum kanallar sigmoid(2.19)~0.9 | |
| # ile TEK olcekte baslardi -> bellek ufku ~1/(1-0.9)=10 token; 100 token | |
| # geriden recall matematiksel olarak imkansizdi (lam^100~2e-5). Simdi | |
| # kanal basina lam 0.90..0.999 arasi lineer dagilir (RetNet/GLA-tarzi | |
| # multi-timescale): bazi kanallar ~10 token, bazilari ~1000 token tutar. | |
| # Sigmoid ciktisi (0,1) oldugundan matrix-blowup korumasi korunur; tum | |
| # usler >= 0 stabilite degismez. decay hala LM loss'tan gradyan alir. | |
| # [HFP-CAP] decay/eta artik anahtar-kanali basina -> key_dim boyutunda. | |
| lam_min = getattr(hfp_config, 'DECAY_LAM_MIN', 0.90) | |
| lam_max = getattr(hfp_config, 'DECAY_LAM_MAX', 0.999) | |
| lam_init = torch.linspace(lam_min, lam_max, self.key_dim) | |
| decay_logit = torch.log(lam_init / (1.0 - lam_init)) # sigmoid^{-1} | |
| self.decay = nn.Parameter(decay_logit) | |
| # [HFP-CORE] Kubik-flux esnekligi eta (per-kanal, >0). Tek-adim kararli | |
| # cozumden lam_t = 1/sqrt(1 + 2*eta*s_t^2), s_t = anlik state buyuklugu. | |
| # Gecis olcegi t* ~ 1/sqrt(2*eta): eta buyuk -> kisa plato, kucuk -> uzun. | |
| # Kanallar arasi 1e-4..1e-2 log-dagilir -> plato ~7..70 token, ogrenilebilir. | |
| eta_init = torch.logspace(-4.0, -2.0, self.key_dim) | |
| self.log_eta = nn.Parameter(torch.log(eta_init)) | |
| self.retrieval_norm = nn.LayerNorm(hidden_size) | |
| self.landmark_buffer = LandmarkBuffer(max_size=hfp_config.LANDMARK_MAX) | |
| def _feat(self, u): | |
| """[HFP-CAP] Anahtar/sorgu ozellik-haritasi -> (..., key_dim), hep >= 0.""" | |
| if self.key_feature_map == "dpfp": | |
| u = torch.cat([F.relu(u), F.relu(-u)], dim=-1) # (..., 2H) | |
| parts = [u * torch.roll(u, shifts=i + 1, dims=-1) for i in range(self.dpfp_nu)] | |
| return torch.cat(parts, dim=-1) # (..., 2H*nu) >= 0 | |
| return F.elu(u) + 1.0 # (..., H) > 0 | |
| def get_initial_state(self, batch_size, device, dtype): | |
| M = torch.zeros(batch_size, self.key_dim, self.hidden_size, device=device, dtype=dtype) | |
| z = torch.zeros(batch_size, self.key_dim, device=device, dtype=dtype) | |
| short_memory = torch.zeros(batch_size, self.max_short_len, self.hidden_size, device=device, dtype=dtype) | |
| # [FIX K8] conv_state: onceki chunk'in son (kernel-1) girdisi (causal conv icin) | |
| conv_state = torch.zeros(batch_size, self.conv_kernel - 1, self.hidden_size, device=device, dtype=dtype) | |
| # state: (short_memory, M, z, token_count, short_len_dynamic, write_idx, conv_state) | |
| return (short_memory, M, z, 0, self.base_short_len, 0, conv_state) | |
| def reset_state(self): | |
| self.landmark_buffer.clear() | |
| if hasattr(self, "_last_gate"): | |
| del self._last_gate | |
| if hasattr(self, "_gate_entropy_live"): | |
| del self._gate_entropy_live | |
| def gate_entropy_loss(self): | |
| if not hasattr(self, "_last_gate"): | |
| return torch.tensor(0.0, device=next(self.parameters()).device) | |
| if hfp_config.ENABLE_ENTROPY_MAP: | |
| return compute_gate_entropy(self._last_gate) * hfp_config.REG_WEIGHT | |
| else: | |
| return torch.tensor(0.0, device=next(self.parameters()).device) | |
| def _write_ring_buffer(self, short_memory, x, write_idx): | |
| """[K6] Vektorize ring-buffer yazimi (eski per-token Python dongusu yerine). | |
| clone(): detach edilmemis state ile in-place autograd hatasini onler.""" | |
| B, L, H = x.shape | |
| cap = self.max_short_len | |
| short_memory = short_memory.clone() | |
| if L >= cap: | |
| # yalnizca son 'cap' token buffer'da kalir | |
| tail = x[:, L - cap:, :] | |
| idx = (write_idx + (L - cap) + torch.arange(cap, device=x.device)) % cap | |
| short_memory[:, idx, :] = tail | |
| else: | |
| idx = (write_idx + torch.arange(L, device=x.device)) % cap | |
| short_memory[:, idx, :] = x | |
| new_write_idx = (write_idx + L) % cap | |
| return short_memory, new_write_idx | |
| def update(self, x, past_state=None, detach_state=True): | |
| if x.dim() == 2: | |
| x = x.unsqueeze(1) | |
| batch_size, seq_len, _ = x.size() | |
| device = x.device | |
| dtype = x.dtype | |
| if past_state is not None: | |
| (short_memory, M, z, token_count, short_len_dynamic, write_idx, conv_state) = past_state | |
| if short_memory is not None and short_memory.size(0) != batch_size: | |
| (short_memory, M, z, token_count, short_len_dynamic, write_idx, conv_state) = self.get_initial_state(batch_size, device, dtype) | |
| else: | |
| (short_memory, M, z, token_count, short_len_dynamic, write_idx, conv_state) = self.get_initial_state(batch_size, device, dtype) | |
| # [K2] detach_state artik cagiran tarafindan kontrol edilir (TBPTT icin False). | |
| if detach_state: | |
| if short_memory is not None: short_memory = short_memory.detach() | |
| if M is not None: M = M.detach() | |
| if z is not None: z = z.detach() | |
| if conv_state is not None: conv_state = conv_state.detach() | |
| # 1. Ring buffer (vektorize) | |
| short_memory, write_idx = self._write_ring_buffer(short_memory, x, write_idx) | |
| token_count += seq_len | |
| active_len = min(token_count, short_len_dynamic) | |
| # 2. [FIX K8] Binding conv: Q/K'yi conv'lanmis girdiden hesapla (komsu token | |
| # karisimi -> anahtar onceki token'i kodlar), V'yi ORIJINAL x'ten (temiz deger). | |
| kk = self.conv_kernel | |
| if kk > 1: | |
| if conv_state is None: | |
| conv_state = torch.zeros(batch_size, kk - 1, self.hidden_size, device=device, dtype=dtype) | |
| x_pad = torch.cat([conv_state, x], dim=1) # (B, kk-1+L, H) | |
| x_qk = self.short_conv(x_pad.transpose(1, 2)).transpose(1, 2) # (B, L, H) causal | |
| new_conv_state = x_pad[:, x_pad.size(1) - (kk - 1):, :] # son kk-1 girdi | |
| else: | |
| x_qk = x | |
| new_conv_state = conv_state | |
| Q = self._feat(self.W_q(x_qk)) # (B,L,key_dim) >= 0 [HFP-CAP] | |
| K = self._feat(self.W_k(x_qk)) # (B,L,key_dim) >= 0 | |
| V_raw = self.W_v(x) # (B,L,H) temiz deger | |
| # 3. Gating (retrieval'dan ONCE: gate'li V hem intra-chunk okumaya | |
| # hem M guncellemesine girer -> gate gradyan alir) | |
| gate_logits = self.importance_gate(x) / self.gate_temperature | |
| gate = torch.sigmoid(self.gate_dropout(gate_logits)) | |
| gate = gate.to(dtype) | |
| self._last_gate = gate.clone().detach() | |
| # [C1] Gradyanli gate-entropy - modeling opsiyonel olarak loss'a ekler. | |
| self._gate_entropy_live = compute_gate_entropy(gate) | |
| gate_entropy = None | |
| if hfp_config.ENABLE_ENTROPY_MAP or hfp_config.ENABLE_DEFECT_FLAG or hfp_config.ENABLE_RYU_TAKAYANAGI: | |
| gate_entropy = compute_gate_entropy(gate) | |
| V = V_raw * gate | |
| # 4. Retention recurrence — mod secilir (exp baseline / cubic_flux HFP-core). | |
| outputs = [] | |
| if self.decay_mode == "cubic_flux": | |
| # [HFP-CORE] Makalenin dth/dtau = -eta*th^3 kubik akisinin birebir | |
| # ayriklastirmasi. Tek-adim kararli cozum -> per-kanal decay faktoru: | |
| # lam_t = 1/sqrt(1 + 2*eta*z_{t-1}^2) (z = anahtar-akumulatoru, per-kanal) | |
| # M_t = lam_t (.) M_{t-1} + k_t v_t^T ; z_t = lam_t (.) z_{t-1} + k_t | |
| # out_t = (q_t M_t)/(q_t . z_t) (causal-inclusive, kendi KV dahil) | |
| # NOT: decay M'in degil Z'nin (anahtar kutlesi) buyuklugune baglidir. | |
| # z bos iken lam~1 (PLATO, unutma yok); z buyudukce lam<1 (aktif, buyukluge | |
| # bagli unutma) -> plato + power-law kuyruk. Kendini-sinirlayan: decay | |
| # buyuklukle arttigindan state patlamaz. Sirali (O(L)); mod default degil. | |
| # Saf recurrence oldugundan chunk-tutarli (full == state-tasiyan chunked). | |
| eta = torch.exp(self.log_eta).to(dtype).unsqueeze(0) # (1,H) > 0 | |
| for t in range(seq_len): | |
| kt = K[:, t]; vt = V[:, t]; qt = Q[:, t] # (B,H) | |
| lam_t = 1.0 / torch.sqrt(1.0 + 2.0 * eta * z * z) # (B,H) | |
| M = M * lam_t.unsqueeze(-1) + torch.einsum('bh,bg->bhg', kt, vt) | |
| z = z * lam_t + kt | |
| num = torch.einsum('bh,bhg->bg', qt, M) # (B,H) | |
| den = (qt * z).sum(-1, keepdim=True) + 1e-6 # (B,1) | |
| outputs.append((num / den).unsqueeze(1)) # (B,1,H) | |
| retrieved = torch.cat(outputs, dim=1) # (B,L,H) | |
| else: | |
| # [K2] exp mod: paralel chunkwise (per-token geometrik decay, causal-inclusive) | |
| lam = torch.sigmoid(self.decay).to(dtype) # (H,), 0..1 | |
| for s in range(0, seq_len, self.rec_block): | |
| Qb = Q[:, s:s + self.rec_block] | |
| Kb = K[:, s:s + self.rec_block] | |
| Vb = V[:, s:s + self.rec_block] | |
| m = Qb.size(1) | |
| p = torch.arange(1, m + 1, device=device, dtype=dtype) # 1..m | |
| lam_i = lam.unsqueeze(0).pow(p.unsqueeze(1)) # (m,H): lam^i | |
| lam_rev = lam.unsqueeze(0).pow((m - p).unsqueeze(1)) # (m,H): lam^{m-i} | |
| # cross-block: eski state'ten oku | |
| Q_dec = Qb * lam_i.unsqueeze(0) # (B,m,H) | |
| num_cross = torch.bmm(Q_dec, M) # (B,m,H) | |
| den_cross = (Q_dec * z.unsqueeze(1)).sum(-1) # (B,m) | |
| # intra-block: D_ij = lam^{i-j} (i>=j), tum usler >= 0 -> stabil | |
| ii = torch.arange(m, device=device).view(m, 1) | |
| jj = torch.arange(m, device=device).view(1, m) | |
| e = (ii - jj).clamp_min(0).to(dtype) # (m,m) | |
| causal = (ii >= jj).to(dtype) | |
| D = lam.view(1, 1, -1).pow(e.unsqueeze(-1)) * causal.unsqueeze(-1) # (m,m,H) | |
| S = torch.einsum('bih,ijh,bjh->bij', Qb, D, Kb) # (B,m,m) | |
| num_intra = torch.bmm(S, Vb) # (B,m,H) | |
| den_intra = S.sum(dim=2) # (B,m) > 0 (Q,K>0) | |
| den = (den_cross + den_intra + 1e-6).unsqueeze(-1) | |
| outputs.append((num_cross + num_intra) / den) | |
| # state guncelle (blok sonu) | |
| lam_m = lam.pow(float(m)) | |
| K_dec = Kb * lam_rev.unsqueeze(0) | |
| M = M * lam_m.view(1, -1, 1) + torch.bmm(K_dec.transpose(1, 2), Vb) | |
| z = z * lam_m.view(1, -1) + K_dec.sum(dim=1) | |
| retrieved = torch.cat(outputs, dim=1) # (B,L,H) | |
| retrieved_memory = self.retrieval_norm(retrieved) # (B,L,H) | |
| # 5. Dynamic Context Windowing & Landmarks (opsiyonel teshis yollari) | |
| if gate_entropy is not None: | |
| if gate_entropy < self.dynamic_short_thresh and short_len_dynamic < self.max_short_len: | |
| short_len_dynamic = min(short_len_dynamic + 4, self.max_short_len) | |
| if hfp_config.ENABLE_DEFECT_FLAG: | |
| coherence = None | |
| if hfp_config.ENABLE_COHERENCE: | |
| coherence = coherence_score(short_memory) | |
| if gate_entropy is not None and coherence is not None: | |
| priority = coherence.item() * gate_entropy.item() | |
| else: | |
| priority = gate.mean().item() | |
| self.landmark_buffer.push(priority, x.mean(dim=1)) | |
| new_past_state = (short_memory, M, z, token_count, short_len_dynamic, write_idx, new_conv_state) | |
| active_short_view = short_memory[:, :active_len, :] | |
| return active_short_view, retrieved_memory, new_past_state | |