Altar.ADM.ToolManifest (Altar v0.2.0)

View Source

ToolManifest structure for ALTAR Data Model (ADM).

A ToolManifest is a collection of tools that represents the complete set of capabilities available in a GRID Host's STRICT mode. It provides version tracking, metadata, and governance information for tool deployment.

Structure

A ToolManifest contains:

  • version - Semantic version of this manifest
  • tools - Array of Tool structures
  • metadata - Optional deployment metadata (environment, timestamp, etc.)

Use Cases

  1. GRID STRICT Mode - Static manifest loaded at Host startup
  2. Tool Governance - Versioned, auditable tool deployments
  3. Multi-Environment - Different manifests for dev/staging/prod
  4. Change Tracking - Version history of tool availability

Examples

# Create a manifest
{:ok, manifest} = ToolManifest.new(%{
  version: "1.0.0",
  tools: [weather_tool, calculator_tool],
  metadata: %{
    "environment" => "production",
    "deployed_at" => "2025-10-07T12:00:00Z",
    "deployed_by" => "ops@example.com"
  }
})

# Load from JSON file (GRID Host startup)
manifest_json = File.read!("tool_manifest.json")
{:ok, manifest} = ToolManifest.from_json(manifest_json)

JSON Serialization

Manifests are typically stored as JSON files:

# Save manifest
json = ToolManifest.to_json(manifest)
File.write!("tool_manifest.json", json)

# Load manifest
{:ok, manifest} = ToolManifest.from_json(File.read!("tool_manifest.json"))

Summary

Types

t()

A validated ToolManifest structure.

Functions

Get a list of all function names across all tools in the manifest.

Find a function declaration by name across all tools.

Parse manifest from JSON string.

Parse manifest from JSON-deserialized map.

Get the total number of functions across all tools.

Check if a function name exists in the manifest.

Construct a new validated ToolManifest.

Convert manifest to pretty-printed JSON string.

Convert manifest to JSON-serializable map.

Get the number of tools in the manifest.

Types

t()

@type t() :: %Altar.ADM.ToolManifest{
  metadata: %{optional(String.t()) => any()} | nil,
  tools: [Altar.ADM.Tool.t()],
  version: String.t()
}

A validated ToolManifest structure.

Functions

all_function_names(tool_manifest)

@spec all_function_names(t()) :: [String.t()]

Get a list of all function names across all tools in the manifest.

Useful for checking tool availability in GRID STRICT mode.

Examples

iex> {:ok, manifest} = Altar.ADM.ToolManifest.new(%{
...>   version: "1.0.0",
...>   tools: [
...>     %{function_declarations: [%{name: "add", description: "Add", parameters: %{}}]},
...>     %{function_declarations: [%{name: "multiply", description: "Multiply", parameters: %{}}]}
...>   ]
...> })
iex> Altar.ADM.ToolManifest.all_function_names(manifest)
["add", "multiply"]

find_function(tool_manifest, name)

@spec find_function(t(), String.t()) ::
  {:ok, {non_neg_integer(), Altar.ADM.FunctionDeclaration.t()}}
  | {:error, :not_found}

Find a function declaration by name across all tools.

Returns {:ok, {tool_index, declaration}} if found, {:error, :not_found} otherwise.

Examples

{:ok, {0, decl}} = ToolManifest.find_function(manifest, "get_weather")
{:error, :not_found} = ToolManifest.find_function(manifest, "nonexistent")

from_json(json)

@spec from_json(String.t()) :: {:ok, t()} | {:error, String.t()}

Parse manifest from JSON string.

Examples

json = File.read!("manifest.json")
{:ok, manifest} = ToolManifest.from_json(json)

from_map(map)

@spec from_map(map()) :: {:ok, t()} | {:error, String.t()}

Parse manifest from JSON-deserialized map.

Examples

map = Jason.decode!(json_string)
{:ok, manifest} = ToolManifest.from_map(map)

function_count(tool_manifest)

@spec function_count(t()) :: non_neg_integer()

Get the total number of functions across all tools.

has_function?(manifest, name)

@spec has_function?(t(), String.t()) :: boolean()

Check if a function name exists in the manifest.

Examples

true = ToolManifest.has_function?(manifest, "get_weather")
false = ToolManifest.has_function?(manifest, "nonexistent")

new(attrs)

@spec new(map() | keyword()) :: {:ok, t()} | {:error, String.t()}

Construct a new validated ToolManifest.

Required Fields

  • :version - Semantic version string (e.g., "1.0.0")
  • :tools - List of Tool structs (can be empty for minimal manifests)

Optional Fields

  • :metadata - Map of arbitrary metadata (environment, deployment info, etc.)

Validation Rules

  1. Version must be a valid semantic version string
  2. Tools must be a list (can be empty)
  3. All tools must be valid Tool structs
  4. Tool names across all functions must be globally unique
  5. Metadata must be a map if provided

Returns {:ok, manifest} or {:error, reason}.

Examples

# Minimal manifest
{:ok, manifest} = ToolManifest.new(%{
  version: "1.0.0",
  tools: []
})

# Production manifest with metadata
{:ok, manifest} = ToolManifest.new(%{
  version: "2.1.0",
  tools: [tool1, tool2, tool3],
  metadata: %{
    "environment" => "production",
    "region" => "us-east-1",
    "deployed_at" => DateTime.utc_now() |> DateTime.to_iso8601(),
    "git_commit" => "abc123",
    "approver" => "security-team@example.com"
  }
})

to_json(manifest)

@spec to_json(t()) :: {:ok, String.t()} | {:error, Jason.EncodeError.t()}

Convert manifest to pretty-printed JSON string.

Examples

json = ToolManifest.to_json(manifest)
File.write!("manifest.json", json)

to_map(tool_manifest)

@spec to_map(t()) :: map()

Convert manifest to JSON-serializable map.

Examples

map = ToolManifest.to_map(manifest)
{:ok, json} = Jason.encode(map, pretty: true)

tool_count(tool_manifest)

@spec tool_count(t()) :: non_neg_integer()

Get the number of tools in the manifest.