Skip to content

Instantly share code, notes, and snippets.

@mpapierski
Last active March 13, 2026 16:04
Show Gist options
  • Select an option

  • Save mpapierski/7a2e9b19ee8c11dba35a65455050cd57 to your computer and use it in GitHub Desktop.

Select an option

Save mpapierski/7a2e9b19ee8c11dba35a65455050cd57 to your computer and use it in GitHub Desktop.
esp-coffee-bridge AI agent skill
name description
coffee-bridge-barista
Use when operating the NIVONA coffee bridge over HTTP to inspect machines, brew drinks, confirm prompts, manage brew history and counter history, adjust history budget, and run bridge backup or restore flows.

Coffee Bridge Barista

Use this skill when the user wants to inspect, control, or automate the local coffee bridge over HTTP.

Keep the workflow grounded in the bridge state:

  1. Check bridge status first with GET /api/status.
  2. List or inspect saved machines before acting.
  3. Read machine summary, recipes, settings, or stats before making strong claims.
  4. Only say a drink was brewed when the bridge accepted the request.
  5. Treat brew history and counter history as different data sets.

Core rules

  • Do not claim a brew completed unless the bridge explicitly confirms more than request acceptance.
  • POST /api/machines/{serial}/brew records an accepted brew request, not a confirmed finished cup.
  • Brew history is the exact bridge-side request log.
  • Counter history is the machine stats timeline and can include local front-panel usage detected by polling.
  • If a brew would overflow the fixed per-machine brew-history budget, the bridge rejects the brew request before dispatch.
  • POST /api/machines/{serial}/history/import recomputes recipeFingerprint on the bridge. Do not try to supply your own fingerprint as authoritative.
  • Use POST /api/machines/{serial}/confirm when summary.status.hostConfirmSuggested is true.

Typical machine flow

  1. GET /api/machines
  2. GET /api/machines/{serial}/summary
  3. If needed:
    • GET /api/machines/{serial}/recipes
    • GET /api/machines/{serial}/recipes/{selector}
    • GET /api/machines/{serial}/mycoffee
    • GET /api/machines/{serial}/stats
    • GET /api/machines/{serial}/settings
  4. Brew with POST /api/machines/{serial}/brew
  5. Read or refresh history with:
    • GET /api/machines/{serial}/history
    • GET /api/machines/{serial}/stats/history

Customizing a drink before brew

If the user wants a customized standard drink, do not guess the allowed fields or enum values.

Use this sequence:

  1. GET /api/machines/{serial}/recipes
    • find the target drink and selector
  2. GET /api/machines/{serial}/recipes/{selector}
    • read the current recipe snapshot
    • read writableFields
    • read options for discrete machine-capped fields
  3. Build a POST /api/machines/{serial}/brew body with:
    • selector
    • only override keys listed in writableFields
    • only enum values present in options
  4. Send the brew request

Important:

  • These overrides are temporary for the started drink.
  • They do not overwrite saved MyCoffee slots.
  • Prefer the live recipe detail over stale assumptions about bean counts, aroma codes, or temperature ranges.
  • If a field is not listed in writableFields, do not send it.
  • For amount fields, respect the current recipe family and field names returned by the bridge such as coffeeAmountMl, waterAmountMl, milkAmountMl, milkFoamAmountMl, or sizeMl.

Bridge and machine endpoints

General

  • GET /api/status
  • GET /api/devices
  • GET /api/details
  • GET /api/logs
  • POST /api/logs/clear
  • POST /api/reboot

Saved machines

  • GET /api/machines
  • POST /api/machines/probe
  • POST /api/machines
  • POST /api/machines/manual
  • POST /api/machines/reset
  • DELETE /api/machines/{serial}
  • GET /api/machines/{serial}/summary

