Packages
fnord
0.7.23
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/store/default_project/conversation.ex
defmodule Store.DefaultProject.Conversation do
@file_path "conversation.jsonl"
def file_path do
path = Store.DefaultProject.store_path() |> Path.join(@file_path)
if !File.exists?(path), do: File.write!(path, "")
path
end
def read_messages do
# Filter out non-content messages
read_file()
|> Stream.filter(fn
%{"role" => "assistant"} -> true
%{"role" => "tool"} -> true
%{"role" => "user"} -> true
_ -> false
end)
end
def last_interaction do
read_file()
|> Enum.reverse()
|> Enum.reduce_while([], fn
%{"timestamp" => _} = msg, acc -> {:halt, [msg | acc]}
msg, acc -> {:cont, [msg | acc]}
end)
end
def latest_timestamp do
read_file()
|> Stream.scan(nil, fn
%{"timestamp" => ts}, _ -> ts
_, ts -> ts
end)
|> Enum.to_list()
|> List.last()
end
def add_timestamp do
ts_msg = %{"timestamp" => DateTime.utc_now() |> DateTime.to_iso8601()}
with {:ok, file} <- File.open(file_path(), [:append, {:encoding, :utf8}]),
{:ok, ts_json} = Jason.encode(ts_msg) do
IO.write(file, ts_json <> "\n")
end
end
def add_messages(msgs) do
with {:ok, file} <- File.open(file_path(), [:append, {:encoding, :utf8}]) do
msgs
|> Stream.filter(&(&1["role"] != "system" and &1["role"] != "developer"))
|> Stream.each(fn msg ->
with {:ok, json} <- Jason.encode(msg) do
IO.write(file, json <> "\n")
end
end)
|> Stream.run()
:ok
end
end
def replace_messages(msgs) do
with {:ok, file} <- File.open(file_path(), [:write, {:encoding, :utf8}]) do
msgs
|> Enum.filter(&add_message?/1)
|> Enum.each(fn msg ->
with {:ok, json} <- Jason.encode(msg) do
IO.write(file, json <> "\n")
end
end)
:ok
end
end
def read_file do
file_path()
|> File.stream!()
|> Stream.reject(&(&1 == ""))
# Parse each line as JSON
|> Stream.map(fn line ->
line
|> Jason.decode()
|> case do
{:ok, msg} -> msg
{:error, _} -> nil
end
end)
|> Stream.reject(&is_nil/1)
end
defp add_message?(%{"role" => "assistant"}), do: true
defp add_message?(%{"role" => "tool"}), do: true
defp add_message?(%{"role" => "user"}), do: true
defp add_message?(%{"timestamp" => _}), do: true
defp add_message?(%{"type" => "summary"}), do: true
defp add_message?(_), do: false
end