Jidoka: Imported Agents Deep Dive
Imported agents are constrained JSON/YAML specs. Executable capabilities resolve through explicit registries supplied by the application.
Setup
Mix.install(
[
{:jidoka, git: "https://github.com/mikehostetler/jidoka.git", ref: "924a486f3c1b7e7a943cb3d5ceee0de65f158467"},
{:kino, "~> 0.19.0"}
],
config: [
jidoka: [
model_aliases: %{fast: "anthropic:claude-haiku-4-5"}
]
]
)
Jidoka.Kino.setup()
Build A Registry
defmodule LivebookDemo.Imported.Tools.AddNumbers do
use Jidoka.Tool,
name: "imported_add_numbers",
description: "Adds two integers.",
schema: Zoi.object(%{a: Zoi.integer(), b: Zoi.integer()})
@impl true
def run(%{a: a, b: b}, _context), do: {:ok, %{sum: a + b}}
end
defmodule LivebookDemo.Imported.Tools.MultiplyNumbers do
use Jidoka.Tool,
name: "imported_multiply_numbers",
description: "Multiplies two integers.",
schema: Zoi.object(%{a: Zoi.integer(), b: Zoi.integer()})
@impl true
def run(%{a: a, b: b}, _context), do: {:ok, %{product: a * b}}
end
defmodule LivebookDemo.Imported.MathPlugin do
use Jidoka.Plugin,
description: "Adds multiplication to imported agents.",
tools: [LivebookDemo.Imported.Tools.MultiplyNumbers]
end
defmodule LivebookDemo.Imported.Guardrails.SafePrompt do
use Jidoka.Guardrail, name: "imported_safe_prompt"
@impl true
def call(%Jidoka.Guardrails.Input{message: message}) do
if String.contains?(String.downcase(message), "secret") do
{:error, :unsafe_prompt}
else
:ok
end
end
end
defmodule LivebookDemo.Imported.SupportCharacter do
use Jido.Character,
defaults: %{
name: "Imported Support Advisor",
identity: %{role: "Support specialist"},
voice: %{tone: :professional},
instructions: ["Use the imported support persona."]
}
end
Import From JSON
spec = %{
"agent" => %{
"id" => "livebook_imported_deep_dive",
"description" => "Imported math assistant",
"context" => %{"tenant" => "demo"}
},
"defaults" => %{
"model" => "fast",
"instructions" => "Use available tools when they help. Keep answers short.",
"character" => "support_advisor"
},
"capabilities" => %{
"tools" => ["imported_add_numbers"],
"plugins" => ["math_plugin"]
},
"lifecycle" => %{
"guardrails" => %{
"input" => ["imported_safe_prompt"]
}
}
}
{:ok, imported_agent} =
Jidoka.import_agent(spec,
available_tools: [LivebookDemo.Imported.Tools.AddNumbers],
available_plugins: [LivebookDemo.Imported.MathPlugin],
available_guardrails: [LivebookDemo.Imported.Guardrails.SafePrompt],
available_characters: %{"support_advisor" => LivebookDemo.Imported.SupportCharacter}
)
{:ok, definition} = Jidoka.inspect_agent(imported_agent)
Map.take(definition, [:kind, :id, :description, :context, :tool_names, :guardrails])
Encode the normalized imported agent back to YAML.
{:ok, yaml} = Jidoka.encode_agent(imported_agent, format: :yaml)
yaml
Unknown capabilities fail at import time.
bad_spec = put_in(spec, ["capabilities", "tools"], ["missing_tool"])
{:error, reason} =
Jidoka.import_agent(bad_spec,
available_tools: [LivebookDemo.Imported.Tools.AddNumbers]
)
reason
Optional Provider Turn
{:ok, pid} =
Jidoka.Kino.start_or_reuse("livebook-imported-deep-dive-agent", fn ->
Jidoka.start_agent(imported_agent, id: "livebook-imported-deep-dive-agent")
end)
Jidoka.Kino.chat("Imported deep-dive chat", fn ->
Jidoka.chat(pid, "Use imported_add_numbers to add 9 and 33. Reply with only the sum.")
end)