agentic examples

The Helpful 404

The Helpful 404: every system has three doors where users arrive with a typo - the URL, the config file, and the CLI - and at all three the system is holding the complete list of correct answers at the exact moment it says "not found." Spending one Levenshtein pass there converts a dead end into a one-keystroke fix. This example wires the framework's own Suggestions engine into all three doors, and proves the discipline that makes suggestions trustworthy: the CONSERVATISM …

Observability & Ops Round 20 Yuki Nishijima exit 0

source on github

bundle exec ruby examples/helpful_404.rb

a real captured run

THE HELPFUL 404 (the system was holding the answer key when it said not-found)

  router   /userz/42      -> 404 /userz/42 - did you mean /users/:id?
  router   /xyzzy         -> 404 /xyzzy
  config   max_retrys     -> unknown key 'max_retrys' - did you mean 'max_retries'?
  config   databese_url   -> unknown key 'databese_url'
  cli      stauts         -> no command 'stauts' - did you mean 'status'?
  cli      shipit         -> no command 'shipit'

  score: 3 typos rescued, 3 strangers given honest silence.

  three doors, one engine, one discipline. the engine is the
  framework's own Suggestions module - the same Levenshtein that
  fixes contract keys fixes URLs and subcommands, because a typo
  doesn't care what layer it's in. the discipline is conservatism:
  the threshold scales with word length, so 'stauts' finds 'status'
  but 'shipit' finds nothing - a wrong suggestion ships a confused
  user somewhere CONFIDENTLY, which is strictly worse than a plain
  404. and the reason this feature is so cheap that skipping it is
  a choice: at the moment any system says 'not found', it is
  HOLDING the complete list of things that exist - routes, schema
  keys, commands. the error message is a UI. spend the Levenshtein.

source

# frozen_string_literal: true

# The Helpful 404: every system has three doors where users arrive
# with a typo - the URL, the config file, and the CLI - and at all
# three the system is holding the complete list of correct answers
# at the exact moment it says "not found." Spending one Levenshtein
# pass there converts a dead end into a one-keystroke fix. This
# example wires the framework's own Suggestions engine into all
# three doors, and proves the discipline that makes suggestions
# trustworthy: the CONSERVATISM rule. Garbage gets silence, because
# a wrong suggestion is worse than none - it sends a confused user
# somewhere confidently.
#
#   bundle exec ruby examples/helpful_404.rb
#
# Runs offline; exits 1 unless every typo gets the right hint and
# every stranger gets honest silence.

require class="s">"bundler/setup"
require class="s">"agentic"

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

ROUTES = [class="s">"/users/class="y">:id", class="s">"/orders/class="y">:id", class="s">"/invoices", class="s">"/settings", class="s">"/health"].freeze
CONFIG_SCHEMA = [class="s">"max_retries", class="s">"timeout_ms", class="s">"pool_size", class="s">"log_level"].freeze
CLI_COMMANDS = [class="s">"status", class="s">"deploy", class="s">"rollback", class="s">"logs", class="s">"console"].freeze

# One engine, three doors. Each door normalizes its own shape, then
# asks the same question: closest valid name within the budget?
DOORS = {
  class="s">"router" => {
    candidates: ROUTES.map { |r| r.split(class="s">"/")[1] },
    normalize: ->(input) { input.split(class="s">"/")[1].to_s },
    render: ->(input, hit) { hit ? class="s">"404 #{input} - did you mean /#{hit}#{ROUTES.find { |r| r.include?(hit) }[/\/:\w+/]}?" : class="s">"404 #{input}" }
  },
  class="s">"config" => {
    candidates: CONFIG_SCHEMA,
    normalize: ->(input) { input },
    render: ->(input, hit) { hit ? class="s">"unknown key '#{input}' - did you mean '#{hit}'?" : class="s">"unknown key '#{input}'" }
  },
  class="s">"cli" => {
    candidates: CLI_COMMANDS,
    normalize: ->(input) { input },
    render: ->(input, hit) { hit ? class="s">"no command '#{input}' - did you mean '#{hit}'?" : class="s">"no command '#{input}'" }
  }
}.freeze

TRIALS = [
  {door: class="s">"router", input: class="s">"/userz/42", expect_hint: class="s">"users"},
  {door: class="s">"router", input: class="s">"/xyzzy", expect_hint: nil}, # a stranger; silence
  {door: class="s">"config", input: class="s">"max_retrys", expect_hint: class="s">"max_retries"},
  {door: class="s">"config", input: class="s">"databese_url", expect_hint: nil}, # not close to anything we have
  {door: class="s">"cli", input: class="s">"stauts", expect_hint: class="s">"status"},
  {door: class="s">"cli", input: class="s">"shipit", expect_hint: nil} # aspirational; silence
].freeze

orchestrator = Agentic:class="y">:PlanOrchestrator.new(concurrency_limit: 3)
trial_tasks = TRIALS.map do |trial|
  task = Agentic:class="y">:Task.new(description: class="s">"#{trial[class="y">:door]}: #{trial[class="y">:input]}", agent_spec: {class="s">"name" => trial[class="y">:door], class="s">"instructions" => class="s">"help"})
  orchestrator.add_task(task, agent: ->(_t) {
    door = DOORS[trial[class="y">:door]]
    hit = Agentic:class="y">:Suggestions.suggest(door[class="y">:normalize].call(trial[class="y">:input]), door[class="y">:candidates])
    {message: door[class="y">:render].call(trial[class="y">:input], hit), hit: hit}
  })
  task
end
result = orchestrator.execute_plan

puts class="s">"THE HELPFUL 404 (the system was holding the answer key when it said not-found)"
puts
failures = []
TRIALS.each_with_index do |trial, i|
  outcome = result.task_result(trial_tasks[i].id).output
  status = (outcome[class="y">:hit]&.to_s == trial[class="y">:expect_hint]&.to_s) ? class="s">"ok" : class="s">"WRONG"
  failures << class="s">"#{trial[class="y">:door]} #{trial[class="y">:input]}: suggested #{outcome[class="y">:hit].inspect}, wanted #{trial[class="y">:expect_hint].inspect}" unless status == class="s">"ok"
  puts format(class="s">"  %-8s %-14s -> %s", trial[class="y">:door], trial[class="y">:input], outcome[class="y">:message])
end
puts

hints_given = TRIALS.count { |t| t[class="y">:expect_hint] }
puts class="s">"  score: #{hints_given} typos rescued, #{TRIALS.size - hints_given} strangers given honest silence."
puts
puts class="s">"  three doors, one engine, one discipline. the engine is the"
puts class="s">"  framework's own Suggestions module - the same Levenshtein that"
puts class="s">"  fixes contract keys fixes URLs and subcommands, because a typo"
puts class="s">"  doesn't care what layer it's in. the discipline is conservatism:"
puts class="s">"  the threshold scales with word length, so 'stauts' finds 'status'"
puts class="s">"  but 'shipit' finds nothing - a wrong suggestion ships a confused"
puts class="s">"  user somewhere CONFIDENTLY, which is strictly worse than a plain"
puts class="s">"  404. and the reason this feature is so cheap that skipping it is"
puts class="s">"  a choice: at the moment any system says 'not found', it is"
puts class="s">"  HOLDING the complete list of things that exist - routes, schema"
puts class="s">"  keys, commands. the error message is a UI. spend the Levenshtein."
exit(failures.empty? ? 0 : 1)