diff --git a/lib/imaginative_restoration/ai/pipeline.ex b/lib/imaginative_restoration/ai/pipeline.ex index a44dd69..e25d033 100644 --- a/lib/imaginative_restoration/ai/pipeline.ex +++ b/lib/imaginative_restoration/ai/pipeline.ex @@ -10,30 +10,25 @@ defmodule ImaginativeRestoration.AI.Pipeline do def init(opts) do stage = Keyword.get(opts, :stage) - if stage in [:crop_and_set_prompt, :process] do + if stage in [:crop_and_label, :process] do {:ok, opts} else - {:error, "stage must be either :crop_and_set_prompt or :process"} + {:error, "stage must be either :crop_and_label or :process"} end end @impl true def change(changeset, opts, _context) do case Keyword.fetch!(opts, :stage) do - :crop_and_set_prompt -> + :crop_and_label -> raw = changeset.data.raw case Replicate.invoke("lucataco/florence-2-large", raw) do {:ok, {label, [x, y, w, h]}} -> - # latest prompt (TODO fail gracefully if none exist) - %Prompt{template: template} = ImaginativeRestoration.Sketches.latest_prompt!() - prompt = String.replace(template, "LABEL", label) - cropped = raw |> Utils.crop!(x, y, w, h) |> Utils.to_dataurl!() changeset |> Ash.Changeset.force_change_attribute(:label, label) - |> Ash.Changeset.force_change_attribute(:prompt, prompt) |> Ash.Changeset.force_change_attribute(:cropped, cropped) _ -> @@ -43,7 +38,10 @@ defmodule ImaginativeRestoration.AI.Pipeline do :process -> cropped = changeset.data.cropped model = changeset.data.model - prompt = changeset.data.prompt + + # latest prompt (TODO fail gracefully if none exist) + %Prompt{template: template} = ImaginativeRestoration.Sketches.latest_prompt!() + prompt = String.replace(template, "LABEL", changeset.data.label) with {:ok, ai_image} <- Replicate.invoke(model, cropped, prompt), {:ok, final_image_url} <- Replicate.invoke("lucataco/remove-bg", ai_image) do diff --git a/lib/imaginative_restoration/sketches.ex b/lib/imaginative_restoration/sketches.ex index 5c67b0a..8d33d2d 100644 --- a/lib/imaginative_restoration/sketches.ex +++ b/lib/imaginative_restoration/sketches.ex @@ -6,7 +6,7 @@ defmodule ImaginativeRestoration.Sketches do resource ImaginativeRestoration.Sketches.Sketch do define :init, args: [:raw] define :init_with_model, args: [:raw, :model], action: :init - define :crop_and_set_prompt + define :crop_and_label define :process end diff --git a/lib/imaginative_restoration/sketches/sketch.ex b/lib/imaginative_restoration/sketches/sketch.ex index 16ec924..f6aee1f 100644 --- a/lib/imaginative_restoration/sketches/sketch.ex +++ b/lib/imaginative_restoration/sketches/sketch.ex @@ -53,7 +53,7 @@ defmodule ImaginativeRestoration.Sketches.Sketch do change set_attribute(:model, arg(:model)) end - update :crop_and_set_prompt do + update :crop_and_label do # No attributes needed - will process the sketch's existing raw image # Validate that we have an raw image to work with @@ -64,7 +64,7 @@ defmodule ImaginativeRestoration.Sketches.Sketch do end end - change {Pipeline, stage: :crop_and_set_prompt} + change {Pipeline, stage: :crop_and_label} end update :process do diff --git a/lib/imaginative_restoration_web/live/app_live.ex b/lib/imaginative_restoration_web/live/app_live.ex index aabbaff..9698244 100644 --- a/lib/imaginative_restoration_web/live/app_live.ex +++ b/lib/imaginative_restoration_web/live/app_live.ex @@ -64,7 +64,7 @@ defmodule ImaginativeRestorationWeb.AppLive do Task.start(fn -> dataurl |> ImaginativeRestoration.Sketches.init!() - |> ImaginativeRestoration.Sketches.crop_and_set_prompt!() + |> ImaginativeRestoration.Sketches.crop_and_label!() |> ImaginativeRestoration.Sketches.process!() end) end diff --git a/lib/imaginative_restoration_web/live/prompt_live.ex b/lib/imaginative_restoration_web/live/prompt_live.ex index 04233bb..bae6907 100644 --- a/lib/imaginative_restoration_web/live/prompt_live.ex +++ b/lib/imaginative_restoration_web/live/prompt_live.ex @@ -30,6 +30,9 @@ defmodule ImaginativeRestorationWeb.PromptLive do

Last 5 captures

+
+ <.button phx-click="process_recent">Process Recent Sketches +
<.sketch :for={{dom_id, sketch} <- @streams.sketches} sketch={sketch} id={dom_id} />
@@ -66,6 +69,27 @@ defmodule ImaginativeRestorationWeb.PromptLive do {:noreply, assign(socket, form: form)} end + @impl true + def handle_event("process_recent", _params, socket) do + sketches = + Sketch + |> Ash.Query.for_read(:read) + |> Ash.Query.sort(inserted_at: :desc) + |> Ash.Query.limit(5) + |> Ash.read!() + + sketches + |> Task.async_stream( + fn sketch -> + ImaginativeRestoration.Sketches.process!(sketch) + end, + timeout: :infinity + ) + |> Stream.run() + + {:noreply, put_flash(socket, :info, "Processing recent sketches...")} + end + @impl true def handle_event("save", %{"form" => params}, socket) do case AshPhoenix.Form.submit(socket.assigns.form, params: params) do