Jido.AI.Skill.Resources (Jido AI v2.4.0)

Copy Markdown View Source

Provides bounded, lazy access to files bundled with a skill.

The resources field is the complete aggregate listing and includes each regular file below the skill root except the root SKILL.md. Root files and custom directories are valid resources. Conventional scripts, references, and assets groups remain available as filtered views of the same entries, so a file can intentionally appear in both resources and its typed view. Paths in returned listings are relative to the skill root.

Listing does not follow symlinks. Loading rejects traversal, absolute paths, and symlinks. Jido.AI.Skill.ResourcePolicy supplies all limits.

Summary

Functions

Returns the default resource policy.

Returns an empty, complete listing for a selected policy.

Checks if a safe regular resource exists.

Lists all bundled resources with explicit bounds.

Lists one conventional resource group with the default policy.

Lists all resources and keeps conventional groups for compatibility.

Loads one resource as text or, with explicit permission, as an image or file.

Loads resource bytes with the default file-size limit.

Loads resource bytes with a selected resource policy.

Loads a resource as bounded UTF-8 text with the default policy.

Loads one resource as bounded UTF-8 text.

Gets a validated resource policy from action context.

Resolves a relative path inside the skill root.

Gets information about a safe regular resource.

Searches the bounded general listing with a glob pattern.

Validates loaded bytes and returns a normalized text, image, or file resource.

Validates text only, retaining the existing :ok return contract.

Types

filesystem_resource_info()

@type filesystem_resource_info() :: %{
  :name => String.t(),
  :relative_path => String.t(),
  :size => non_neg_integer(),
  :modified => DateTime.t(),
  optional(:type) => atom() | String.t() | nil,
  optional(:mime_type) => String.t() | nil,
  optional(:metadata) => map()
}

loaded_resource()

@type loaded_resource() :: %{
  :content => binary(),
  :size => non_neg_integer(),
  optional(:kind) => :text | :image | :file,
  optional(:mime_type) => String.t() | nil,
  optional(:filename) => String.t() | nil,
  optional(:selector) => {:path, String.t()} | {:resource_id, String.t()},
  optional(:relative_path) => String.t(),
  optional(:resource_id) => String.t()
}

resource_info()

@type resource_info() :: filesystem_resource_info()

resource_listing()

@type resource_listing() :: %{
  resources: [filesystem_resource_info()],
  scripts: [filesystem_resource_info()],
  references: [filesystem_resource_info()],
  assets: [filesystem_resource_info()],
  complete: boolean(),
  truncated: boolean(),
  truncation_reasons: [atom()],
  limits: map()
}

resource_type()

@type resource_type() :: :scripts | :references | :assets

Functions

default_policy()

@spec default_policy() :: Jido.AI.Skill.ResourcePolicy.t()

Returns the default resource policy.

empty_listing(policy_or_opts \\ [])

@spec empty_listing(Jido.AI.Skill.ResourcePolicy.t() | keyword() | map()) ::
  {:ok, resource_listing()} | {:error, term()}

Returns an empty, complete listing for a selected policy.

exists?(skill_root, relative_path)

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

Checks if a safe regular resource exists.

list_all(skill_root, policy_or_opts \\ [])

@spec list_all(String.t(), Jido.AI.Skill.ResourcePolicy.t() | keyword() | map()) ::
  {:ok, resource_listing()} | {:error, term()}

Lists all bundled resources with explicit bounds.

Results are sorted by relative path. If a limit prevents a complete result, complete is false and truncation_reasons identifies each reached limit or unreadable entry.

list_by_type(skill_root, type)

@spec list_by_type(String.t(), resource_type()) :: [resource_info()]

Lists one conventional resource group with the default policy.

list_resources(skill_root)

@spec list_resources(String.t()) :: resource_listing()

Lists all resources and keeps conventional groups for compatibility.

This function uses the default policy. Use list_all/2 for custom limits.

load(skill_root, relative_path, policy_or_opts \\ [])

@spec load(
  String.t(),
  String.t(),
  Jido.AI.Skill.ResourcePolicy.t() | keyword() | map()
) ::
  {:ok, loaded_resource()} | {:error, term()}

Loads one resource as text or, with explicit permission, as an image or file.

The result contains raw bytes and metadata. Callers must keep binary bytes out of JSON and use a supported attachment transport.

load_resource(skill_root, relative_path)

@spec load_resource(String.t(), String.t()) :: {:ok, binary()} | {:error, term()}

Loads resource bytes with the default file-size limit.

load_resource(skill_root, relative_path, policy_or_opts)

@spec load_resource(
  String.t(),
  String.t(),
  Jido.AI.Skill.ResourcePolicy.t() | keyword() | map()
) ::
  {:ok, binary()} | {:error, term()}

Loads resource bytes with a selected resource policy.

load_resource_text(skill_root, relative_path)

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

Loads a resource as bounded UTF-8 text with the default policy.

load_text(skill_root, relative_path, policy_or_opts \\ [])

@spec load_text(
  String.t(),
  String.t(),
  Jido.AI.Skill.ResourcePolicy.t() | keyword() | map()
) ::
  {:ok,
   %{content: String.t(), relative_path: String.t(), size: non_neg_integer()}}
  | {:error, term()}

Loads one resource as bounded UTF-8 text.

The result includes the normalized relative path and byte size. Binary content returns :binary_resource.

policy_from_context(context)

@spec policy_from_context(map()) ::
  {:ok, Jido.AI.Skill.ResourcePolicy.t()} | {:error, term()}

Gets a validated resource policy from action context.

The default policy is returned when the reserved context key is absent.

resolve_path(skill_root, relative_path)

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

Resolves a relative path inside the skill root.

Absolute paths, traversal, and paths that resolve through an escaping symlink return :path_traversal.

resource_info(skill_root, relative_path)

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

Gets information about a safe regular resource.

search(skill_root, pattern)

@spec search(String.t(), String.t()) :: [resource_info()]

Searches the bounded general listing with a glob pattern.

validate_loaded_resource(resource, policy)

@spec validate_loaded_resource(loaded_resource(), Jido.AI.Skill.ResourcePolicy.t()) ::
  {:ok, loaded_resource()} | {:error, term()}

Validates loaded bytes and returns a normalized text, image, or file resource.

Every resource is subject to max_file_bytes. Only text is subject to max_text_bytes. Binary resources require binary: :allow, a filename, and a MIME type. Known image and PDF signatures must match their metadata.

validate_loaded_text(resource, policy)

@spec validate_loaded_text(loaded_resource(), Jido.AI.Skill.ResourcePolicy.t()) ::
  :ok | {:error, term()}

Validates text only, retaining the existing :ok return contract.