[ AI for FactoryTalk Optix ]

Tell it the change. Review every line.

Describe what you need in plain words, like you'd ask a colleague. Pilotello makes the change on a copy of your FactoryTalk Optix project, checks its work and shows you every line. Nothing is applied until you approve.

Get early access
  • No PLC connection.
  • No production access.
  • You approve every change.
Restyle · experimental
The OvenLine2 Overview screen with Optix's default look: zone values in plain rows, blue default tabs and a default trend.
The OvenLine2 Overview screen after Pilotello's restyle: a dark header with a live clock, four zone tiles with coloured stripes, a process card, a styled trend and a status bar with a red alarm button.
PilotelloRun 20261029-091900
You, excerpt

… the HMI still has Optix's default look … Restyle the whole HMI, the window and all four screens (Overview, Schedule, BakeHistory, Alarms), to our design system …

Agent

Baseline validates clean. I'm snapshotting the original project so I can diff against it later, and checking which UI module definitions the validator can see.

Agent, done

I've restyled the window and all four screens to the design system, and the pack validator passes. Nothing has been opened in Studio or run in Runtime, so the actual on-screen rendering is still unchecked.

2 files restyled, 6 font files added, 78 of 78 bindings kept, model untouched

The window is a design preview. The request and the agent's messages are verbatim from run 20261029-091900-restyle-design-system-pack on the public OvenLine2 project, set to Optix's default look. Both screens are real: the project before, then the agent's result, exported and run in FactoryTalk Optix Runtime by our test harness.
[ Restyle · experimental ]

From Optix defaults to your design system

We gave Pilotello OvenLine2 with Optix's default look and a short design system: colours, fonts and components. It restyled the window and all four screens without touching the model, the logic or a single binding.

Overview[A]Optix default[B]After Pilotello
The OvenLine2 Overview screen with Optix's default look: zone values in plain rows, blue default tabs and a default trend.
The OvenLine2 Overview screen after Pilotello's restyle: a dark header with a live clock, four zone tiles with coloured stripes, a process card, a styled trend and a status bar with a red alarm button.

[A]Default widgets: values in rows, default tabs, default trend colours.

[B]Zone tiles with their series stripes, a process card, a header with the live clock and a status bar with the alarm button.

Schedule[A]Optix default[B]After Pilotello
The Schedule screen with Optix's default look: a list of days with default blue switches and grey buttons.
The Schedule screen after Pilotello's restyle: seven day cards with green ON switches, large start times and square step buttons.

[A]Default switches and buttons in a plain list.

[B]One card per day with an ON/OFF switch, the start time large and a [TODAY] marker.

Bake history[A]Optix default[B]After Pilotello
The Bake History screen with Optix's default look: a default data grid, grey filter buttons and a default trend.
The Bake History screen after Pilotello's restyle: dark and outlined filter buttons, a styled run table and a selected-run card with its trend.

[A]Default grid, buttons and trend.

[B]Filter buttons, a styled run table and a selected-run card with its trend.

  • 9 min 27 sagent time, 53 turns
  • 78 of 78bindings kept
  • 18 of 18button actions kept
  • 95%of colours from the design system
  • 3 of 3runs passed
Agent, verbatim

I've restyled the window and all four screens to the design system, and the pack validator passes. Nothing has been opened in Studio or run in Runtime, so the actual on-screen rendering is still unchecked.

Our harness did: it exported the result and ran it in FactoryTalk Optix Runtime, where these screens were captured.

Captured in FactoryTalk Optix Runtime by our test harness on October 29, 2026: the default project, then the same project with the change from run 20261029-091900-restyle-design-system-pack. Nothing was retouched, so its flaws stay visible: the header shows the project name beside an empty logo box, and on Bake history the trend title overlaps its legend. Read the design system we gave it.

[ One real request ]

Zone 5, before and after

OvenLine2 is a public demo project: a bakery tunnel oven with five heating zones. Zone 5 was in the model but missing from the screens. We asked Pilotello to add it, in one paragraph.

