Packages
Embedded Gralkor memory for Elixir/OTP — runs Graphiti + FalkorDB in-process via PythonX. Embed in a Jido (or any Elixir) supervision tree to give your agent long-term, temporally-aware knowledge-graph memory.
Retired package: Renamed - moved into :jido_gralkor
Current section
Files
Jump to
Current section
Files
lib/gralkor/format.ex
defmodule Gralkor.Format do
@moduledoc """
Format graphiti edge data into the canonical fact strings the LLM sees.
Pure Elixir — graphiti runs in Python, but we extract its edges into
Elixir maps and format them here, never reaching back into Python for
formatting.
Output shape per fact:
- {fact} (created …) (valid from …) (invalid since …) (expired …)
Timestamp normalisation matches the server's `pipelines/formatting.py` so
consumers see identical fact text from either stack.
See `ex-format-fact` in `gralkor/TEST_TREES.md`.
"""
@fractional_seconds ~r/\.\d+/
@trailing_z ~r/Z$/
@tz_offset ~r/([+-])(\d{2}):(\d{2})$/
@spec format_fact(map()) :: String.t()
def format_fact(%{fact: fact} = m) do
base = "- " <> fact
base
|> append_ts(m, :created_at, "created")
|> append_ts(m, :valid_at, "valid from")
|> append_ts(m, :invalid_at, "invalid since")
|> append_ts(m, :expired_at, "expired")
end
@spec format_facts([map()]) :: String.t()
def format_facts([]), do: ""
def format_facts(facts) when is_list(facts) do
facts |> Enum.map(&format_fact/1) |> Enum.join("\n")
end
@spec format_timestamp(String.t()) :: String.t()
def format_timestamp(ts) when is_binary(ts) do
ts
|> then(&Regex.replace(@fractional_seconds, &1, ""))
|> then(&Regex.replace(@trailing_z, &1, "+0"))
|> then(&compact_tz_offset/1)
end
defp compact_tz_offset(s) do
Regex.replace(@tz_offset, s, fn _full, sign, hours_str, minutes_str ->
hours = hours_str |> String.to_integer() |> Integer.to_string()
if minutes_str == "00" do
"#{sign}#{hours}"
else
"#{sign}#{hours}:#{minutes_str}"
end
end)
end
defp append_ts(acc, m, key, label) do
case Map.get(m, key) do
nil -> acc
"" -> acc
ts -> acc <> " (#{label} #{format_timestamp(ts)})"
end
end
end