The submit
The submit: what execution does
The submit of a skill with kinds is a list of named calls. A kind can have its own, in
kinds.<kind>.submit.
submit:
- name: dispatch
mode: request # request (default) | handover | self
tool: createDelivery
args:
body.address: "$item.fields.address"
body.items: "$selection[kind=dish]"
body.fee: "$item.price"
body.idempotency_key: "$action.key"
line_fields: {ref: slug, quantity: quantity}
| key | meaning |
|---|---|
name | the call's name: letters, digits, _, -. Unique among a skill's calls (its own and its kinds'). Required |
mode | request by default; see the table below |
tool | the operation called. Required for a request: without it, the station is refused |
url | the tenant's link, for a handover |
args | the operation's inputs (body.x, query.y) and their sources |
output | what the call keeps of the tenant's answer, for a later call |
line_fields, line_shape | the shape of a line sent to the tenant |
| mode | meaning | what is sent |
|---|---|---|
request | Convoy calls an operation of the tenant | tool with args |
handover | the person finishes on the tenant's site | nothing; they receive the declared url link |
self | the person takes care of it themselves (pickup at the counter) | nothing; it is recorded |
One call per skill or per kind, today. A list of two calls is refused at load. To chain two
writes, use two skills, each with its call and each the task of a playbook, and have the second
read the first with $submitted[…]. See Current limits.
The sources of args.
| write | gives |
|---|---|
$selection | this skill's lines, one per item |
$selection[kind=X] | the lines of kind X, across the whole selection — filed only if this operation succeeds; otherwise they stay in the selection |
$item.fields.<field> | a filled-in field of the item |
$item.price | the amount computed by the update: {price: …} guard |
$item.ref | the item's reference at the tenant |
$submitted[<task>.<call>].<output> | an output of another call in the same submit — see below |
$params.<name> | a parameter of the skill: the binding a task of the active playbook gives it, else its default — see below |
$action.key | the idempotency key of the action this call files |
$submit.<field> | what the person answered in the submit guard's form, or what the room already knew for an identifies field (Auth) |
Reading another call: $submitted and output
skills:
- name: formation
invoke: {method: recommendLegalStructure}
kinds: {company_formation: {}}
submit:
- name: open
tool: openFormationDossier
args: {body.idempotency_key: "$action.key"}
output: {company_id: "$output.company_id"}
- name: accounting
invoke: {method: getAccountingPlans}
kinds: {accounting_subscription: {}}
submit:
- name: subscribe
tool: subscribeAccounting
args: {body.company_id: "$submitted[societe.open].company_id"}
playbooks:
- name: open-company
tasks:
societe: {skill: formation}
compta: {skill: accounting, required: false, after: [societe]}
- The task is a playbook's:
$submitted[societe.open]cites the callopenof the skillformation, whose task issociete. Written on a skill's call, the reference holds for the whole station (a skill belongs to no playbook): two playbooks may share a task name if it designates the same call; a name two playbooks give to two different calls is refused when read. It does not place the task it reads first: write theafter. - A choice is one reference. Two methods of one
one_ofmay each have a call of the same name (payfor the refund and for the credit note):$submitted[geste.pay]reads the method that was filed. - Only what
outputdeclares can be read. An output is$output(the whole answer) or$output.<path>(a path into the answer). The rest of the answer is kept for no one. - Only a
requesthas an answer.outputon ahandoverorselfcall refuses the station, as does a reference to such a call. - Checked at load. Citing a call no task runs (a skill's name where a task's is meant, a skill
that is the task of no playbook), an undeclared call, an undeclared output, the call's own answer, or
any form other than
$submitted[<task>.<call>].<output>refuses the station. An output nothing reads gives a note. - At execution, the call that reads another runs after it. If the cited call failed, if the
reference cannot be answered, or if two methods of one choice answer it, the dependent call is
put on hold (receipt
held, withwaits_for): it is never filed with a blank value. The same for a line whose stored call reads a source Core does not know: it is put on hold, never sent with that source as its own text; it has to be chosen again. - If the cited task has nothing in the selection, the reference is empty: the tenant applies its own default (the SIREN, for example).
- A retry inside a journey reads what this journey already filed, from the room's record: after a partial submit (the company opened, the accounting refused), the accounting is linked to the company the first submit opened. What an earlier journey filed is never read. If that record cannot be read, the call depending on it is held ("… cannot be read right now — try again in a moment"), never sent blank; if the journey itself cannot be read, the submit is refused. Outside a journey, only an answer whose filed lines are still in the selection is read again.
$params at submit
A submit call reads a parameter of its skill with $params.<name> in its args. Its value is the
binding a task of the active playbook gives it, for the line's method
(A task's params), else the parameter's default.
- A binding leaves with the answer of the call it reads, in the same submit, after it.
- A binding has no fallback. If nothing in this submit or earlier in this journey answered it (the gesture's line left the selection), or if the call it reads failed, the call is put on hold.
- Neither a binding nor a
default: the call is put on hold, with the reason — "… reads $params.refund_id, which nothing sets here — no task of the active playbook binds it, and it has no default". That is the case of a skill run outside the playbook that binds its parameter.
$action.key, never $item.id$item.id is the catalogue reference, the same for every customer who chooses this item. A
tenant that deduplicates on it gives the second customer the first customer's order, with
ok: true. $action.key comes from the room and the lines the call files; it stays stable for a
retry. Two lines filed by two calls get two keys. Several lines filed by one call (three dishes
ordered together) are one action and share one key.
line_fields — what the tenant calls a line's reference and quantity. By default, Convoy
sends {slug, qty}. If the tenant's schema expects quantity, its API ignores an unknown key: it
orders 1 for a customer who wanted 2, with no error. Check its schema.
line_shape: ref — for a tenant that expects a list of identifiers
(timesheet_ids: [..]). Refused on a part that has quantities.
handover — the URL is the tenant's, with a closed set of placeholders: {tenant_url},
{items}, {room}. An unknown placeholder makes the station refuse to start.
The conditions to meet before executing — the submit guard — are in Policies.