Overview[A]Before[B]After
The OvenLine2 Overview screen before the change: four zone tiles, Z1 to Z4, and four lines on the live temperature trend.
The OvenLine2 Overview screen after the change: five zone tiles, Z1 to Z5, and five lines on the live temperature trend.

[A]Four zone tiles and four lines on the live trend. Zone 5 is running, but not on screen.

[B]A fifth tile for zone 5, in the next free slot, and a fifth line on the live trend.

Bake history[A]Before[B]After
The Bake History screen before the change: the run list has Z1 to Z4 AVG columns and the run trend has four lines.
The Bake History screen after the change: the run list has a new Z5 AVG column and the run trend has a fifth line.

[A]Average temperatures for zones 1 to 4 only, and four lines on the run trend.

[B]A Z5 AVG column in the run list and a fifth line on the run trend.

Both screens were captured in FactoryTalk Optix Runtime by our test harness on October 6, 2026: first the untouched project, then the same project with the change from run 20261005-officiel-04. Nothing was retouched.

[ How it works ]

From a request to a reviewed change

Step to show

Reads your project first

It finds how your project already does things before it proposes anything.

Agent, verbatim

Overview tile: each zone is an instance of the project's ZoneTile type. Its Zone alias points at the model zone, and its colour stripe takes UI/Palette/SeriesN. The tiles sit 248 px apart.

Every source I needed already existed (Model/Oven/Zones/Z5 with PV, SP and Output, and Palette/Series5), so nothing had to be invented.

Works on a copy

It lists every file it will change. Your original project is never touched.

Files changed
  • Nodes/DataStores/DataStores.yaml+9Three database columns
  • Nodes/Loggers/Loggers.yaml+50Zone 5 temperature and setpoint, logged
  • Nodes/UI/Screens/Screens.yaml+180Zone 5 tile, two trend lines, history column
  • ProjectFiles/NetSolution/OvenZones.cs1 line editedZ5 added to the zone list

Checks its work

Automatic checks catch what breaks Optix projects: duplicate IDs, broken links, queries the database refuses, wrong method calls and edits outside the plan.

Checks, automatic
  • No duplicate or malformed node IDsPASS
  • Every link and alias points at a node that existsPASS
  • UTF-8 without BOM, line endings keptPASS
  • No database query the Optix store would refusePASS
  • Every method call matches what the method declaresPASS
  • Only the files in the plan changedPASS
  • No certificates, secrets, drivers or new IP addresses touchedPASS

A search for Z5 now finds it in every place where Z1–Z4 appear.

You approve

You read the full diff, then approve it or send it back.

Agent, verbatim

This is the only line in the whole diff that changed rather than being added.

Exploded view, OvenLine2
BRINDLE & RYE BAKEHOUSEOVERVIEWSCHEDULEBAKE HISTORYALARMSOVERVIEWZ1Z2Z3Z4Z5BELTZONE TEMPERATURESx 24x 272x 520x 768x 1016y 184y 336[03]OVERVIEW1280 × 800Z5 at x 1016OvenLoggerTimestampZ1_PVZ1_SPZ2_PVZ2_SPZ3_PVZ3_SPZ4_PVZ4_SPZ5_PVZ5_SPBakeRunsStartedZ1_AvgZ2_AvgZ3_AvgZ4_AvgZ5_AvgOvenZones.csShown = { "Z1", "Z2", "Z3", "Z4", "Z5" }[02]HISTORYlogger, tablesand the zone listZ1Z2Z3Z4Z5Belt[01]MODELzones Z1 to Z5Z5 already there
  • [01]Model: a tunnel oven, zones Z1 to Z5. Zone 5 is already there
  • [02]History: the run adds Z5 to the logger, to two tables and to the zone list
  • [03]Overview, 1280 × 800: tiles at x 24, 272, 520 and 768; the Z5 tile at x 1016, y 184; a fifth trend line
Drawing of the public OvenLine2 fixture. The free slot and the tile position are the coordinates the agent found and used in run 20261005-officiel-04.
[ You stay in control ]

Nothing changes until you approve

Every change arrives as a diff you can read line by line, with the agent's own list of what it could not check.

