Powered by AppSignal & Oban Pro

Jidoka: Phoenix LiveView Consumer Boundary

18_phoenix_liveview_consumer.livemd

Jidoka: Phoenix LiveView Consumer Boundary

Run in Livebook

Jidoka does not need to render Phoenix components. The reusable boundary is a Jidoka.Session plus an AgentView: the session names the conversation and runtime context, while AgentView projects the runtime state a LiveView can render.

Setup

Mix.install(
  [
    {:jidoka, git: "https://github.com/agentjido/jidoka.git", branch: "main"},
    {:kino, "~> 0.19.0"}
  ],
  config: [
    jidoka: [
      model_aliases: %{fast: "anthropic:claude-haiku-4-5"}
    ]
  ]
)
Jidoka.Kino.setup()

Define An AgentView

defmodule LivebookDemo.AgentView.SupportAgent do
  use Jidoka.Agent

  agent do
    id :livebook_agent_view_support

    schema Zoi.object(%{
      channel: Zoi.string() |> Zoi.default("livebook"),
      session: Zoi.string()
    })
  end

  defaults do
    model :fast
    instructions "You are a support assistant."
  end
end

defmodule LivebookDemo.AgentView.SupportView do
  use Jidoka.AgentView
end

Project Runtime State

session =
  Jidoka.Session.new!(
    agent: LivebookDemo.AgentView.SupportAgent,
    id: "onboarding-demo",
    context: %{channel: "livebook", actor: %{id: "user-1"}}
  )

{:ok, pid} = LivebookDemo.AgentView.SupportView.start_agent(session)
{:ok, view} = LivebookDemo.AgentView.SupportView.snapshot(pid, session)

Map.take(view, [
  :agent_id,
  :conversation_id,
  :runtime_context,
  :visible_messages,
  :streaming_message,
  :status
])

A LiveView can optimistically append the user’s message before the async agent turn completes.

pending = LivebookDemo.AgentView.SupportView.before_turn(view, "My invoice is confusing.")

Map.take(pending, [:status, :visible_messages, :streaming_message])

The lower-level projection remains available for debugging.

{:ok, projection} = Jidoka.Agent.View.snapshot(pid)

projection
|> Map.take([:visible_messages, :streaming_message, :llm_context, :events])

Optional Provider Turn

Jidoka.Kino.chat("AgentView-backed chat", fn ->
  Jidoka.chat(session, "Explain the AgentView boundary in one sentence.")
end)