# `Jido.AI.Skill.Resources`
[🔗](https://github.com/agentjido/jido_ai/blob/v2.4.0/lib/jido_ai/skill/resources.ex#L1)

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.

# `filesystem_resource_info`

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

# `loaded_resource`

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

# `resource_info`

```elixir
@type resource_info() :: filesystem_resource_info()
```

# `resource_listing`

```elixir
@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`

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

# `default_policy`

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

Returns the default resource policy.

# `empty_listing`

```elixir
@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?`

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

Checks if a safe regular resource exists.

# `list_all`

```elixir
@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`

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

Lists one conventional resource group with the default policy.

# `list_resources`

```elixir
@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`

```elixir
@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`

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

Loads resource bytes with the default file-size limit.

# `load_resource`

```elixir
@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`

```elixir
@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`

```elixir
@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`

```elixir
@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`

```elixir
@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`

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

Gets information about a safe regular resource.

# `search`

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

Searches the bounded general listing with a glob pattern.

# `validate_loaded_resource`

```elixir
@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`

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

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

---

*Consult [api-reference.md](api-reference.md) for complete listing*