Nodes/UI/Screens/Screens.yaml+180, additions only
493+ - Name: TileZ5
494+ Type: ZoneTile
495+ Children:
496+ - Name: LeftMargin
497+ Type: BaseVariableType
498+ DataType: Size
499+ ModellingRule: Optional
500+ Value: 1016.0
501+ - Name: TopMargin
502+ Type: BaseVariableType
503+ DataType: Size
504+ ModellingRule: Optional
505+ Value: 72.0
506+ - Name: Zone
507+ Type: Alias
508+ DataType: NodeId
509+ Value: "/Objects/OvenLine2/Model/Oven/Zones/Z5"
The real diff, first lines. Buttons are a design preview.
Agent, verbatim

What this changes in recorded data: the two store tables each gain a column. On a runtime whose database already holds history, existing rows will have empty Z5 values. Also, the run-journal NetLogic only creates sample history when the database is empty, so on an existing database Z5 will only show values recorded from now on.

Still to check by hand: build the project in Studio, then run it and confirm the fifth tile, both trend pens and the "Z5 AVG" column render and update.

The agent tells you what it didn't check. For this run we checked both: our harness exported the result and ran it in FactoryTalk Optix Runtime (the screens above), and an engineer opened it in Studio and looked at the tile, both trend lines and the history column.

[ Proof ]

Check our work

The Zone 5 change on this page comes from one recorded run on a public project. Here is the rest of it: the full request, the numbers and every changed line.

The request, word for word

In the FactoryTalk Optix 1.7.3 project in the folder OvenLine2, zone 5 of the tunnel oven has just been commissioned: the PLC, simulated here by the OvenSimulation NetLogic, already provides Model/Oven/Zones/Z5 with PV, SP and Output, but the HMI only shows zones 1 to 4. Add zone 5 to the HMI exactly the way zones 1 to 4 are shown, everywhere they appear. Start by analyzing how zones 1 to 4 are shown and state your plan, including every file you will change, before you write anything; follow the project's conventions (types, palette, layout). Constraints: do not change the model (OvenLine2/Nodes/Model/), the OvenSimulation NetLogic or anything under OvenLine2/Nodes/CommDrivers/; no new communication, driver or controller access; reuse the existing variables, and if something you need is missing, stop and report it instead of inventing it; do not modify or delete existing nodes, and keep every existing node Id and namespace. Validate your changes before you finish, then report the files you changed, how you validated them, and a summary of the diff.

