machine:extension:author
Writes a browser workflow by driving a real browser. It observes the live page, asks a model for one step, applies that step in the session, and keeps the ones that worked, so the workflow it emits is a record of a run that actually happened rather than a guess at the site's markup. A step that fails is not discarded silently. Its error goes back into the next prompt, so the model corrects against what the page did rather than against what it assumed. What the loop may write covers the whole of what a page hands over. It reads prose and it reads listings as rows, and where the thing it was sent for is a file behind a form rather than something written on the page, it re-issues that form and keeps the bytes. A wall only a person can get through is not a failure either. The loop writes a step that hands the page to whoever is in front of it, says what they have to do, and waits, and neither the time they take nor the turn it took is charged to the session.
Options
| Name | Type | Description |
|---|---|---|
goal | string | What the authored workflow should accomplish, in plain language |
start_url | string | The page the session opens on |
workflow_id | string | The id the authored workflow is written and synced under |
name | string | The human-readable title of the authored workflow |
provider | string | The inference provider driving the loop |
model | string | The model on that provider |
connection | string | Names the approved connector carrying the provider's API key |
variables | map[string]string | The {{ }} placeholders the authored workflow may use, name to description |
values | map[string]string | Real values for the declared variables, typed into the live page during the authoring session and never written into the emitted workflow |
max_steps | int | How many iterations the loop may take before giving up (default 25). A turn that waited on a person is handed back, up to five of them |
write | bool | Save the authored workflow as a JSON file as well as returning it |
out_dir | string | Where a written workflow JSON lands, relative to the working directory (default "workflows") |
client_id | string | The extension client to drive, a hint the host may honour; empty leaves the choice of browser to the host |
sync | bool | Push the authored workflow into the extension's library when the session ends |
timeout_ms | int | How long the whole authoring session may take before failing, not counting the time it spent waiting on a person |
repairing | []Step | The steps of a fragment that stopped working, so a repair keeps what the fragment was reading instead of starting from the goal alone |
↳ id | string | Uniquely names the step within its workflow, echoed on its StepResult. |
↳ type | string | Is the action to perform (click, fill, select, captureUrl, ...). |
↳ label | string | Is a human-readable description shown in run progress UIs. |
↳ selector | Selector | Picks the DOM node(s) the step acts on. |
↳ css | string | Is a CSS selector. |
↳ path | string | Is an explicit DOM path, used when CSS cannot express the target. |
↳ indexes | []int | Narrows a multi-match selector to these positions. |
↳ enter | []string | Names the subtrees CSS has to resolve inside, outermost first. Each entry selects a shadow host or an iframe, resolved in the tree the previous entry opened, so a control inside a web component inside a same-origin frame is reachable by one Selector. Empty runs CSS against the top document. |
↳ index | int | Narrows a multi-match selector to a single position. |
↳ all | bool | Expands the step to act on every match instead of the first. |
↳ value | string | Is the input for value-taking steps such as fill and select. It may contain {{ variable }} placeholders. |
↳ format | string | Names the shape extraction steps return their data in. |
↳ attribute | string | Names the DOM attribute an extraction step reads. |
↳ fields | ExtractField | Are the named columns an extractList step reads out of each item its selector matched. Key order is the column order, and every returned item carries every key. |
↳ limit | int | Caps how many items an extractList step returns. The extension applies its own bound when this is zero, so a listing that lazily grew to ten thousand rows truncates and says so. |
↳ url | string | Is the address for navigation steps. |
↳ fn | string | Names the page function an eval step invokes. |
↳ args | []any | Are the arguments passed to Fn. |
↳ body_params | map[string]string | Overrides or adds form fields on the request a captureDownload re-issues, and carries the parameters a captureUrl sends, in the query for a GET and form-encoded otherwise. |
↳ method | string | Is the HTTP method a captureUrl step fetches its URL with, defaulting to GET. |
↳ filename | string | Renames a captured file (captureDownload, captureUrl and capturePageFile). It may contain {{ variable }} placeholders. |
↳ output | string | Chooses where a captured file goes, and the controlling client is its only destination. |
↳ wait | WaitConfig | Blocks the step until a page condition holds. |
↳ selector | string | Waits for a matching element to appear (or disappear, see Absent). |
↳ text | string | Waits for this text to be present on the page. |
↳ url_includes | string | Waits for the page URL to contain this substring. |
↳ absent | bool | Flips the wait to expect the selector to disappear rather than appear. |
↳ delay_ms | int | Is a fixed pause in milliseconds, applied on top of any condition. |
↳ timeout_ms | int | Bounds the wait, in milliseconds. |
↳ prompt | string | Is the text shown at a user gate asking for manual input. |
↳ continue_on | ContinueCondition | Holds the step until a user gate is cleared or a page condition is met. |
↳ manual | bool | Pauses the run for an explicit user continue. |
↳ selector | string | Resumes when a matching element appears. |
↳ text | string | Resumes when this text is present on the page. |
↳ url_includes | string | Resumes when the page URL contains this substring. |
↳ timeout_ms | int | Bounds the hold, in milliseconds. |
↳ timeout_ms | int | Overrides the workflow's default step timeout, in milliseconds. |
↳ optional | bool | Lets the run continue when this step fails. |
↳ condition | Condition | Condition, when set, gates the step. If it does not hold, the step is skipped rather than failed. |
↳ selector | string | Holds when a matching element exists on the page. |
↳ text | string | Holds when the page (or the selected element) contains this text. |
↳ url_includes | string | Holds when the page URL contains this substring. |
↳ match | string | Decides how the set predicates combine, "any" or "all". |
↳ negate | bool | Inverts the combined result. |
↳ store | string | Names a slot the step's data is saved under, readable by later steps and returned on the WorkflowResult. |
↳ resume | ResumePoint | Resume, when set, marks this step as a point a re-run may start at, and carries the predicate recognizing a browser already standing there. |
↳ id | string | Names this point so a later point's Rewind can reach it. It is unique within one workflow. |
↳ when | Condition | Recognizes the browser standing at this point. |
↳ selector | string | Holds when a matching element exists on the page. |
↳ text | string | Holds when the page (or the selected element) contains this text. |
↳ url_includes | string | Holds when the page URL contains this substring. |
↳ match | string | Decides how the set predicates combine, "any" or "all". |
↳ negate | bool | Inverts the combined result. |
↳ rewind | Rewind | Rewind, when set, is how the browser leaves this point for an earlier one. |
↳ to | string | Names the resume point this reaches, which must sit earlier in the step list than the point declaring it. |
↳ url | string | Navigates the tab back to the earlier point. |
↳ selector | string | Clicks a control on the current page that leads back, for a flow whose way back is a button rather than an address. |
↳ wait | WaitConfig | Holds until the page has settled after the rewind, before the target point's own predicate is checked again. |
↳ selector | string | Waits for a matching element to appear (or disappear, see Absent). |
↳ text | string | Waits for this text to be present on the page. |
↳ url_includes | string | Waits for the page URL to contain this substring. |
↳ absent | bool | Flips the wait to expect the selector to disappear rather than appear. |
↳ delay_ms | int | Is a fixed pause in milliseconds, applied on top of any condition. |
↳ timeout_ms | int | Bounds the wait, in milliseconds. |
↳ always | bool | Runs the step even when re-entry starts the run past it, for work the page cannot report as already done. |
broken_step | string | The id of the step of that fragment which stopped working |
broken_reason | string | Why that fragment stopped holding up |
Outputs
| Name | Type | Description |
|---|---|---|
workflow | Workflow | The authored workflow, in the extension's wire schema |
↳ id | string | Uniquely names the workflow. Sequences reference library fragments by it. |
↳ name | string | Is the human-readable title shown in the extension UI. |
↳ target | TargetConfig | Locates the page the workflow runs against and controls tab reuse. |
↳ url | string | Is the address to open when no existing tab matches. |
↳ match_url | string | Is a substring an existing tab's URL must contain for the run to reuse that tab instead of opening URL. |
↳ reuse_tab | bool | Reuses a matching open tab instead of opening a new one. Nil means the extension default (true). |
↳ activate | bool | Brings the target tab to the foreground. Nil means the extension default (true). |
↳ reload | bool | Forces a page reload on a reused tab before the first step runs. |
↳ steps | []Step | Are the actions to perform, in order. |
↳ id | string | Uniquely names the step within its workflow, echoed on its StepResult. |
↳ type | string | Is the action to perform (click, fill, select, captureUrl, ...). |
↳ label | string | Is a human-readable description shown in run progress UIs. |
↳ selector | Selector | Picks the DOM node(s) the step acts on. |
↳ css | string | Is a CSS selector. |
↳ path | string | Is an explicit DOM path, used when CSS cannot express the target. |
↳ indexes | []int | Narrows a multi-match selector to these positions. |
↳ enter | []string | Names the subtrees CSS has to resolve inside, outermost first. Each entry selects a shadow host or an iframe, resolved in the tree the previous entry opened, so a control inside a web component inside a same-origin frame is reachable by one Selector. Empty runs CSS against the top document. |
↳ index | int | Narrows a multi-match selector to a single position. |
↳ all | bool | Expands the step to act on every match instead of the first. |
↳ value | string | Is the input for value-taking steps such as fill and select. It may contain {{ variable }} placeholders. |
↳ format | string | Names the shape extraction steps return their data in. |
↳ attribute | string | Names the DOM attribute an extraction step reads. |
↳ fields | ExtractField | Are the named columns an extractList step reads out of each item its selector matched. Key order is the column order, and every returned item carries every key. |
↳ limit | int | Caps how many items an extractList step returns. The extension applies its own bound when this is zero, so a listing that lazily grew to ten thousand rows truncates and says so. |
↳ url | string | Is the address for navigation steps. |
↳ fn | string | Names the page function an eval step invokes. |
↳ args | []any | Are the arguments passed to Fn. |
↳ body_params | map[string]string | Overrides or adds form fields on the request a captureDownload re-issues, and carries the parameters a captureUrl sends, in the query for a GET and form-encoded otherwise. |
↳ method | string | Is the HTTP method a captureUrl step fetches its URL with, defaulting to GET. |
↳ filename | string | Renames a captured file (captureDownload, captureUrl and capturePageFile). It may contain {{ variable }} placeholders. |
↳ output | string | Chooses where a captured file goes, and the controlling client is its only destination. |
↳ wait | WaitConfig | Blocks the step until a page condition holds. |
↳ selector | string | Waits for a matching element to appear (or disappear, see Absent). |
↳ text | string | Waits for this text to be present on the page. |
↳ url_includes | string | Waits for the page URL to contain this substring. |
↳ absent | bool | Flips the wait to expect the selector to disappear rather than appear. |
↳ delay_ms | int | Is a fixed pause in milliseconds, applied on top of any condition. |
↳ timeout_ms | int | Bounds the wait, in milliseconds. |
↳ prompt | string | Is the text shown at a user gate asking for manual input. |
↳ continue_on | ContinueCondition | Holds the step until a user gate is cleared or a page condition is met. |
↳ manual | bool | Pauses the run for an explicit user continue. |
↳ selector | string | Resumes when a matching element appears. |
↳ text | string | Resumes when this text is present on the page. |
↳ url_includes | string | Resumes when the page URL contains this substring. |
↳ timeout_ms | int | Bounds the hold, in milliseconds. |
↳ timeout_ms | int | Overrides the workflow's default step timeout, in milliseconds. |
↳ optional | bool | Lets the run continue when this step fails. |
↳ condition | Condition | Condition, when set, gates the step. If it does not hold, the step is skipped rather than failed. |
↳ selector | string | Holds when a matching element exists on the page. |
↳ text | string | Holds when the page (or the selected element) contains this text. |
↳ url_includes | string | Holds when the page URL contains this substring. |
↳ match | string | Decides how the set predicates combine, "any" or "all". |
↳ negate | bool | Inverts the combined result. |
↳ store | string | Names a slot the step's data is saved under, readable by later steps and returned on the WorkflowResult. |
↳ resume | ResumePoint | Resume, when set, marks this step as a point a re-run may start at, and carries the predicate recognizing a browser already standing there. |
↳ id | string | Names this point so a later point's Rewind can reach it. It is unique within one workflow. |
↳ when | Condition | Recognizes the browser standing at this point. |
↳ selector | string | Holds when a matching element exists on the page. |
↳ text | string | Holds when the page (or the selected element) contains this text. |
↳ url_includes | string | Holds when the page URL contains this substring. |
↳ match | string | Decides how the set predicates combine, "any" or "all". |
↳ negate | bool | Inverts the combined result. |
↳ rewind | Rewind | Rewind, when set, is how the browser leaves this point for an earlier one. |
↳ to | string | Names the resume point this reaches, which must sit earlier in the step list than the point declaring it. |
↳ url | string | Navigates the tab back to the earlier point. |
↳ selector | string | Clicks a control on the current page that leads back, for a flow whose way back is a button rather than an address. |
↳ wait | WaitConfig | Holds until the page has settled after the rewind, before the target point's own predicate is checked again. |
↳ selector | string | Waits for a matching element to appear (or disappear, see Absent). |
↳ text | string | Waits for this text to be present on the page. |
↳ url_includes | string | Waits for the page URL to contain this substring. |
↳ absent | bool | Flips the wait to expect the selector to disappear rather than appear. |
↳ delay_ms | int | Is a fixed pause in milliseconds, applied on top of any condition. |
↳ timeout_ms | int | Bounds the wait, in milliseconds. |
↳ always | bool | Runs the step even when re-entry starts the run past it, for work the page cannot report as already done. |
↳ options | WorkflowOptions | Carries run-wide defaults such as the step timeout and the tab contention policy. |
↳ default_timeout_ms | int | Is the per-step timeout in milliseconds for steps that do not set their own. |
↳ continue_on_error | bool | Keeps the run going past a failed step instead of stopping at the first failure. |
↳ concurrency | string | Is the contention policy when another run already holds the target tab, one of "queue" (default), "parallel", or "reject". |
↳ reentry | bool | Lets a run start at a resume point the live page matches instead of replaying from the first step. Nil means the extension default (true), and an explicit false forces a clean run of a fragment that declares points. |
↳ condition | Condition | Condition, when set, gates the whole workflow. If it does not hold, the run is skipped rather than failed. |
↳ selector | string | Holds when a matching element exists on the page. |
↳ text | string | Holds when the page (or the selected element) contains this text. |
↳ url_includes | string | Holds when the page URL contains this substring. |
↳ match | string | Decides how the set predicates combine, "any" or "all". |
↳ negate | bool | Inverts the combined result. |
path | string | Where the workflow JSON was written, empty unless the run asked for a file |
steps | int | How many steps the session accepted |
done | bool | Whether the model called the goal reached, false when the loop ran out of steps or attempts |
notes | []string | The model's reasoning for each accepted step, in order |
contract | ExtContract | What the authored workflow promises to return, derived from the step it exists to run, which is either the rows it reads or the file it takes |
↳ store | string | Names the slot the rows land in, which is the store of the fragment's own extractList step. |
↳ fields | []string | Are the columns every healthy row carries. A column no row answers is a selector that stopped matching, whatever the run reported. |
↳ min_rows | int | Is the fewest rows a healthy run returns, one by default. A listing that answers with nothing is the case this is here for. |
↳ file | bool | Says the fragment's read is a captured file rather than a listing, so a healthy run is one that came back with bytes under a name. It is the same silence in a different shape, since a capture whose form moved answers with nothing and reports success. |
Examples
Runs one authoring session in a single step, which is the convenience form. The loop it runs is the same one the api registry's aweehub/web/author document spells out step by step, so reach for the document when a run needs to see each turn and for this when it does not. The browser has to be open with the extension connected to the bridge, since the loop writes the workflow by performing it.
name: Author a login workflow by doing it once
vars:
workflow_id: site-login
actions:
- name: author
component: machine:extension:author
vars:
goal: |
Log in with the email address and password the run supplies, and stop
once the account page is on screen.
start_url: https://example.com/login
workflow_id: "{{ var.workflow_id }}"
name: Example - Login
provider: openrouter
model: anthropic/claude-sonnet-5
variables:
email: the account's email address
password: the account's password
values:
email: "{{ env.SITE_EMAIL }}"
password: "{{ env.SITE_PASSWORD }}"
max_steps: 20
write: true
out_dir: ./authored
sync: true
outputs:
workflow: "{{ author.path }}"
finished: "{{ author.done }}"
notes: "{{ author.notes }}"Then run
Authors a workflow and immediately runs it back, which is the loop that turns one supervised session into a fragment the scheduler can fire unattended. The authored fragment reaches the library through the author step's own sync, so the run step only needs its id.
name: Author an invoice export, then run it
actions:
- name: author
component: machine:extension:author
vars:
goal: Open the invoices report for the given period and export it as CSV.
start_url: https://example.com/reports
workflow_id: invoice-export
provider: openrouter
model: anthropic/claude-sonnet-5
variables:
date_from: the first day of the period, as YYYY-MM-DD
date_to: the last day of the period, as YYYY-MM-DD
sync: true
- name: export
component: machine:extension:run
vars:
workflow_id: invoice-export
variables:
date_from: "{{ var.date_from }}"
date_to: "{{ var.date_to }}"
outputs:
authored: "{{ author.workflow }}"
files: "{{ export.stored }}"