Skip to main content
Version: Target · roadmap

Product · simple — a shop

The case. The same shop as in the current version. Nothing new on the journey side: it is the shape of the config that changes.

What changes. The search parameter says who can set it. A profile receives the search operation. The station starts in observe: no model acts.

examples/cible/product-simple.yaml
# Product · simple — CIBLE. The same shop as the actuelle example, in the target shape:
# fields are typed, operations say read or write.
station:
id: maison-indigo
kind: product
name: Maison Indigo
guidance: {max_mode: observe} # no model acts until the station is calibrated

global: # applies to every field of its type, every skill
language: fr
currency: EUR # every `type: price` field
locale: fr-FR
timezone: Europe/Paris

apis:
- name: boutique
openapi_url: https://api.maison-indigo.example.fr/openapi.json
base_url: https://api.maison-indigo.example.fr
auth: {type: none}
operations:
- {id: searchProducts, access: read}

profiles: # everything is closed until a profile is granted an operation
anonyme: {when: "identity.authenticated == false", grants: [boutique.searchProducts]}

skills:
- name: articles
cognitive:
objective: "aider à trouver le tissu ou le vêtement qui correspond au projet"
diagnose: [l'usage, la couleur, le budget]
params:
q: {type: text, set_by: [llm, person]} # what the person is looking for
invoke:
method: searchProducts
args: {q: "$params.q"}
present:
fields:
name: {from: name, type: text, role: title}
price: {from: price, type: price, role: billed}
image: {from: image_url, type: image}
page: {from: slug, type: url, role: link, # the shop's own page for this article
template: "https://maison-indigo.example.fr/article/{value}"}
submit:
- {name: commande, mode: handover, url: "https://maison-indigo.example.fr/commande?add={items}"}
render: {component: carousel}

submit_guard:
confirm: true

agent: # the agent Convoy deploys: a client of this station, like any other
name: Maison Indigo
persona: "une conseillère textile qui connaît chaque tissu de l'atelier"
tone: friendly
rules:
- "Ne jamais inventer un article ou un prix : tout vient de l'outil."
emoji: false # a discreet emoji in replies, or none
model: gemini-2.5-flash # the model the agent runs on
portals:
web:
widget:
origins: [https://maison-indigo.example.fr] # the only sites the widget may load on
theme: {primary: "#24508f", secondary: "#f2ede4", font: manrope} # the widget's colours and typeface

What happens​

the person or the agentCoreresult
"a blue wax print for a dress"articles: read of searchProductsa carousel; a read trace in the room
adds two itemsno guardtwo reserved actions, total in euros
"Finalise"confirm; no one but the person in the room (default)the link to the tenant's site

Key points​

  • A simple station stays simple: one profile, no policy, no playbook. The anonyme profile receives boutique.searchProducts, because everything is closed by default.
  • role: billed says which field is the billed price; an item can carry another price field (a struck-through price) without ambiguity.