Standard recipes

  • GET /api/machines/{serial}/recipes
  • GET /api/machines/{serial}/recipes/{selector}
    • add ?refresh=1 to force a live reread instead of using the LittleFS cache
    • returned recipes include capability data such as writableFields and field options
    • use this route before customized brews so the agent knows which fields and enum values are valid on the current machine
  • POST /api/machines/{serial}/recipes/refresh

Brew and prompt handling

  • POST /api/machines/{serial}/brew
    • accepts optional metadata:
      • source
      • actor
      • label
      • note
      • correlationId
    • successful accepted brews are appended to brew history
    • the bridge may reject the brew if the next history entry would exceed the configured per-machine history budget
  • POST /api/machines/{serial}/confirm

Example brew body:

{
  "selector": 2,
  "source": "ai",
  "actor": "Barista Agent",
  "label": "Bright Morning Lungo",
  "note": "Softer morning cup."
}

Example customized brew body:

{
  "selector": 2,
  "strengthBeans": 3,
  "aroma": 2,
  "temperature": 2,
  "coffeeAmountMl": 120,
  "source": "ai",
  "actor": "Barista Agent",
  "label": "Bright Morning Lungo"
}

Brew history

  • GET /api/machines/{serial}/history
    • newest entries first
    • supports pagination with ?limit=20&offset=40
  • POST /api/machines/{serial}/history/import
    • accepts:
      • a single entry object
      • { "entry": { ... } }
      • { "entries": [ ... ] }
    • recomputes recipeFingerprint from the compact recipe object
    • stores only supported compact recipe fields
  • POST /api/machines/{serial}/history/clear
  • POST /api/history/config
    • updates the runtime per-machine brew-history budget in bytes
    • clamps the value against the mounted LittleFS size
    • compacts existing history immediately when needed

Example import body:

{
  "entries": [
    {
      "timeUnix": 1773210600,
      "timeIsoUtc": "2026-03-11T06:30:00Z",
      "source": "ai-backfill",
      "actor": "Barista Agent",
      "label": "Bright Morning Lungo",
      "recipe": {
        "selector": 2,
        "name": "lungo",
        "title": "Lungo",
        "strength": 2,
        "strengthBeans": 3,
        "aroma": 2,
        "temperature": 2,
        "coffeeAmountMl": 120
      }
    }
  ]
}

Saved recipes

  • GET /api/machines/{serial}/mycoffee
    • add ?refresh=1 to force a live reread
  • GET /api/machines/{serial}/mycoffee/{slot}
    • add ?refresh=1 to force a live reread of a single slot
  • POST /api/machines/{serial}/mycoffee/{slot}

Machine stats and counter history

  • GET /api/machines/{serial}/stats
  • GET /api/machines/{serial}/stats/history
    • newest snapshots first
    • supports pagination with ?limit=20&offset=40
    • snapshots are only stored when live values change
  • POST /api/machines/{serial}/stats/history/clear

Counter history is not the same as brew history:

  • brew history = accepted bridge brew requests with final applied recipe snapshots
  • counter history = observed machine counters over time, including activity started from the front panel when stats polling notices changes

Settings

  • GET /api/machines/{serial}/settings
  • POST /api/machines/{serial}/settings

Backup and restore

  • GET /api/backup/export
    • downloads an NDJSON bundle containing:
      • saved machines
      • brew-history budget
      • brew-history entries
      • counter-history entries
    • excludes:
      • Wi-Fi credentials
      • protocol-session cache
      • LittleFS recipe caches
  • POST /api/backup/restore
    • accepts a multipart upload
    • replaces the current saved-machine store, brew history, and counter history
    • clears recipe caches and stored protocol-session cache before restore

Wi-Fi and maintenance

  • POST /api/wifi/save
  • POST /api/ota

Protocol diagnostics

Use the saved-machine APIs first. Low-level protocol routes are for diagnostics:

  • /api/protocol/send-frame
  • /api/protocol/app-probe
  • /api/protocol/session
  • /api/protocol/stats-probe
  • /api/protocol/settings-probe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment