Checking on-device AI availability…

Each instance below enhances a plain search input with on-device AI Suggestions: plain rewordings (typo fixes, finished-out phrases, broader related terms) mixed freely with fielded/boolean reformulations wherever Fields are configured, never labeled or capped by which kind of improvement a given one is. Type a natural-language query, wait a moment for Suggestions to appear, then accept one to see that instance's configured Action run. Requires Chrome with the on-device LanguageModel available. Expand the <query-shaper> line under any search box below to see exactly how it's configured.

1. Internet Archive

Fields declared as an inline JSON schema; Format lucene; Action opensearch against a hand-built template (no published OpenSearch document for archive.org). examples cover a range with an open ("before"/wildcard) bound, a grouped OR combined with negation, a typo, and a vague input deliberately given five varied Suggestions.

<query-shaper for="ia-search" ... />
<query-shaper
  for="ia-search"
  fields='[{"name":"mediatype"},{"name":"year","type":"number"},{"name":"creator"},{"name":"subject"},{"name":"language"}]'
  examples='[
    {"input":"climate change documentaries from 2020","suggestions":["mediatype:movies AND subject:\"climate change\" AND year:2020"]},
    {"input":"documentaries from before 2015","suggestions":["mediatype:movies AND year:[* TO 2015]"]},
    {"input":"audio recordings or texts about jazz, not from 2020","suggestions":["(mediatype:audio OR mediatype:texts) AND subject:jazz AND -year:2020"]},
    {"input":"documentries about space","suggestions":["mediatype:movies AND subject:space","documentaries about space"]},
    {"input":"vintage sci-fi films","suggestions":["mediatype:movies AND subject:\"science fiction\"","vintage science fiction movies","classic sci-fi films","mediatype:movies AND subject:vintage","old science fiction movies"]}
  ]'
  format="lucene"
  action="opensearch"
  template="https://archive.org/search?query={searchTerms}"
></query-shaper>

2. Open Library

Format lucene; Action opensearch, with the template sourced directly from Open Library's real OpenSearch description document. examples cover a bounded range, a wildcard open range, a combined field + negation, a grouped OR, a typo, and a vague input given five varied Suggestions. notes directly targets a real bug seen live: the model once assigned "Harry Potter" to author instead of title.

<query-shaper for="ol-search" ... />
<query-shaper
  for="ol-search"
  fields='[{"name":"author"},{"name":"title"},{"name":"language","description":"ISO 639 code"},{"name":"first_publish_year","type":"number"}]'
  examples='[
    {"input":"harry potter books published before 2000","suggestions":["title:\"harry potter\" AND first_publish_year:[1000 TO 2000]"]},
    {"input":"books by cory doctorow in english","suggestions":["author:\"cory doctorow\" AND language:en"]},
    {"input":"books published up to 2005","suggestions":["first_publish_year:[* TO 2005]"]},
    {"input":"books by asimov but not in french","suggestions":["author:\"isaac asimov\" AND -language:fr"]},
    {"input":"tolkien books in english or spanish","suggestions":["author:\"j.r.r. tolkien\" AND (language:en OR language:es)"]},
    {"input":"harry poter books","suggestions":["title:\"harry potter\"","harry potter books"]},
    {"input":"classic fantasy novels","suggestions":["title:fantasy","fantasy novels","classic fantasy books","title:\"lord of the rings\"","fantasy literature classics"]}
  ]'
  notes="A book or series title (e.g. &quot;Harry Potter&quot;, &quot;Lord of the Rings&quot;) always belongs in the title field, never author: only a real person's name belongs in author."
  format="lucene"
  action="opensearch"
  template="https://openlibrary.org/search?q={searchTerms}&mode=everything"
></query-shaper>

3. Wayback Machine: gov collection search

The gov collection itself is fixed configuration baked into the template, never a Field the model varies. Format lucene; the {searchTerms} placeholder sits in a path segment, not a query string. examples cover a bare term mixed with fielded conditions (since "climate policy" isn't itself a declared Field), negation, a wildcard open range in each direction, a typo, and a vague input given five varied Suggestions.

<query-shaper for="wb-search" ... />
<query-shaper
  for="wb-search"
  fields='[{"name":"language"},{"name":"site"},{"name":"year","type":"number"},{"name":"pubdate","type":"date"}]'
  examples='[
    {"input":"government sites about climate policy after 2015","suggestions":["site:gov AND year:[2015 TO *] climate policy"]},
    {"input":"English language government sites","suggestions":["language:en AND site:gov"]},
    {"input":"sites excluding .com domains from 2020","suggestions":["-site:com AND year:2020"]},
    {"input":"old government pages up to 2010","suggestions":["site:gov AND year:[* TO 2010]"]},
    {"input":"goverment sites","suggestions":["site:gov","government sites"]},
    {"input":"climate change resources","suggestions":["climate change","site:gov climate change","climate policy resources","environmental policy sites","site:org climate change"]}
  ]'
  format="lucene"
  action="opensearch"
  template="https://web.archive.org/collection-search/gov/{searchTerms}"
></query-shaper>

4. No Fields declared

No fields attribute at all: the model is never told about any backend fields, so Suggestions stay plain rewordings (typo fixes, finished-out phrases, broader related terms) and never attempt a fielded reformulation, since there's nothing declared to reformulate against.

<query-shaper for="generic-none" />
<query-shaper for="generic-none"></query-shaper>

5. Free-form text Fields

A loosely specified, human-written Fields description still produces sensible Expression Suggestions, helped along here by examples, since a harder-to-parse prose Fields declaration measurably needed more encouragement to attempt a fielded Suggestion at all, covering a range, negation, and grouping.

<query-shaper for="generic-freeform" ... />
<query-shaper
  for="generic-freeform"
  fields="title, author, language:iso-639-1, date (allowed patterns YYYY[-MM[-DD]]), categories (comma-separated list)"
  examples='[
    {"input":"French novels from the 1920s","suggestions":["language:fr AND date:[1920 TO 1929]","french novels 1920s"]},
    {"input":"books by Verne in French","suggestions":["author:\"jules verne\" AND language:fr"]},
    {"input":"novels not in english, from before 1950","suggestions":["-language:en AND date:[* TO 1950]"]},
    {"input":"adventure or mystery novels in french","suggestions":["(categories:adventure OR categories:mystery) AND language:fr"]},
    {"input":"vernes novels","suggestions":["author:\"jules verne\"","verne&apos;s novels"]}
  ]'
></query-shaper>

6. Inline JSON Fields

The more precise, structured declaration path. examples cover a range, the boolean field, negation, a grouped OR, a typo, and a vague input deliberately given five varied Suggestions mixing fielded and plain-rewording styles.

<query-shaper for="generic-json" ... />
<query-shaper
  for="generic-json"
  fields='[{"name":"category"},{"name":"price","type":"number"},{"name":"in_stock","type":"boolean"}]'
  examples='[
    {"input":"electronics under $50","suggestions":["category:electronics AND price:[0 TO 50]","cheap electronics"]},
    {"input":"laptops in stock","suggestions":["category:laptop AND in_stock:true"]},
    {"input":"cheap electronics, not laptops","suggestions":["category:electronics AND -category:laptop AND price:[0 TO 50]"]},
    {"input":"electronics or gadgets under $50","suggestions":["(category:electronics OR category:gadgets) AND price:[0 TO 50]"]},
    {"input":"electroncis under $50","suggestions":["category:electronics AND price:[0 TO 50]","electronics under $50"]},
    {"input":"cheap stuff","suggestions":["price:[0 TO 20]","category:electronics AND price:[0 TO 20]","affordable items","budget electronics","discounted electronics"]}
  ]'
></query-shaper>

7. Custom .format render function

The escape hatch for backends neither built-in preset covers. A render function can't be expressed as an attribute, so it's set imperatively on the .format property once the element is defined. This one renders field=value pairs joined by ; instead of lucene or url-params syntax.

<query-shaper for="generic-custom" ... />
<query-shaper
  id="generic-custom-shaper"
  for="generic-custom"
  fields='[{"name":"category"},{"name":"price","type":"number"}]'
></query-shaper>

<script type="module">
  customElements.whenDefined('query-shaper').then(() => {
    document.querySelector('#generic-custom-shaper').format = (fields) =>
      fields.map((f) => `${f.field ?? 'q'}=${f.value}`).join(';')
  })
</script>