Jidoka

Hex.pmHex DocsCILicenseWebsiteEcosystemDiscord

A data-driven Elixir agent framework for the Jido ecosystem.

Jidoka turns agent definitions into inspectable, resumable model and tool turns. Use it to build application agents that call LLMs, expose Jido actions, apply controls, keep conversation state, and pause safely for human review.

Elixir DSL / JSON / YAML
Jidoka.Agent.Spec
Jidoka.Turn.Plan
pure workflow steps → effect intents → runtime adapters
result / events / journal / snapshot / session

Jidoka keeps agent definitions small and keeps runtime state explicit. Model calls and operations cross one effect boundary, so tests can replace them with deterministic capabilities.

Why Jidoka

Installation

Jidoka requires Elixir 1.18 or later.

If your project uses Igniter, install the current release from Hex:

mix igniter.install jidoka@0.9.0

For manual installation, add Jidoka to mix.exs:

def deps do
[
{:jidoka, "~> 0.9.0"}
]
end

Then fetch the dependencies:

mix deps.get

Jidoka is beta software. The public API can change before a stable release.

Quick Start

Define an agent with the Spark DSL:

defmodule MyApp.Assistant do
use Jidoka.Agent
agent :assistant do
model "openai:gpt-4o-mini"
instructions "Answer clearly and briefly."
end
end

Export a provider key before a live call:

export OPENAI_API_KEY=...
# or
export ANTHROPIC_API_KEY=...

Jidoka does not implement dotenv loading. ReqLLM is a Jidoka runtime dependency, and it loads .env from the current working directory by default when the application starts. Existing system environment values take priority. For production, disable this behavior and provide credentials through the deployment environment or a secret manager:

# config/runtime.exs
import Config
config :req_llm, load_dotenv: false

Call chat/3 when you need only the final text:

{:ok, text} = Jidoka.chat(MyApp.Assistant, "What can you help me with?")

Call turn/3 when you also need usage, events, and the effect journal:

{:ok, result} =
Jidoka.turn(MyApp.Assistant, "What can you help me with?")
result.content
result.usage
result.events
result.journal.results

Add A Tool

A tool is work declared in an agent's tools block. An action is one Elixir implementation type for a tool. Jidoka normalizes each tool into an operation, which is the contract that the model and runtime use.

defmodule MyApp.LocalTime do
use Jidoka.Action,
name: "local_time",
description: "Returns the local time for a city.",
schema: Zoi.object(%{city: Zoi.string() |> Zoi.default("Chicago")})
@impl true
def run(params, _context) do
city = Map.get(params, :city) || Map.get(params, "city") || "Chicago"
{:ok, %{city: city, time: "09:30"}}
end
end
defmodule MyApp.TimeAgent do
use Jidoka.Agent
agent :time_agent do
model "openai:gpt-4o-mini"
instructions "Use local_time when the user asks for the time."
end
tools do
action MyApp.LocalTime
end
end
{:ok, preflight} =
Jidoka.preflight(MyApp.TimeAgent, "What time is it in Chicago?")
preflight.prompt.operations
{:ok, text} =
Jidoka.chat(MyApp.TimeAgent, "What time is it in Chicago?")

The model can request local_time. Jidoka validates the arguments, runs the action, adds the result to agent state, and asks the model for the final answer.

Choose The Right API

NeedAPI
Final assistant textJidoka.chat/3
Full result, usage, events, and journalJidoka.turn/3
Multi-turn conversation stateJidoka.session/2 and Jidoka.chat/3
Async UI request and event streamJidoka.chat_async/3, Jidoka.stream/2, Jidoka.await/2, and Jidoka.cancel/2
Resume a paused turnJidoka.resume/2
Approve or deny pending workJidoka.approve/3 and Jidoka.deny/3
Inspect the compiled agent or runtime dataJidoka.inspect/2
Assemble a prompt without live effectsJidoka.preflight/3
Run under a Jido agent processJidoka.start_agent/2
Import or export portable agent dataJidoka.import/2 and Jidoka.export/2

Prefer the Jidoka facade in application code. Use the public contract modules when you build stores, adapters, integrations, or inspection tools.

The main success shapes are:

Call targetSuccess shape
Agent, spec, plan, or hosted agent with chat/3{:ok, text}
Caller-managed session with chat/3{:ok, updated_session, text}
Agent, spec, plan, or hosted agent with turn/3{:ok, %Jidoka.Turn.Result{}}
Paused direct turn{:hibernate, snapshot}
Paused caller-managed session{:hibernate, updated_session, snapshot}

Inspect Before A Live Call

Preflight validates the request and assembles the prompt without calling a model or an operation:

{:ok, preflight} =
Jidoka.preflight(
MyApp.TimeAgent,
"What time is it in Chicago?"
)
preflight.prompt.messages
preflight.prompt.operations
preflight.timeline

Use Jidoka.inspect/2 to read the compiled spec and plan:

Jidoka.inspect(MyApp.TimeAgent)

After a turn, use Jidoka.Debug.request/2 for a complete request summary:

{:ok, summary} = Jidoka.Debug.request(result)
summary.prompt.messages
summary.operation_results
summary.usage
summary.replay_diagnostics.status

Keep State And Pause Safely

Use a session when the same agent must keep state across turns:

{:ok, session} = Jidoka.session(MyApp.Assistant, "support-thread-123")
{:ok, session, _text} =
Jidoka.chat(session, "Remember that my team is called Platform.")
{:ok, session, text} =
Jidoka.chat(session, "What is my team called?")

Controls can stop a turn before unsafe work. A stopped turn returns a snapshot:

{:hibernate, snapshot} =
Jidoka.turn(MyApp.SupportAgent, "Refund order A1001")
approval =
snapshot.turn_state.pending_interrupt
|> Jidoka.Review.Response.approve()
{:ok, result} = Jidoka.resume(snapshot, approval: approval)

The built-in in-memory stores are for tests and one-node development. Use application-owned durable stores when state must survive a process or node failure.

Author With Data

You can import agents from JSON or YAML:

version: 1
agent:
id: assistant
model: openai:gpt-4o-mini
instructions: Answer clearly and briefly.
{:ok, spec} = Jidoka.import(yaml)
{:ok, text} = Jidoka.chat(spec, "Hello")

Import resolves executable references, such as actions, controls, Ash resources, and Zoi schemas, through explicit registries. Do not resolve untrusted references without an application policy.

Production Checklist

Before live traffic:

Start with Configuration, Idempotency And Safety, and Tracing And Events.

Examples

The source repository includes deterministic reference agents under examples/:

mix run examples/support_agent/example.exs
mix test --only example:support_agent
mix test --only tool_calling

The Support Agent demonstrates a controlled tool call, human approval with snapshot resume, and operation-result handling. The default scenarios do not use provider keys, network calls, or recorded model fixtures.

The examples run in CI and appear in the published documentation. They are not copied into the Hex package archive.

The Phoenix showcase application lives in showcase/:

cd showcase
mix deps.get
mix phx.server

Standalone Livebooks live in guides/livebooks/. Complete examples keep their Livebook beside their agent code and scenario tests.

Documentation

Use the Documentation Overview to select a path for application development, production operation, integrations, contract work, or maintenance.

GoalStart here
Install and run one agentGetting Started
Understand specs, plans, turns, and effectsCore Concepts
Select a public facade functionPublic Facade
Define agents and toolsAgent DSL and Tools And Operations
Use sessions and durable storesSessions And Stores
Add controls and human reviewControls and Human In The Loop
Test without live providersTesting And Evals
Verify a real provider loopLive LLM Tool Loop
Prepare a deploymentProduction Operator Path

The complete module reference is available on HexDocs.

Development

Run the standard checks from the package root:

mix deps.get
mix format --check-formatted
mix compile --warnings-as-errors
mix test
mix quality
mix docs --warnings-as-errors

Run all example and guide Livebooks with:

mix run scripts/check_livebooks.exs -- --project examples/*/*.livemd guides/livebooks/*.livemd

Live provider tests are opt-in:

mix test --include live test/jidoka/live_req_llm_test.exs

See Contributing and Contributor Testing before you submit a change.

Project Status

The current package version is 0.9.0. The stable application surface is centered on the Jidoka facade, the agent DSL, and public data contracts.

The runtime uses a provider-neutral JSON decision protocol. Native provider tool calling, inline workflow syntax, and additional production adapters remain active design areas.

License

Jidoka is available under the Apache License 2.0. See LICENSE.