Project
OvenLine2, public on GitHub (MIT licence)
Run
20261005-officiel-04, October 5, 2026
Model
Claude Opus 5.5
Agent time
1 min 53 s, 33 turns
Change
4 files, 239 lines added, 1 line edited, nothing deleted
Checks
7 of 7 pass, 0 errors, 0 warnings
Built and run
Exported, compiled and run in FactoryTalk Optix Runtime by our harness, 0 errors
Repeated
3 official runs in a row (04, 05, 06) pass with the same diff
Fingerprints
project 61346a956de5 request b85419b467a8 agent knowledge b7af4c1a39e7
Show the full diff4 files, +240 −1
Nodes/DataStores/DataStores.yaml+9, additions only
@@ -80,6 +80,9 @@ Children:
8080 - Name: Z4_Avg
8181 Type: StoreColumn
8282 DataType: Float
83+ - Name: Z5_Avg
84+ Type: StoreColumn
85+ DataType: Float
8386 - Name: RecordLimit
8487 Type: BaseDataVariableType
8588 DataType: UInt32
@@ -133,6 +136,12 @@ Children:
133136 - Name: Z4_SP
134137 Type: StoreColumn
135138 DataType: Float
139+ - Name: Z5_PV
140+ Type: StoreColumn
141+ DataType: Float
142+ - Name: Z5_SP
143+ Type: StoreColumn
144+ DataType: Float
136145 - Name: RecordLimit
137146 Type: BaseDataVariableType
138147 DataType: UInt32
Nodes/Loggers/Loggers.yaml+50, additions only
@@ -219,6 +219,56 @@ Children:
219219 Type: BaseVariableType
220220 DataType: DynamicLinkMode
221221 Value: 2
222+ - Name: Z5_PV
223+ Type: VariableToLog
224+ DataType: BaseDataType
225+ Children:
226+ - Name: LastValue
227+ Type: PropertyType
228+ DataType: BaseDataType
229+ AccessLevel: Read
230+ - Name: Timestamp
231+ Type: PropertyType
232+ DataType: UtcTime
233+ AccessLevel: Read
234+ - Name: LastOperationCode
235+ Type: PropertyType
236+ DataType: StatusCode
237+ AccessLevel: Read
238+ - Name: DynamicLink
239+ Type: DynamicLink
240+ DataType: NodePath
241+ Value: "../../../../Model/Oven/Zones/Z5/PV"
242+ Children:
243+ - Name: Mode
244+ Type: BaseVariableType
245+ DataType: DynamicLinkMode
246+ Value: 2
247+ - Name: Z5_SP
248+ Type: VariableToLog
249+ DataType: BaseDataType
250+ Children:
251+ - Name: LastValue
252+ Type: PropertyType
253+ DataType: BaseDataType
254+ AccessLevel: Read
255+ - Name: Timestamp
256+ Type: PropertyType
257+ DataType: UtcTime
258+ AccessLevel: Read
259+ - Name: LastOperationCode
260+ Type: PropertyType
261+ DataType: StatusCode
262+ AccessLevel: Read
263+ - Name: DynamicLink
264+ Type: DynamicLink
265+ DataType: NodePath
266+ Value: "../../../../Model/Oven/Zones/Z5/SP"
267+ Children:
268+ - Name: Mode
269+ Type: BaseVariableType
270+ DataType: DynamicLinkMode
271+ Value: 2
222272 - Class: Reference
223273 Target: ns=8;i=21
224274 Direction: Forward
Nodes/UI/Screens/Screens.yaml+180, additions only
@@ -490,6 +490,93 @@ Children:
490490 Type: DynamicLink
491491 DataType: NodePath
492492 Value: "{Zone}/Output"
493+ - Name: TileZ5
494+ Type: ZoneTile
495+ Children:
496+ - Name: LeftMargin
497+ Type: BaseVariableType
498+ DataType: Size
499+ ModellingRule: Optional
500+ Value: 1016.0
501+ - Name: TopMargin
502+ Type: BaseVariableType
503+ DataType: Size
504+ ModellingRule: Optional
505+ Value: 72.0
506+ - Name: Zone
507+ Type: Alias
508+ DataType: NodeId
509+ Value: "/Objects/OvenLine2/Model/Oven/Zones/Z5"
510+ Children:
511+ - Name: Kind
512+ Type: PropertyType
513+ DataType: NodeId
514+ Value: "/Objects/OvenLine2/Model/ZoneType"
515+ - Name: Card
516+ Type: Rectangle
517+ - Name: Stripe
518+ Type: Rectangle
519+ Children:
520+ - Name: FillColor
521+ Type: BaseDataVariableType
522+ DataType: Color
523+ Children:
524+ - Name: DynamicLink
525+ Type: DynamicLink
526+ DataType: NodePath
527+ Value: "/Objects/OvenLine2/UI/Palette/Series5"
528+ - Name: Name
529+ Type: Label
530+ Children:
531+ - Name: Text
532+ Type: BaseDataVariableType
533+ DataType: LocalizedText
534+ Children:
535+ - Name: DynamicLink
536+ Type: DynamicLink
537+ DataType: NodePath
538+ Value: "{Zone}@BrowseName"
539+ - Name: Caption
540+ Type: Label
541+ - Name: PV
542+ Type: Label
543+ Children:
544+ - Name: Text
545+ Type: BaseDataVariableType
546+ DataType: LocalizedText
547+ Children:
548+ - Name: DynamicLink
549+ Type: DynamicLink
550+ DataType: NodePath
551+ Value: "{Zone}/PV"
552+ - Name: PVUnit
553+ Type: Label
554+ - Name: SPCaption
555+ Type: Label
556+ - Name: SP
557+ Type: Label
558+ Children:
559+ - Name: Text
560+ Type: BaseDataVariableType
561+ DataType: LocalizedText
562+ Children:
563+ - Name: DynamicLink
564+ Type: DynamicLink
565+ DataType: NodePath
566+ Value: "{Zone}/SP"
567+ - Name: OutCaption
568+ Type: Label
569+ - Name: Output
570+ Type: Label
571+ Children:
572+ - Name: Text
573+ Type: BaseDataVariableType
574+ DataType: LocalizedText
575+ Children:
576+ - Name: DynamicLink
577+ Type: DynamicLink
578+ DataType: NodePath
579+ Value: "{Zone}/Output"
493580 - Name: BeltCard
494581 Type: Rectangle
495582 Children:
@@ -1247,6 +1334,37 @@ Children:
12471334 DataType: LocalizedText
12481335 ModellingRule: Optional
12491336 Value: {"LocaleId":"en-US","Text":"Z4 PV"}
1337+ - Name: Z5_PV
1338+ Type: TrendPen
1339+ DataType: Float
1340+ Children:
1341+ - Name: Thickness
1342+ Type: BaseDataVariableType
1343+ DataType: Size
1344+ Value: 2.0
1345+ - Name: Enabled
1346+ Type: BaseDataVariableType
1347+ DataType: Boolean
1348+ Value: true
1349+ - Name: Thresholds
1350+ Type: BaseObjectType
1351+ - Name: DynamicLink
1352+ Type: DynamicLink
1353+ DataType: NodePath
1354+ Value: "/Objects/OvenLine2/Loggers/OvenLogger/VariablesToLog/Z5_PV/LastValue"
1355+ - Name: Color
1356+ Type: BaseDataVariableType
1357+ DataType: Color
1358+ Children:
1359+ - Name: DynamicLink
1360+ Type: DynamicLink
1361+ DataType: NodePath
1362+ Value: "/Objects/OvenLine2/UI/Palette/Series5"
1363+ - Name: Title
1364+ Type: BaseDataVariableType
1365+ DataType: LocalizedText
1366+ ModellingRule: Optional
1367+ Value: {"LocaleId":"en-US","Text":"Z5 PV"}
12501368 - Class: Reference
12511369 Target: ns=3;i=1129
12521370 Direction: Forward
@@ -4475,6 +4593,41 @@ Children:
44754593 Type: DynamicLink
44764594 DataType: NodePath
44774595 Value: "{Item}/Z4_Avg"
4596+ - Name: Z5_AvgColumn
4597+ Type: DataGridColumn
4598+ Children:
4599+ - Name: Title
4600+ Type: BaseDataVariableType
4601+ DataType: LocalizedText
4602+ Value: {"LocaleId":"en-US","Text":"Z5 AVG"}
4603+ - Name: Width
4604+ Type: BaseDataVariableType
4605+ DataType: Size
4606+ Value: 56.0
4607+ - Name: Visible
4608+ Type: BaseDataVariableType
4609+ DataType: Boolean
4610+ Value: true
4611+ - Name: HeaderAlignment
4612+ Type: BaseDataVariableType
4613+ DataType: TextHorizontalAlignment
4614+ - Name: ContentAlignment
4615+ Type: BaseVariableType
4616+ DataType: HorizontalAlignment
4617+ - Name: OrderBy
4618+ Type: BaseDataVariableType
4619+ DataType: NodePath
4620+ - Name: DataItemTemplate
4621+ Type: DataGridLabelItemTemplate
4622+ Children:
4623+ - Name: Text
4624+ Type: BaseDataVariableType
4625+ DataType: LocalizedText
4626+ Children:
4627+ - Name: DynamicLink
4628+ Type: DynamicLink
4629+ DataType: NodePath
4630+ Value: "{Item}/Z5_Avg"
44784631 - Name: ResultColumn
44794632 Type: DataGridColumn
44804633 Children:
@@ -5195,6 +5348,33 @@ Children:
51955348 DataType: LocalizedText
51965349 ModellingRule: Optional
51975350 Value: {"LocaleId":"en-US","Text":"Z4 PV"}
5351+ - Name: Z5_PV
5352+ Type: TrendPen
5353+ DataType: Float
5354+ Children:
5355+ - Name: Thickness
5356+ Type: BaseDataVariableType
5357+ DataType: Size
5358+ Value: 2.0
5359+ - Name: Enabled
5360+ Type: BaseDataVariableType
5361+ DataType: Boolean
5362+ Value: true
5363+ - Name: Thresholds
5364+ Type: BaseObjectType
5365+ - Name: Color
5366+ Type: BaseDataVariableType
5367+ DataType: Color
5368+ Children:
5369+ - Name: DynamicLink
5370+ Type: DynamicLink
5371+ DataType: NodePath
5372+ Value: "/Objects/OvenLine2/UI/Palette/Series5"
5373+ - Name: Title
5374+ Type: BaseDataVariableType
5375+ DataType: LocalizedText
5376+ ModellingRule: Optional
5377+ Value: {"LocaleId":"en-US","Text":"Z5 PV"}
51985378 - Class: Reference
51995379 Target: ns=3;i=1129
52005380 Direction: Forward
ProjectFiles/NetSolution/OvenZones.cs1 line edited
@@ -2,5 +2,5 @@
22// Model/Oven/Zones; the run journal logs and averages only the zones listed here.
33public static class OvenZones
44{
5- public static readonly string[] Shown = { "Z1", "Z2", "Z3", "Z4" };
5+ public static readonly string[] Shown = { "Z1", "Z2", "Z3", "Z4", "Z5" };
66}
[ Your machine ]

