Packages
fnord
0.9.37
0.9.40
0.9.39
0.9.38
0.9.37
0.9.36
0.9.35
0.9.34
0.9.33
0.9.32
0.9.31
0.9.30
0.9.29
0.9.28
0.9.27
0.9.26
0.9.25
0.9.24
0.9.23
0.9.22
0.9.21
0.9.20
0.9.19
0.9.18
0.9.17
0.9.16
0.9.15
0.9.14
0.9.13
0.9.12
0.9.11
0.9.10
0.9.9
0.9.8
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.99
0.8.98
0.8.97
0.8.96
0.8.95
0.8.94
0.8.93
0.8.92
0.8.91
0.8.90
0.8.89
0.8.88
0.8.87
0.8.86
0.8.85
0.8.84
0.8.83
0.8.82
0.8.81
0.8.80
0.8.79
0.8.78
0.8.77
0.8.76
0.8.75
0.8.74
0.8.73
0.8.72
0.8.71
0.8.70
0.8.69
0.8.68
0.8.67
0.8.66
0.8.65
0.8.64
0.8.63
0.8.62
0.8.61
0.8.60
0.8.59
0.8.58
0.8.57
0.8.56
0.8.55
0.8.54
0.8.53
0.8.52
0.8.51
0.8.50
0.8.49
0.8.48
0.8.47
0.8.46
0.8.45
0.8.44
0.8.43
0.8.42
0.8.41
0.8.40
0.8.39
0.8.38
0.8.37
0.8.36
0.8.35
0.8.34
0.8.33
0.8.32
0.8.31
0.8.30
0.8.29
0.8.27
0.8.26
0.8.25
0.8.24
0.8.23
0.8.22
0.8.21
0.8.20
0.8.19
0.8.18
0.8.17
0.8.16
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.1
0.8.0
0.7.24
0.7.23
0.7.22
0.7.21
0.7.20
0.7.19
0.7.18
0.7.17
0.7.16
0.7.15
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.3
0.7.2
0.7.1
0.7.0
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.1
0.6.0
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.44
0.4.43
0.4.42
0.4.41
0.4.40
0.4.39
0.4.38
0.4.37
0.4.36
0.4.35
0.4.34
0.4.33
0.4.32
0.4.30
0.4.29
0.4.28
0.4.27
0.4.26
0.4.25
0.4.24
0.4.23
0.4.22
0.4.21
0.4.20
0.4.19
0.4.18
0.4.17
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.0
0.2.0
0.1.0
AI code archaeology
Current section
Files
Jump to
Current section
Files
lib/memory/migration.ex
defmodule Memory.Migration do
@moduledoc """
Helpers for repairing and migrating memory index statuses.
This module provides programmatic functions (not a mix task) so migration
can be invoked in an escript environment or in tests. The default behavior
is a dry-run listing of candidate memories; pass `apply?: true` to perform
an in-place repair (set index_status to :analyzed).
"""
@doc """
Scan global, project, and session memories for nil index_status.
When `project` is nil, the current selected project is used (via
Store.get_project()). Returns {:ok, report_map} where report_map
contains lists of affected memories.
"""
def migrate_nil_statuses(project \\ nil, opts \\ []) do
apply? = Keyword.get(opts, :apply?, false)
report = %{
global: find_nil_status_memories(:global),
project: find_nil_status_project_memories(project),
session: find_nil_status_session_memories(project)
}
if apply? do
apply_status_repairs(report, project)
{:ok, Map.put(report, :applied, true)}
else
{:ok, Map.put(report, :applied, false)}
end
end
# --------------------------------------------------------------------------
# Scanning
# --------------------------------------------------------------------------
defp find_nil_status_memories(:global) do
{:ok, titles} = Memory.Global.list()
titles
|> Enum.filter(&has_nil_status?(:global, &1))
|> Enum.map(fn title -> {:global, title} end)
end
defp find_nil_status_project_memories(project) do
case Store.get_project(project) do
{:ok, _} ->
{:ok, titles} = Memory.Project.list()
titles
|> Enum.filter(&has_nil_status?(:project, &1))
|> Enum.map(fn title -> {:project, title} end)
_ ->
[]
end
end
defp find_nil_status_session_memories(project) do
case Store.get_project(project) do
{:ok, proj} ->
proj
|> Store.Project.Conversation.list()
|> Enum.flat_map(&session_memories_with_nil_status/1)
_ ->
[]
end
end
defp has_nil_status?(scope, title) do
case Memory.read(scope, title) do
{:ok, mem} -> is_nil(mem.index_status)
_ -> false
end
end
defp session_memories_with_nil_status(conv) do
case Store.Project.Conversation.read(conv) do
{:ok, data} ->
data.memory
|> Enum.filter(fn
%Memory{scope: :session, index_status: nil} -> true
_ -> false
end)
|> Enum.map(fn m -> {conv.id, m.title} end)
_ ->
[]
end
end
# --------------------------------------------------------------------------
# Applying repairs
# --------------------------------------------------------------------------
defp apply_status_repairs(report, project) do
repair_scoped_memories(report.global)
repair_scoped_memories(report.project)
repair_session_memories(project)
end
defp repair_scoped_memories(candidates) do
Enum.each(candidates, fn {scope, title} ->
Memory.set_status(scope, title, :analyzed)
end)
end
defp repair_session_memories(project) do
case Store.get_project(project) do
{:ok, proj} ->
proj
|> Store.Project.Conversation.list()
|> Enum.each(&repair_conversation_session_memories/1)
_ ->
:ok
end
end
defp repair_conversation_session_memories(conv) do
case Store.Project.Conversation.read(conv) do
{:ok, data} ->
updated_mem =
Enum.map(data.memory, fn
%Memory{scope: :session, index_status: nil} = m ->
%{m | index_status: :analyzed}
other ->
other
end)
data
|> Map.put(:memory, updated_mem)
|> then(&Store.Project.Conversation.write(conv, &1))
_ ->
:ok
end
end
end