Conjure.NativeSkill behaviour (Conjure v0.1.1-alpha)
View SourceBehaviour for native Elixir skill modules.
Native skills are Elixir modules that implement this behaviour, allowing them to be executed directly in the BEAM without external processes. This enables type-safe, in-process skill execution with full access to the application's runtime context.
Tool Mapping
Native skill callbacks map to Claude's tool types:
| Claude Tool | Native Callback | Purpose |
|---|---|---|
bash_tool | execute/2 | Run commands/logic |
view | read/3 | Read resources |
create_file | write/3 | Create resources |
str_replace | modify/4 | Update resources |
Implementing a Native Skill
defmodule MyApp.Skills.CacheManager do
@behaviour Conjure.NativeSkill
@impl true
def __skill_info__ do
%{
name: "cache-manager",
description: "Manage application cache",
allowed_tools: [:execute, :read]
}
end
@impl true
def execute("clear", _context) do
:ok = MyApp.Cache.clear()
{:ok, "Cache cleared successfully"}
end
def execute("stats", _context) do
stats = MyApp.Cache.stats()
{:ok, format_stats(stats)}
end
@impl true
def read("keys", _context, _opts) do
keys = MyApp.Cache.keys()
{:ok, Enum.join(keys, "\n")}
end
endUsage
session = Conjure.Session.new_native([MyApp.Skills.CacheManager])
{:ok, response, session} = Conjure.Session.chat(
session,
"Clear the cache and show me the stats",
&api_callback/1
)Tool Definitions
Native skills automatically generate Claude tool definitions based on
__skill_info__/0. The backend translates tool calls to callback invocations.
Context
Each callback receives a Conjure.ExecutionContext that provides:
- Working directory for file operations
- Allowed paths for security boundaries
- Timeout configuration
- Custom executor config (can store app-specific data)
Optional Callbacks
Only __skill_info__/0 is required. Implement only the callbacks your
skill needs:
execute/2- For command/action executionread/3- For reading resourceswrite/3- For creating resourcesmodify/4- For modifying resources
See Also
Conjure.Backend.Native- Native backend implementationConjure.Session.new_native/2- Creating native sessions
Summary
Callbacks
Return skill metadata.
Execute a command or action.
Modify an existing resource.
Read a resource.
Write/create a resource.
Functions
Get skill info from a module.
Check if a module implements the NativeSkill behaviour.
Build Claude tool definitions from a native skill module.
Types
Callbacks
@callback __skill_info__() :: skill_info()
Return skill metadata.
This callback is required and provides information about the skill including its name, description, and which tools it implements.
Example
def __skill_info__ do
%{
name: "database-query",
description: "Execute read-only database queries",
allowed_tools: [:execute, :read]
}
end
Execute a command or action.
This is the primary action callback, replacing bash_tool. Use it for performing operations, running queries, triggering actions, etc.
Example
def execute("query " <> sql, _context) do
case MyApp.Repo.query(sql) do
{:ok, result} -> {:ok, format_result(result)}
{:error, err} -> {:error, err}
end
end
@callback modify( path :: String.t(), old_content :: String.t(), new_content :: String.t(), context() ) :: result()
Modify an existing resource.
Replaces str_replace tool. Use for updating existing resources, patching data, etc.
Example
def modify(path, old_content, new_content, _context) do
content = File.read!(path)
updated = String.replace(content, old_content, new_content)
File.write!(path, updated)
{:ok, "Modified #{path}"}
end
Read a resource.
Replaces the view tool. Use for reading files, fetching data, getting resource state, etc.
Options
:offset- Starting position (for pagination):limit- Maximum amount to return
Example
def read("schema/" <> table, _context, _opts) do
schema = MyApp.Repo.get_schema(table)
{:ok, format_schema(schema)}
end
Write/create a resource.
Replaces create_file tool. Use for creating new resources, storing data, writing files, etc.
Example
def write(path, content, _context) do
case File.write(path, content) do
:ok -> {:ok, "Created #{path}"}
{:error, reason} -> {:error, reason}
end
end
Functions
@spec get_info(module()) :: {:ok, skill_info()} | {:error, :not_a_skill}
Get skill info from a module.
Returns {:ok, info} if the module implements __skill_info__/0,
or {:error, :not_a_skill} otherwise.
Check if a module implements the NativeSkill behaviour.
Example
Conjure.NativeSkill.implements?(MyApp.Skills.CacheManager)
# => true
Conjure.NativeSkill.implements?(String)
# => false
Build Claude tool definitions from a native skill module.
Returns a list of tool definitions that can be passed to the Claude API.
Only includes tools listed in allowed_tools.
Example
Conjure.NativeSkill.tool_definitions(MyApp.Skills.CacheManager)
# => [
# %{
# "name" => "cache_manager_execute",
# "description" => "Execute a command for cache-manager skill",
# "input_schema" => %{...}
# },
# ...
# ]