Packages

fnord

0.9.29

AI code archaeology

Current section

Files

Jump to
fnord lib memory session.ex
Raw

lib/memory/session.ex

defmodule Memory.Session do
# ----------------------------------------------------------------------------
# Behaviour Implementation
# ----------------------------------------------------------------------------
@behaviour Memory
# Session memories with these statuses have been promoted to long-term
# (project/global) storage by the indexer. They are excluded from list and
# search results to avoid redundancy with their long-term counterparts.
@promoted_statuses [:incorporated, :merged]
@impl Memory
def init() do
case get_conversation_pid() do
{:ok, _pid} -> :ok
error -> error
end
end
@impl Memory
def list() do
with {:ok, memories} <- get_conversation_memory() do
titles =
memories
|> Enum.reject(fn %Memory{index_status: s} -> s in @promoted_statuses end)
|> Enum.map(& &1.title)
{:ok, titles}
end
end
@impl Memory
def exists?(title) when is_binary(title) do
with {:ok, memories} <- get_conversation_memory() do
Enum.any?(memories, fn %Memory{title: t} -> t == title end)
else
_ -> false
end
end
@impl Memory
def read(title) when is_binary(title) do
with {:ok, memories} <- get_conversation_memory() do
memories
|> Enum.find(fn %Memory{title: t} -> t == title end)
|> case do
nil -> {:error, :not_found}
mem -> {:ok, mem}
end
end
end
@impl Memory
def save(%Memory{title: title} = memory) do
with {:ok, pid} <- get_conversation_pid(),
{:ok, memories} <- get_conversation_memory() do
updated =
memories
|> Enum.reject(fn %Memory{title: t} -> t == title end)
|> Kernel.++([memory])
|> Enum.map(fn
%Memory{scope: :session, index_status: nil} = m -> %{m | index_status: :new}
m -> m
end)
Services.Conversation.put_memory(pid, updated)
:ok
end
end
@impl Memory
def forget(title) when is_binary(title) do
with {:ok, pid} <- get_conversation_pid(),
{:ok, memories} <- get_conversation_memory() do
updated = Enum.reject(memories, fn %Memory{title: t} -> t == title end)
Services.Conversation.put_memory(pid, updated)
:ok
end
end
@impl Memory
def is_available?() do
case get_conversation_pid() do
{:ok, _pid} -> true
_ -> false
end
end
# ----------------------------------------------------------------------------
# Internals
# ----------------------------------------------------------------------------
defp get_conversation_pid() do
Services.Globals.get_env(:fnord, :current_conversation)
|> case do
nil -> {:error, :no_conversation_set}
pid when is_pid(pid) -> {:ok, pid}
_ -> {:error, :invalid_conversation}
end
end
defp get_conversation_memory() do
with {:ok, pid} <- get_conversation_pid() do
{:ok, Services.Conversation.get_memory(pid)}
end
end
end