Planck.Headless (Planck.Headless v0.1.6)

Copy Markdown View Source

The headless core of the Planck coding agent.

planck_headless owns configuration, loads resources at startup (tools, skills, teams, compactor), and manages session lifecycles. UIs depend on this module; they are rendering surfaces only and never call planck_agent directly.

See the design specs in the specs/ directory of the repository.

Summary

Functions

Return models available for use (providers with API keys configured).

Close a session. Stops the agent team and the session GenServer. The SQLite file is retained for later resumption.

Return the resolved configuration.

Persist a model entry to the JSON config, then reload resources so the new model is immediately available.

Persist a provider entry to the JSON config and API key to .env, then reload resources.

Close a session and permanently delete its SQLite file from disk.

Look up a team by alias.

List all sessions on disk — active and inactive — with their id, name, and whether they are currently running.

List all registered teams with alias, name, and description.

Nudge the orchestrator to act on its existing message history without adding a new user message. Used after session resume when a recovery context is already present and just needs to be acted upon.

Send a user prompt to the orchestrator of a session.

Register a local-node tool globally. Available to all new sessions.

Reload tools, skills, teams, and the compactor from disk. In-flight sessions keep their original resources.

Resume a session by session_id or by name. Reconstructs the team, restores message history, and injects a recovery context if prior work was in-flight.

Edit a previous user message: rewind the orchestrator to strictly before the given DB row id (truncates both the SQLite session and in-memory history via Planck.Agent.rewind_to_message/2), then re-prompt with new_text.

Start a new session. Returns {:ok, session_id}.

Remove a globally registered tool by name. No-op if not found.

Types

session_id()

@type session_id() :: String.t()

Functions

available_models()

@spec available_models() :: [Planck.AI.Model.t()]

Return models available for use (providers with API keys configured).

close_session(session_id)

@spec close_session(session_id()) :: :ok | {:error, term()}

Close a session. Stops the agent team and the session GenServer. The SQLite file is retained for later resumption.

config()

@spec config() :: Planck.Headless.Config.t()

Return the resolved configuration.

configure_model(opts)

@spec configure_model(keyword()) :: :ok | {:error, term()}

Persist a model entry to the JSON config, then reload resources so the new model is immediately available.

Options:

  • :id (required) — user alias (e.g. "sonnet")
  • :model (required) — provider model identifier (e.g. "claude-sonnet-4-6")
  • :provider (required) — key referencing an entry in the providers map
  • :scope:local (default, .planck/) or :global (~/.planck/)
  • :default — set as default_model (default: true)
  • :params — inference parameters map (e.g. %{"temperature" => 0.7})

configure_provider(opts)

@spec configure_provider(keyword()) :: :ok | {:error, term()}

Persist a provider entry to the JSON config and API key to .env, then reload resources.

Options:

  • :id (required) — provider key written to providers map (e.g. "anthropic", "nvidia")
  • :type (required) — "anthropic", "openai", or "google"
  • :base_url — for OpenAI-compatible endpoints
  • :identifier — uppercase tag for env var derivation ("NVIDIA"NVIDIA_API_KEY)
  • :has_api_key — set false for keyless local servers; default true
  • :api_key — written to <scope>/.env
  • :scope:local (default, .planck/) or :global (~/.planck/)

delete_session(session_id)

@spec delete_session(session_id()) :: :ok

Close a session and permanently delete its SQLite file from disk.

Stops all running agents and the Session GenServer if active, then removes the .db file. This operation is irreversible.

get_team(team_alias)

@spec get_team(String.t()) :: {:ok, Planck.Agent.Team.t()} | {:error, :not_found}

Look up a team by alias.

list_sessions()

@spec list_sessions() :: [
  %{session_id: String.t(), name: String.t(), active: boolean()}
]

List all sessions on disk — active and inactive — with their id, name, and whether they are currently running.

list_teams()

@spec list_teams() :: [
  %{alias: String.t(), name: String.t() | nil, description: String.t() | nil}
]

List all registered teams with alias, name, and description.

nudge(session_id)

@spec nudge(session_id()) :: :ok | {:error, term()}

Nudge the orchestrator to act on its existing message history without adding a new user message. Used after session resume when a recovery context is already present and just needs to be acted upon.

Returns :ok if the orchestrator was nudged, {:error, reason} otherwise.

prompt(session_id, text)

@spec prompt(session_id(), String.t()) :: :ok | {:error, term()}

Send a user prompt to the orchestrator of a session.

register_tool(tool)

@spec register_tool(Planck.Agent.Tool.t()) :: :ok

Register a local-node tool globally. Available to all new sessions.

If a tool with the same name is already registered it is replaced. Registered tools shadow sidecar tools and built-ins of the same name. See the tool-shadowing guide for details.

reload_resources()

@spec reload_resources() :: :ok

Reload tools, skills, teams, and the compactor from disk. In-flight sessions keep their original resources.

resume_session(id_or_name, opts \\ [])

@spec resume_session(
  String.t(),
  keyword()
) :: {:ok, session_id()} | {:error, term()}

Resume a session by session_id or by name. Reconstructs the team, restores message history, and injects a recovery context if prior work was in-flight.

rewind_to_message(session_id, db_id, new_text)

@spec rewind_to_message(session_id(), pos_integer(), String.t()) ::
  :ok | {:error, term()}

Edit a previous user message: rewind the orchestrator to strictly before the given DB row id (truncates both the SQLite session and in-memory history via Planck.Agent.rewind_to_message/2), then re-prompt with new_text.

start_session(opts \\ [])

@spec start_session(keyword()) :: {:ok, session_id()} | {:error, term()}

Start a new session. Returns {:ok, session_id}.

Options

  • template: — team alias, path to a TEAM.json directory, or nil for the default dynamic team (lone orchestrator built from config defaults).
  • name: — session name; auto-generated as <adjective>-<noun> if absent.
  • cwd: — working directory for the session (default: File.cwd!()).
  • tools: — extra Planck.Agent.Tool.t() list available only for this session. These shadow registered and built-in tools of the same name.

unregister_tool(name)

@spec unregister_tool(String.t()) :: :ok

Remove a globally registered tool by name. No-op if not found.