Packages
fnord
0.8.18
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/notes_server.ex
defmodule NotesServer do
use GenServer
# -----------------------------------------------------------------------------
# Client API
# -----------------------------------------------------------------------------
@spec start_link(opts :: keyword()) :: GenServer.on_start()
def start_link(opts \\ []) do
UI.debug("[notes-server] starting")
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
end
@doc """
Load existing research notes from persistent storage. The project must be set
from the --project command line option or CWD.
"""
@spec load_notes() :: :ok | {:error, any}
def load_notes() do
GenServer.cast(__MODULE__, :load_notes)
end
@doc """
Uses an AI model to answer a question about the existing research notes. The
question should be a concise request for information about the project, such
as "What is the purpose of this project?" or "What languages and technologies
are used in this project?". The AI model will analyze the existing notes and
return a concise answer.
"""
@spec ask(binary) :: binary
def ask(question) do
GenServer.call(__MODULE__, {:ask, question}, :infinity)
end
@doc """
Uses an AI model to analyze the user's message and extract insights about
their coding preferences, learning style, personality, and other relevant
traits. The insights are stored in the server's state and can be consolidated
later.
"""
@spec ingest_user_msg(binary) :: :ok
def ingest_user_msg(msg_text) do
GenServer.cast(__MODULE__, {:ingest_user_msg, msg_text})
end
@doc """
Uses an AI model to analyze the result of a tool call and extract facts about
the project. The facts are stored in the server's state and can be
consolidated later.
"""
@spec ingest_research(binary, binary, any) :: :ok
def ingest_research(func, args_json, result) do
GenServer.cast(__MODULE__, {:ingest_research, func, args_json, result})
end
@doc """
Consolidates all newly extracted facts and user insights into the existing
research notes. This uses an AI model to reorganize and consolidate the notes
according to specified guidelines. The consolidated notes are saved to
persistent storage.
Currently, consolidation generally happens at the beginning of a new research
session (from `AI.Agent.Coordinator`).
"""
@spec consolidate() :: :ok
def consolidate() do
UI.debug("[notes-server] consolidating existing research")
GenServer.cast(__MODULE__, :consolidate)
end
@doc """
Commits the new notes that have been collected over the course of the current
session to persistent storage. This saves any newly extracted facts and user
insights that have not yet been consolidated into the main research notes.
The new notes are added to a special section at the end of the existing
research notes, labeled `# NEW NOTES (unconsolidated)`. This section is meant
to be consolidated later by the `consolidate/0` function.
"""
@spec commit() :: :ok | {:error, any}
def commit() do
UI.debug("[notes-server] saving research collected this session")
GenServer.call(__MODULE__, :commit, :infinity)
end
# -----------------------------------------------------------------------------
# Server API
# -----------------------------------------------------------------------------
def init(_opts) do
{:ok, AI.Notes.new()}
end
def handle_cast(:load_notes, state) do
{:noreply, AI.Notes.init(state)}
end
def handle_cast({:ingest_user_msg, msg_text}, state) do
{:noreply, AI.Notes.ingest_user_msg(state, msg_text)}
end
def handle_cast({:ingest_research, func, args_json, result}, state) do
{:noreply, AI.Notes.ingest_research(state, func, args_json, result)}
end
def handle_cast(:consolidate, state) do
{:noreply, AI.Notes.consolidate(state)}
end
def handle_call(:commit, _from, state) do
with {:ok, state} <- AI.Notes.commit(state) do
{:reply, :ok, state}
else
{:error, reason} -> {:reply, {:error, reason}, state}
end
end
def handle_call({:ask, question}, _from, state) do
{:reply, AI.Notes.ask(state, question), state}
end
end