agentic examples

The Omakase Scaffold

The Omakase Scaffold: `rails new` for plans. You bring six lines of intent - a name and some steps. The generator brings the menu: journaling on, retries configured, concurrency chosen, a runnable file with your name on it. Convention over configuration isn't about taking choices away; it's about not making you answer forty questions before hello-world. And the output is JUST RUBY - a file you own, edit, and outgrow. The scaffold is a starting line, not a cage.

Scheduling & Concurrency Round 17 DHH exit 0

source on github

bundle exec ruby examples/omakase_scaffold.rb

a real captured run

THE OMAKASE SCAFFOLD (six lines of intent, a running plan back)

  recipe "newsletter_digest" (4 steps declared)
    generated: newsletter_digest.rb (46 lines you didn't write)
    ran it:    "newsletter_digest: completed, 4/4 steps, journal at /tmp/newsletter_digest.jsonl"

  recipe "release_notes" (3 steps declared)
    generated: release_notes.rb (40 lines you didn't write)
    ran it:    "release_notes: completed, 3/3 steps, journal at /tmp/release_notes.jsonl"

  the recipe says WHAT (steps and order); the scaffold supplies the
  HOW everyone forgets until 2am - journaling, retries with jittered
  backoff, a sane concurrency ceiling. that's omakase: the chef
  chooses, you eat well, and if you hate the fish you own the
  kitchen - the generated file is plain Ruby with your name on it,
  TODOs where your work goes, no framework umbilical. generators
  are how conventions travel; a convention nobody scaffolds is a
  convention nobody follows.

source

# frozen_string_literal: true

# The Omakase Scaffold: `rails new` for plans. You bring six lines
# of intent - a name and some steps. The generator brings the menu:
# journaling on, retries configured, concurrency chosen, a runnable
# file with your name on it. Convention over configuration isn't
# about taking choices away; it's about not making you answer forty
# questions before hello-world. And the output is JUST RUBY - a file
# you own, edit, and outgrow. The scaffold is a starting line, not
# a cage.
#
#   bundle exec ruby examples/omakase_scaffold.rb
#
# Runs offline; two recipes are scaffolded, and the generated
# programs are actually RUN - the proof of a generator is its output
# booting, not its template compiling.

require class="s">"bundler/setup"
require class="s">"agentic"
require class="s">"open3"
require class="s">"rbconfig"
require class="s">"tmpdir"

ROOT = File.expand_path(class="s">"..", __dir__)

# --- the whole interface: what a recipe author writes ------------------------------
RECIPES = [
  {name: class="s">"newsletter_digest",
   steps: [
     {step: class="s">"collect articles"},
     {step: class="s">"rank by relevance", after: class="s">"collect articles"},
     {step: class="s">"draft summary", after: class="s">"rank by relevance"},
     {step: class="s">"format email", after: class="s">"draft summary"}
   ]},
  {name: class="s">"release_notes",
   steps: [
     {step: class="s">"gather merged prs"},
     {step: class="s">"gather closed issues"},
     {step: class="s">"write highlights", after: [class="s">"gather merged prs", class="s">"gather closed issues"]}
   ]}
].freeze

# --- the generator: conventions poured around the recipe ---------------------------
def scaffold(recipe, dir)
  vars = recipe[class="y">:steps].each_with_index.to_h { |s, i| [s[class="y">:step], class="s">"task_#{i}"] }
  task_lines = recipe[class="y">:steps].map do |s|
    deps = Array(s[class="y">:after]).map { |d| vars.fetch(d) }
    <<~RUBY.chomp
      #{vars[s[:step]]} = Agentic::Task.new(description: #{s[:step].inspect}, agent_spec: {"name" => #{s[:step].inspect}, "instructions" => "do it"})
      orchestrator.add_task(#{vars[s[class="y">:step]]}, [#{deps.join(class="s">", ")}], agent: ->(t) {
        # TODO: replace this stub with your real work for #{s[:step].inspect}
        class="s">"#{s[class="y">:step]}: done#{" (given: \#{t.previous_output})class="s">" if deps.any?}"
      })
    RUBY
  end

  source = <<~RUBY
    # frozen_string_literal: true
    # Generated by omakase_scaffold - and immediately YOURS. Edit freely.
    require class="s">"agentic"
    require class="s">"tmpdir"

    Agentic.logger.level = class="y">:fatal

    # Omakase defaults: a journal (so every run is replayable), a retry
    # policy (transient errors get three chances), a concurrency ceiling
    # (parallel where the graph allows, never a stampede). Disagree with
    # any of it? It's your file now - change it.
    journal = Agentic:class="y">:ExecutionJournal.new(path: File.join(Dir.tmpdir, class="s">"#{recipe[class="y">:name]}.jsonl"))
    orchestrator = Agentic:class="y">:PlanOrchestrator.new(
      concurrency_limit: 4,
      lifecycle_hooks: journal.lifecycle_hooks,
      retry_policy: {max_retries: 3, backoff_base: 0.05, backoff_jitter: class="y">:full}
    )

    #{task_lines.join("\n\n").gsub("\n", "\n    ").strip}

    result = orchestrator.execute_plan
    done = result.results.values.count(&class="y">:successful?)
    puts class="s">"#{recipe[class="y">:name]}: \#{result.status}, \#{done}/#{recipe[class="y">:steps].size} steps, journal at \#{journal.path}"
    exit(result.status == class="y">:completed ? 0 : 1)
  RUBY

  path = File.join(dir, class="s">"#{recipe[class="y">:name]}.rb")
  File.write(path, source)
  path
end

puts class="s">"THE OMAKASE SCAFFOLD (six lines of intent, a running plan back)"
puts

failures = 0
Dir.mktmpdir(class="s">"omakase") do |dir|
  RECIPES.each do |recipe|
    path = scaffold(recipe, dir)
    lines = File.read(path).lines.size
    # The generated program finds agentic through this repo's bundle
    out, err, status = Open3.capture3({class="s">"BUNDLE_GEMFILE" => File.join(ROOT, class="s">"Gemfile")}, RbConfig.ruby, class="s">"-rbundler/setup", path)
    ok = status.success? && out.include?(class="s">"#{recipe[class="y">:name]}: completed")
    failures += 1 unless ok
    puts class="s">"  recipe #{recipe[class="y">:name].inspect} (#{recipe[class="y">:steps].size} steps declared)"
    puts class="s">"    generated: #{File.basename(path)} (#{lines} lines you didn't write)"
    puts class="s">"    ran it:    #{ok ? out.strip.inspect : "FAILED: #{err.lines.last&.strip}class="s">"}"
    puts
  end
end

puts class="s">"  the recipe says WHAT (steps and order); the scaffold supplies the"
puts class="s">"  HOW everyone forgets until 2am - journaling, retries with jittered"
puts class="s">"  backoff, a sane concurrency ceiling. that's omakase: the chef"
puts class="s">"  chooses, you eat well, and if you hate the fish you own the"
puts class="s">"  kitchen - the generated file is plain Ruby with your name on it,"
puts class="s">"  TODOs where your work goes, no framework umbilical. generators"
puts class="s">"  are how conventions travel; a convention nobody scaffolds is a"
puts class="s">"  convention nobody follows."
exit(failures.zero? ? 0 : 1)