What leaves your machine

Your local scan stays in your browser.

When you request an AI change, you review the exact files or excerpts that will be securely processed before anything is sent.

[ You review first ]

Data sheet

Planned for launch. Anything not settled says so.
Stays in your browser
The scan of your project folder: which files exist, how screens, types and links are organised.
Sent for a change
Only the files or excerpts you approve, listed with their size before anything is sent. You can remove any of them.
Never sent
Certificates and keys (ProjectFiles/PKI, .pem, .key, .pfx, .p12), .env files and tokens, communication drivers (Nodes/CommDrivers, where PLC addresses live), workstation files (*.optix.design) and Runtime databases.
AI model
Anthropic's API, under commercial terms.
Training on your files
To be confirmed
How long files are kept
To be confirmed
Deleted after each job
To be confirmed
Not promised
Zero retention without a contract. Validation of safety logic. Every Optix version.
[ Questions ]

FAQ

Does Pilotello connect to my PLC or my running HMI?

No. It never connects to a controller, a running HMI or your plant network. Pilotello works on a copy of your project files, and you deploy the result yourself, the way you do today.

What can I ask it to do?

Change an existing FactoryTalk Optix project. The jobs we prove in public are the ones on this page: add a new unit exactly like its siblings, on every screen, trend, log and history table where the others appear; and restyle an HMI to your design system, which is still experimental. Other kinds of changes will be marked experimental until they pass the same tests.

Which versions of FactoryTalk Optix does it support?

Our tests run on FactoryTalk Optix Studio 1.7.3. The supported versions will be listed before launch.

Do I need to install anything?

No. Pilotello will run in your browser. There is no desktop app and no plugin to install in Studio.

Does my project leave my machine?

Your local scan stays in your browser. When you ask for a change, you see the exact files or excerpts that will be sent before anything goes, and you can remove any of them. The data sheet lists what is never sent.

How much will it cost?

Prices will be announced before the limited launch. People on the early access list hear first. Joining the list is free and needs no credit card.

Who gets access first?

People on the early access list, in waves. You get one email when your access opens.

What won't it do?

Deploy to a PLC or an HMI, validate safety logic, or support every version of Optix. And it doesn't replace your review: you approve every change before it is applied.

Is Pilotello affiliated with Rockwell Automation?

No. Pilotello is an independent product. FactoryTalk and Optix are trademarks of Rockwell Automation, Inc.

[ Early access ]

Get early access

Emails about early access only. No sales calls.

Where does your Optix project live?

We use your email only for early access news. Read the privacy notice.