Nous.Skill.Registry (nous v0.13.3)

View Source

Discovery, management, and activation of skills.

The registry maintains skills indexed by name, group, tags, and scope. It supports loading/unloading, activation/deactivation, group operations, and input matching for auto-activation.

Example

registry = Nous.Skill.Registry.new()
|> Nous.Skill.Registry.register(skill)
|> Nous.Skill.Registry.activate("code_review", agent, ctx)

active = Nous.Skill.Registry.active_skills(registry)

Summary

Functions

Activate a skill by name.

Activate all skills in a group.

Check if a skill is currently active.

Get all currently active skills.

Get all skills in a group.

Get all skills with a tag.

Deactivate a skill by name.

Deactivate all skills in a group.

Get a skill by name.

List all registered skill names.

Find skills matching user input.

Create an empty registry.

Register a skill in the registry, indexing by name, group, tags, and scope.

Register multiple skills at once.

Register all skills from multiple directories.

Register all skills found in a directory (recursively scans for .md files).

Resolve a mixed list of skill specs into a populated registry.

Types

t()

@type t() :: %Nous.Skill.Registry{
  active: term(),
  groups: %{optional(atom()) => [String.t()]},
  scopes: %{optional(Nous.Skill.scope()) => [String.t()]},
  skills: %{optional(String.t()) => Nous.Skill.t()},
  tags: %{optional(atom()) => [String.t()]}
}

Functions

activate(registry, name, agent, ctx)

@spec activate(t(), String.t(), Nous.Agent.t(), Nous.Agent.Context.t()) ::
  {String.t() | nil, [Nous.Tool.t()], t()}

Activate a skill by name.

Loads the skill if not already loaded, marks it as active. Returns {instructions, tools, updated_registry}.

activate_group(registry, group, agent, ctx)

@spec activate_group(t(), atom(), Nous.Agent.t(), Nous.Agent.Context.t()) ::
  {[{String.t(), [Nous.Tool.t()]}], t()}

Activate all skills in a group.

active?(registry, name)

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

Check if a skill is currently active.

active_skills(registry)

@spec active_skills(t()) :: [Nous.Skill.t()]

Get all currently active skills.

by_group(registry, group)

@spec by_group(t(), atom()) :: [Nous.Skill.t()]

Get all skills in a group.

by_tag(registry, tag)

@spec by_tag(t(), atom()) :: [Nous.Skill.t()]

Get all skills with a tag.

deactivate(registry, name)

@spec deactivate(t(), String.t()) :: t()

Deactivate a skill by name.

deactivate_group(registry, group)

@spec deactivate_group(t(), atom()) :: t()

Deactivate all skills in a group.

get(registry, name)

@spec get(t(), String.t()) :: Nous.Skill.t() | nil

Get a skill by name.

list(registry)

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

List all registered skill names.

match(registry, input)

@spec match(t(), String.t()) :: [Nous.Skill.t()]

Find skills matching user input.

Checks skills with {:on_match, fn} activation or falls back to description keyword matching.

new()

@spec new() :: t()

Create an empty registry.

register(registry, skill)

@spec register(t(), Nous.Skill.t()) :: t()

Register a skill in the registry, indexing by name, group, tags, and scope.

register_all(registry, skills)

@spec register_all(t(), [Nous.Skill.t()]) :: t()

Register multiple skills at once.

register_directories(registry, paths)

@spec register_directories(t(), [String.t()]) :: t()

Register all skills from multiple directories.

Example

registry = Registry.new()
|> Registry.register_directories(["priv/skills/", "~/.nous/skills/", ".nous/skills/"])

register_directory(registry, path)

@spec register_directory(t(), String.t()) :: t()

Register all skills found in a directory (recursively scans for .md files).

This is the primary API for loading file-based skills from a folder.

Example

registry = Registry.new()
|> Registry.register_directory("priv/skills/")
|> Registry.register_directory("~/.nous/skills/")

resolve(specs)

@spec resolve([module() | String.t() | Nous.Skill.t() | {:group, atom()}]) :: t()

Resolve a mixed list of skill specs into a populated registry.

Accepts:

  • Modules implementing Nous.Skill behaviour
  • Directory paths (strings ending with / or existing dirs)
  • File paths (strings ending with .md)
  • Skill.t() structs
  • {:group, atom()} tuples (registers all built-in skills for that group)

Example

registry = Registry.resolve([
  MyApp.Skills.CodeReview,         # module
  "priv/skills/",                  # directory
  "priv/skills/custom.md",         # single file
  {:group, :testing},              # built-in group
  %Skill{name: "inline", ...}      # inline struct
])