Skip to main content

livebook/01_contracts_and_runtime.livemd

# Jidoka Contracts And Runtime

## Section

This notebook shows the Jidoka center of gravity: agent definition data, a compiled
turn plan, preflight inspection, a deterministic tool loop, and hibernate/resume.

```elixir
Mix.install(
  [
    {:kino, "~> 0.14"},
    {:jidoka, path: Path.expand("..", __DIR__)}
  ],
  consolidate_protocols: false
)
```

```elixir
Jidoka.Kino.setup_notebook(model: "test:notebook-model", check_provider?: false)
```

## Define A Small Agent

```elixir
defmodule ContractLookup do
  use Jidoka.Action,
    name: "lookup_contract",
    description: "Returns deterministic contract data.",
    schema:
      Zoi.object(%{
        id: Zoi.string()
      })

  @impl true
  def run(params, _context) do
    id = Map.get(params, :id) || Map.get(params, "id")
    {:ok, %{id: id, status: "active", owner: "Ada"}}
  end
end

defmodule ContractAgent do
  use Jidoka.Agent

  agent :contract_agent do
    model %{provider: :test, id: "notebook-model"}
    instructions "Use lookup_contract before answering contract questions."
  end

  tools do
    action ContractLookup
  end
end
```

## Inspect The Data Contracts

```elixir
spec = ContractAgent.spec()
{:ok, plan} = Jidoka.plan(spec)
{:ok, _inspection} = Jidoka.Kino.debug_agent(ContractAgent)
{:ok, _diagram} = Jidoka.Kino.agent_diagram(ContractAgent)
{:ok, preflight} = Jidoka.Kino.preflight(plan, "Check contract C-100.")

%{
  spec: Jidoka.project(spec),
  plan: Jidoka.project(plan),
  prompt_messages: preflight.prompt.messages
}
```

## Run A Deterministic Tool Loop

```elixir
fake_llm = fn _intent, journal ->
  llm_calls =
    journal.results
    |> Map.values()
    |> Enum.count(&(&1.kind == :llm))

  case llm_calls do
    0 ->
      {:ok, %{type: :operation, name: "lookup_contract", arguments: %{"id" => "C-100"}}}

    1 ->
      {:ok, %{type: :final, content: "Contract C-100 is active and owned by Ada."}}
  end
end

{:ok, result} = ContractAgent.run_turn("Check contract C-100.", llm: fake_llm)

%{
  content: result.content,
  operations: Enum.map(result.agent_state.operation_results, &Jidoka.project/1),
  journal: Jidoka.inspect(result.journal)
}
```

```elixir
{:ok, _timeline} = Jidoka.Kino.timeline(result)
{:ok, _graph} = Jidoka.Kino.call_graph(result)
```

## Hibernate And Resume

```elixir
{:hibernate, snapshot} =
  ContractAgent.run_turn("Check contract C-100.",
    llm: fake_llm,
    checkpoint: :after_prompt
  )

{snapshot.cursor.phase, snapshot.agent_id}
```

```elixir
{:ok, resumed} =
  Jidoka.resume(snapshot,
    llm: fake_llm,
    operations: Jidoka.Runtime.JidoActions.operations([ContractLookup])
  )

resumed.content
```

<!-- livebook:{"offset":2645,"stamp":{"token":"XCP.SSJ-R7d0g5DhKoK0stFdj6WbLjFh3rd5Q2eldCzOM82EohFJ9X4DPDRC2d1e5LqxdLxctZR5Zq3y_BKY9qX_0mVvA-g2Jx_QZQ7KA55Mon0Vc9lG05mnwq5KHEA","version":2}} -->