Packages
agent_client_protocol
0.1.0
Elixir implementation of the Agent Client Protocol (ACP) for communication between code editors and AI coding agents. Includes schema types, JSON-RPC primitives, behaviours, and connection management.
Current section
Files
Jump to
Current section
Files
lib/acp/plan.ex
defmodule ACP.Plan do
@moduledoc "Execution plan for complex tasks."
@type t :: %__MODULE__{
entries: [ACP.PlanEntry.t()],
meta: ACP.Ext.meta()
}
@enforce_keys [:entries]
defstruct [:entries, :meta]
def new(entries), do: %__MODULE__{entries: entries}
def to_json(%__MODULE__{} = plan) do
map = %{"entries" => Enum.map(plan.entries, &ACP.PlanEntry.to_json/1)}
if plan.meta, do: Map.put(map, "_meta", plan.meta), else: map
end
def from_json(%{"entries" => entries} = map) do
{:ok,
%__MODULE__{
entries:
Enum.map(entries, fn e ->
{:ok, pe} = ACP.PlanEntry.from_json(e)
pe
end),
meta: Map.get(map, "_meta")
}}
end
end
defmodule ACP.PlanEntry do
@moduledoc "A single entry in the execution plan."
@type t :: %__MODULE__{
content: String.t(),
priority: ACP.PlanEntry.priority(),
status: ACP.PlanEntry.status(),
meta: ACP.Ext.meta()
}
@type priority :: :high | :medium | :low
@type status :: :pending | :in_progress | :completed
@enforce_keys [:content, :priority, :status]
defstruct [:content, :priority, :status, :meta]
def new(content, priority, status) do
%__MODULE__{content: content, priority: priority, status: status}
end
def to_json(%__MODULE__{} = entry) do
map = %{
"content" => entry.content,
"priority" => encode_priority(entry.priority),
"status" => encode_status(entry.status)
}
if entry.meta, do: Map.put(map, "_meta", entry.meta), else: map
end
def from_json(%{"content" => content, "priority" => priority, "status" => status} = map) do
{:ok,
%__MODULE__{
content: content,
priority: decode_priority(priority),
status: decode_status(status),
meta: Map.get(map, "_meta")
}}
end
defp encode_priority(:high), do: "high"
defp encode_priority(:medium), do: "medium"
defp encode_priority(:low), do: "low"
defp decode_priority("high"), do: :high
defp decode_priority("medium"), do: :medium
defp decode_priority("low"), do: :low
defp encode_status(:pending), do: "pending"
defp encode_status(:in_progress), do: "in_progress"
defp encode_status(:completed), do: "completed"
defp decode_status("pending"), do: :pending
defp decode_status("in_progress"), do: :in_progress
defp decode_status("completed"), do: :completed
end
defimpl Jason.Encoder, for: ACP.Plan do
def encode(plan, opts), do: ACP.Plan.to_json(plan) |> Jason.Encoder.encode(opts)
end
defimpl Jason.Encoder, for: ACP.PlanEntry do
def encode(entry, opts), do: ACP.PlanEntry.to_json(entry) |> Jason.Encoder.encode(opts)
end