A programming language of composable state machines.

Orb is a programming language in which every program is a composition of finite-state behaviors represented as data. The compiler checks every path, and one source compiles to five platforms.

1 npx -y @almadar/orb mcp

Using Orb from an agent

Orb provides a Model Context Protocol (MCP) server. Any MCP-capable agent can run it through npx and use its tools to write and check programs.

Prompt
1 2 3 Build me a chat app in Orb. Orb runs through npx. Register its MCP server with `npx -y @almadar/orb mcp install --client <your client>`, or start it directly with `npx -y @almadar/orb mcp`. Then build with its tools: read `reference`, find behaviors with `behaviors` and `describe_behavior`, compose them, run `validate` until it reports 0 errors and 0 warnings, `play` the machine, and run it with `npx -y @almadar/orb serve <file>`.
01

Programs as state machines

The checkout below is an Orb program from the standard library. Each step is a transition, and the diagram is generated from the same source.

Checkout

Customer Info

Customer Info

The name of the customer placing the order.
The customer's email address.
CheckoutRules.lolololo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 trait CheckoutRules -> @rebindable Checkout [interaction, instance] { state step1 { INIT -> step1 (set @entity.customerName "") (set @entity.email "") (set @entity.orderTotal 0) (set @entity.shippingAddress "") (set @entity.status draft) CHECKOUT_STARTED -> step1 (set @entity.customerName "") (set @entity.email "") (set @entity.orderTotal 0) (set @entity.shippingAddress "") (set @entity.status draft) DRAFT -> step1 (set @entity.customerName ?data.customerName) (set @entity.email ?data.email) (emit CheckoutStepEntered { customerName: ?data.customerName email: ?data.email step: step1 }) NEXT -> step2 when (and ?data.customerName ?data.email) (set @entity.customerName ?data.customerName) (set @entity.email ?data.email) (emit CheckoutStepEntered { customerName: ?data.customerName email: ?data.email step: step2 }) NEXT -> step1 (render-ui toast <Alert dismissible message={"Enter your name and email to continue."} variant={warning} />) (emit CheckoutNextRefused { step: step1 }) } state step2 { INIT -> step1 (set @entity.customerName "") (set @entity.email "") (set @entity.orderTotal 0) (set @entity.shippingAddress "") (set @entity.status draft) CHECKOUT_STARTED -> step1 (set @entity.customerName "") (set @entity.email "") (set @entity.orderTotal 0) (set @entity.shippingAddress "") (set @entity.status draft) DRAFT -> step2 (set @entity.shippingAddress ?data.shippingAddress) (emit CheckoutStepEntered { customerName: @entity.customerName email: @entity.email shippingAddress: ?data.shippingAddress step: step2 }) NEXT -> step3 when (and @entity.customerName @entity.email ?data.shippingAddress) (set @entity.shippingAddress ?data.shippingAddress) (emit CheckoutStepEntered { customerName: @entity.customerName email: @entity.email shippingAddress: ?data.shippingAddress step: step3 }) NEXT -> step2 (render-ui toast <Alert dismissible message={"Enter a shipping address to continue."} variant={warning} />) (emit CheckoutNextRefused { step: step2 }) PREV -> step1 (emit CheckoutStepEntered { step: step1 }) } state step3 { INIT -> step1 (set @entity.customerName "") (set @entity.email "") (set @entity.orderTotal 0) (set @entity.shippingAddress "") (set @entity.status draft) CHECKOUT_STARTED -> step1 (set @entity.customerName "") (set @entity.email "") (set @entity.orderTotal 0) (set @entity.shippingAddress "") (set @entity.status draft) PAYMENT_DONE -> review when (and @entity.customerName @entity.email @entity.shippingAddress) (emit CheckoutStepEntered { customerName: @entity.customerName email: @entity.email orderTotal: @entity.orderTotal shippingAddress: @entity.shippingAddress step: review }) PAYMENT_DONE -> step3 (render-ui toast <Alert dismissible message={"Complete the customer and shipping steps before paying."} variant={warning} />) (emit CheckoutNextRefused { step: step3 }) PAYMENT_FAILED -> step3 (emit CheckoutPaymentFailed { code: ?code, error: ?error }) PREV -> step2 (emit CheckoutStepEntered { customerName: @entity.customerName email: @entity.email shippingAddress: @entity.shippingAddress step: step2 }) } state review { INIT -> step1 (set @entity.customerName "") (set @entity.email "") (set @entity.orderTotal 0) (set @entity.shippingAddress "") (set @entity.status draft) CHECKOUT_STARTED -> step1 (set @entity.customerName "") (set @entity.email "") (set @entity.orderTotal 0) (set @entity.shippingAddress "") (set @entity.status draft) COMPLETE -> complete when (and @entity.customerName @entity.email @entity.shippingAddress) (set @entity.status placed) (persist create Checkout @entity { emit: { failure: CheckoutSaveFailed, success: CheckoutSaved } }) (emit ORDER_PLACED { customerName: @entity.customerName email: @entity.email id: @entity.id orderTotal: @entity.orderTotal shippingAddress: @entity.shippingAddress }) (render-ui toast <Alert dismissible message={"Order placed successfully"} variant={success} />) (emit CheckoutStepEntered { step: complete }) COMPLETE -> review (render-ui toast <Alert dismissible message={"This order is missing details and can't be placed."} variant={warning} />) (emit CheckoutNextRefused { step: review }) PREV -> step3 (emit CheckoutStepEntered { customerName: @entity.customerName email: @entity.email shippingAddress: @entity.shippingAddress step: step3 }) } state complete { INIT -> step1 (set @entity.customerName "") (set @entity.email "") (set @entity.orderTotal 0) (set @entity.shippingAddress "") (set @entity.status draft) CHECKOUT_STARTED -> step1 (set @entity.customerName "") (set @entity.email "") (set @entity.orderTotal 0) (set @entity.shippingAddress "") (set @entity.status draft) CheckoutSaved -> complete CheckoutSaveFailed -> complete (render-ui toast <Alert dismissible message={"Your order could not be completed — please contact support"} variant={error} />) RESTART -> step1 (set @entity.customerName "") (set @entity.email "") (set @entity.orderTotal 0) (set @entity.shippingAddress "") (set @entity.status draft) (emit CheckoutStepEntered { step: step1 }) } emits { ORDER_PLACED -> external { id : string customerName : string email : string shippingAddress : string orderTotal : money } @description "Indicates a purchase order has been successfully submitted." @synonyms "purchased, confirmed, completed, finalized" @tier "domain" CheckoutStepEntered { step : string! customerName : string email : string shippingAddress : string orderTotal : money } @description "The wizard moved to a step; the payload carries what the step shows." @synonyms "step changed, wizard advanced" @tier "internal" CheckoutNextRefused -> external { step : string! } @description "A wizard step was refused because its required inputs are missing." @synonyms "step refused, cannot continue" @tier "domain" CheckoutPaymentFailed { error : string code : string } @description "The card payment was declined; the payment step stays open for a retry." @synonyms "payment failed, card declined" @tier "domain" CheckoutSaved -> internal { id : string } @description "Indicates a checkout configuration has been successfully saved." @synonyms "saved, persisted, stored" @tier "presentation" CheckoutSaveFailed -> internal { error : string code : string } @description "Indicates a failure during the saving of checkout data." @synonyms "error, failure, problem, unsuccessful" @tier "internal" } listens { CheckoutPayment.ServiceStripeStripeCompleted -> PAYMENT_DONE CheckoutPayment.ServiceStripeStripeFailed -> PAYMENT_FAILED CHECKOUT_STARTED { id : string! } @description "The customer chose to go to the full checkout wizard." @synonyms "begin, start, purchase" @tier "domain" DRAFT { data : { customerName : string, email : string, shippingAddress : string } } @description "Keeps what the customer has entered on the current step without moving on, so the step shows it." @synonyms "draft, save progress, fill in" @tier "domain" NEXT { data : { customerName : string, email : string, shippingAddress : string } } @description "Indicates navigation to the next item or step." @synonyms "next, forward, advance" @tier "domain" PREV @description "Navigates to the previous screen or item." @synonyms "back, previous, rewind" @tier "domain" PAYMENT_DONE { result : { id : string!, status : string! } } @description "Indicates a payment transaction has completed successfully." @synonyms "paid, processed, confirmed, finalized" @tier "domain" PAYMENT_FAILED { error : string code : string } @description "Indicates a payment transaction was unsuccessful." @synonyms "error, declined, rejected, unsuccessful" @tier "domain" COMPLETE @description "Indicates a process or transaction has finished successfully." @synonyms "finished, done, succeeded, finalized" @tier "domain" CheckoutSaved { id : string } @description "Indicates a checkout configuration has been successfully saved." @synonyms "saved, persisted, stored" @tier "presentation" CheckoutSaveFailed { error : string code : string } @description "Indicates a failure during the saving of checkout data." @synonyms "error, failure, problem, unsuccessful" @tier "internal" RESTART @description "Starts a new checkout." @synonyms "start over, new order" @tier "domain" } }
INIT
CHECKOUT_STARTED
DRAFT
NEXT
NEXT
INIT
CHECKOUT_STARTED
DRAFT
NEXT
NEXT
PREV
INIT
CHECKOUT_STARTED
PAYMENT_DONE
PAYMENT_DONE
PAYMENT_FAILED
PREV
INIT
CHECKOUT_STARTED
COMPLETE
COMPLETE
PREV
INIT
CHECKOUT_STARTED
CheckoutSaved
CheckoutSaveFailed
RESTART
nowstep1
step2
step3
review
complete
02

Composition of library behaviors

Each component on the screen is a library behavior. The application imports it and supplies its data, event names and configuration; the state machine is defined by the library.

stock-page.lolololo
1 2 3 4 5 6 7 8 9 10 11 12 13 uses Browse from "std/behaviors/std-browse" uses Stats from "std/behaviors/std-stats" uses Graphs from "std/behaviors/std-graphs" trait DemoStockPageList = Browse.traits.BrowseItemBrowse -> DemoStockItem { config { browseLook: "dense" searchField: "name" orderBy: "position" displayPageSize: 12 itemClickEvent: VIEW } }
03

Agents as behaviors

An assistant composed into an application uses the application's declared inputs as its tools. It acts as the signed-in user, through the same transitions as user interaction.

Each added module extends the assistant's available actions.

Guards and access rules apply to the assistant as they apply to a user.

The state machine, not the prompt, determines the outcome.

kflow.lolololo
1 2 3 4 5 6 7 8 9 10 11 orbital KflowAssistant = Agent.orbitals.AgentAssistantOrbital { config { appName: "KFlow" tools: [ { event: Learner.KflowCompanionTools.COMPANION_READ_PATHS }, { event: Learner.KflowCompanionTools.COMPANION_READ_CONCEPT }, { event: Learner.KflowCompanionTools.COMPANION_CREATE_GOAL }, { event: Learner.KflowCompanionTools.COMPANION_MARK_LEARNED } ] } }
04

A closed vocabulary

Counted from the installed catalog. A model selects from this closed vocabulary rather than inventing an API, and each error is reported with a code and a source location.

448

operators

257

UI patterns

327

validation codes, each with a suggested fix

05

Multilingual syntax

A program can be written with English, Arabic or Slovenian keywords; all versions compile to the same code. Further languages can be added by the community as language packs.

stock-desk.lolololo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 trait DemoStockPageDesk -> DemoStockItem [lifecycle, instance] { initial: idle state idle { INIT -> idle (fetch DemoStockItem { emit: { success: STOCK_LOADED } }) SELL_VASES -> idle (persist update DemoStockItem { id: "item-3", onHand: 0, status: "out" } { emit: { success: STOCK_CHANGED } }) } listens { DemoStockPageTour.TOUR_STEP -> SELL_VASES when (= ?event "SELL_VASES") } }
06

Games as state machines

Dungeon Delver, a dungeon crawl based on the D&D 5e rules. Dice, the character sheet, turn-based combat and dungeon generation are each a separate behavior.

Dungeon Delver
HP
LV
1
XP
AC
16
MV
0

Start the delve

Rolls appear here
Chronicle

alive

DUNGEON DELVER

Clear the Warrens beneath the old keep: three floors down lies the stolen Sun Medallion. Click a tile to move, an adjacent monster to attack; Dash (D), Dodge (G), End Turn (Space), descend the stairs (E). Chests heal, traps bite.

Select a tile to move and an adjacent monster to attack. Dash, Dodge and End turn are beside the board.
BoardCombat.lolololo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 trait BoardCombat -> @rebindable DelverGame [lifecycle, instance] { state active { INIT -> active (set @entity.phase idle) ENCOUNTER_START -> active when (and true (> (array/len ?units) 0)) (set @entity.units (array/map ?units (fn u (object/merge { actionUsed: false, moveLeft: 0 } @u)))) (set @entity.combatTiles (if (> (array/len ?tiles) 0) ?tiles (array/flatten (array/map (array/range 0 14) (fn gy (array/map (array/range 0 20) (fn gx { id: (str/concat t- @gx "-" @gy) passable: true room: 1 x: @gx y: @gy }))))))) (set @entity.round 0) (set @entity.turnIndex 0) (set @entity.pending { kind: initiative rolls: {} }) (set @entity.monsterQueue (array/map ?units (fn u (object/get @u id)))) (set @entity.phase rolling-initiative) (emit ROLL { bonus: (object/get (array/first @entity.units) dexMod) count: 1 mode: normal purpose: (str/concat "initiative:" (object/get (array/first @entity.units) id)) sides: 20 }) MOVE -> active when (and true (and (or (== @entity.phase player-turn) (== @entity.phase ended)) (and (== (array/len (array/filter @entity.units (fn u (and (== (object/get @u id) ?unitId) (and (== (object/get @u team) hero) (> (object/get @u hp) 0)))))) 1) (and (grid/in-bounds { x: ?x, y: ?y } 20 14) (and (== (object/get (array/find @entity.combatTiles (fn t (and (== (object/get @t x) ?x) (== (object/get @t y) ?y)))) passable) true) (and (== (array/len (array/filter @entity.units (fn o (and (!= (object/get @o id) ?unitId) (and (> (object/get @o hp) 0) (and (== (object/get @o x) ?x) (== (object/get @o y) ?y))))))) 0) (array/includes (array/map (path/reachable { x: (object/get (array/find @entity.units (fn u (== (object/get @u id) ?unitId))) x) y: (object/get (array/find @entity.units (fn u (== (object/get @u id) ?unitId))) y) } (object/get (array/find @entity.units (fn u (== (object/get @u id) ?unitId))) moveLeft) (array/concat (array/map (array/filter @entity.combatTiles (fn t (not (object/get @t passable)))) (fn t { x: (object/get @t x) y: (object/get @t y) })) (array/map (array/filter @entity.units (fn o (and (!= (object/get @o id) ?unitId) (> (object/get @o hp) 0)))) (fn o { x: (object/get @o x) y: (object/get @o y) }))) 20 14) (fn c (str/concat (object/get @c x) "-" (object/get @c y)))) (str/concat ?x "-" ?y)))))))) (set @entity.units (array/map @entity.units (fn u (if (== (object/get @u id) ?unitId) (object/merge @u { moveLeft: (- (object/get @u moveLeft) (- (array/len (path/astar { x: (object/get @u x) y: (object/get @u y) } { x: ?x, y: ?y } (array/concat (array/map (array/filter @entity.combatTiles (fn t (not (object/get @t passable)))) (fn t { x: (object/get @t x) y: (object/get @t y) })) (array/map (array/filter @entity.units (fn o (and (!= (object/get @o id) ?unitId) (> (object/get @o hp) 0)))) (fn o { x: (object/get @o x) y: (object/get @o y) }))) 20 14)) 1)) x: ?x y: ?y }) @u)))) (emit UNIT_MOVED { unitId: ?unitId x: ?x y: ?y }) ATTACK -> active when (and true (and (== @entity.phase player-turn) (and (== (array/len (array/filter @entity.units (fn u (and (== (object/get @u id) ?attackerId) (and (== (object/get @u team) hero) (and (> (object/get @u hp) 0) (== (object/get @u actionUsed) false))))))) 1) (and (== (array/len (array/filter @entity.units (fn u (and (== (object/get @u id) ?targetId) (and (== (object/get @u team) monster) (> (object/get @u hp) 0)))))) 1) (<= (grid/manhattan-distance { x: (object/get (array/find @entity.units (fn u (== (object/get @u id) ?attackerId))) x) y: (object/get (array/find @entity.units (fn u (== (object/get @u id) ?attackerId))) y) } { x: (object/get (array/find @entity.units (fn u (== (object/get @u id) ?targetId))) x) y: (object/get (array/find @entity.units (fn u (== (object/get @u id) ?targetId))) y) }) 1))))) (set @entity.pending { attackerId: ?attackerId crit: false kind: attack targetId: ?targetId }) (set @entity.units (array/map @entity.units (fn u (if (== (object/get @u id) ?attackerId) (object/merge @u { actionUsed: true }) @u)))) (emit ROLL { bonus: (object/get (array/find @entity.units (fn u (== (object/get @u id) ?attackerId))) attackBonus) count: 1 mode: normal purpose: (str/concat "attack:" ?attackerId) sides: 20 }) COMBAT_DASH -> active when (and true (and (== @entity.phase player-turn) (== (array/len (array/filter @entity.units (fn u (and (== (object/get @u team) hero) (and (> (object/get @u hp) 0) (== (object/get @u actionUsed) false)))))) 1))) (set @entity.units (array/map @entity.units (fn u (if (== (object/get @u team) hero) (object/merge @u { actionUsed: true moveLeft: (+ (object/get @u moveLeft) (object/get @u speed)) }) @u)))) (emit UNIT_DASHED { unitId: (object/get (array/find @entity.units (fn u (== (object/get @u team) hero))) id) }) COMBAT_DODGE -> active when (and true (and (== @entity.phase player-turn) (== (array/len (array/filter @entity.units (fn u (and (== (object/get @u team) hero) (and (> (object/get @u hp) 0) (== (object/get @u actionUsed) false)))))) 1))) (set @entity.units (array/map @entity.units (fn u (if (== (object/get @u team) hero) (object/merge @u { actionUsed: true, dodging: true }) @u)))) (emit UNIT_DODGING { unitId: (object/get (array/find @entity.units (fn u (== (object/get @u team) hero))) id) }) DICE_ROLLED -> active when true (if (str/startsWith ?purpose "initiative:") (do (set @entity.pending { kind: initiative rolls: (object/set (object/get @entity.pending rolls) (str/slice ?purpose 11) ?total) }) (set @entity.monsterQueue (array/drop @entity.monsterQueue 1)) (if (> (array/len @entity.monsterQueue) 0) (emit ROLL { bonus: (object/get (array/find @entity.units (fn u (== (object/get @u id) (array/first @entity.monsterQueue)))) dexMod) count: 1 mode: normal purpose: (str/concat "initiative:" (array/first @entity.monsterQueue)) sides: 20 }) (do (set @entity.initiative (array/map (array/sort (array/map @entity.units (fn u { id: (object/get @u id) sortKey: (+ (* (object/get (object/get @entity.pending rolls) (object/get @u id)) 100) (object/get @u dexMod)) })) sortKey desc) (fn e (object/get @e id)))) (set @entity.round 1) (set @entity.turnIndex 0) (set @entity.pending {}) (if (== (object/get (array/find @entity.units (fn u (== (object/get @u id) (array/first @entity.initiative)))) team) hero) (let ((hero (array/find @entity.units (fn u (== (object/get @u team) hero))))) (if (and (<= (object/get @hero hp) 0) (not (== (object/get @hero stable) true))) (do (set @entity.phase player-turn) (emit TURN_STARTED { round: @entity.round unitId: (object/get @hero id) }) (emit ROLL { bonus: 0 count: 1 mode: normal purpose: deathsave sides: 20 })) (if (== (object/get @hero stable) true) (do (set @entity.phase monster-turn) (set @entity.turnIndex (+ @entity.turnIndex 1)) (set @entity.monsterQueue (array/filter @entity.initiative (fn iid (== (object/get (array/find @entity.units (fn u (== (object/get @u id) @iid))) team) monster)))) (emit MONSTER_STEP { remaining: (array/len @entity.monsterQueue) })) (do (set @entity.phase player-turn) (set @entity.units (array/map @entity.units (fn u (if (== (object/get @u team) "hero") (object/merge @u { actionUsed: false dodging: false moveLeft: (object/get @u speed) }) @u)))) (emit TURN_STARTED { round: @entity.round unitId: (object/get @hero id) }))))) (do (set @entity.phase monster-turn) (set @entity.monsterQueue (array/filter @entity.initiative (fn iid (== (object/get (array/find @entity.units (fn u (== (object/get @u id) @iid))) team) monster)))) (emit MONSTER_STEP { remaining: (array/len @entity.monsterQueue) })))))) (if (str/startsWith ?purpose "attack:") (let ((attacker (array/find @entity.units (fn u (== (object/get @u id) (object/get @entity.pending attackerId))))) (target (array/find @entity.units (fn u (== (object/get @u id) (object/get @entity.pending targetId)))))) (let ((nat (array/first ?kept))) (let ((crit (== @nat 20))) (let ((hit (and (!= @nat 1) (or @crit (>= ?total (object/get @target ac)))))) (if @hit (do (set @entity.pending (object/merge @entity.pending { crit: @crit })) (emit ROLL { bonus: (object/get (object/get @attacker damage) bonus) count: (if @crit (* 2 (object/get (object/get @attacker damage) count)) (object/get (object/get @attacker damage) count)) mode: normal purpose: (str/concat "damage:" (object/get @attacker id)) sides: (object/get (object/get @attacker damage) sides) })) (do (set @entity.pending {}) (emit ATTACK_RESOLVED { attackerId: (object/get @attacker id) crit: false damage: 0 hit: false targetId: (object/get @target id) }) (if (== @entity.phase monster-turn) (emit MONSTER_STEP { remaining: (array/len @entity.monsterQueue) }) null))))))) (if (str/startsWith ?purpose "damage:") (let ((attackerId (object/get @entity.pending attackerId)) (targetId (object/get @entity.pending targetId))) (let ((target (array/find @entity.units (fn u (== (object/get @u id) @targetId))))) (let ((isHero (== (object/get @target team) hero))) (let ((newHp (- (object/get @target hp) ?total))) (do (set @entity.units (array/map @entity.units (fn u (if (== (object/get @u id) @targetId) (object/merge @u { hp: @newHp }) @u)))) (if @isHero (do (set @entity.units (array/map @entity.units (fn u (if (== (object/get @u id) @targetId) (object/merge @u { stable: false }) @u)))) (emit HERO_DAMAGE { amount: ?total crit: (object/get @entity.pending crit) })) null) (if (and (not @isHero) (<= @newHp 0)) (do (set @entity.initiative (array/filter @entity.initiative (fn iid (!= @iid @targetId)))) (emit MONSTER_SLAIN { cr: (object/get @target cr) id: @targetId kind: (object/get @target kind) xpValue: (object/get @target xpValue) }) (emit HERO_GAIN_XP { amount: (object/get @target xpValue) })) null) (emit ATTACK_RESOLVED { attackerId: @attackerId crit: (object/get @entity.pending crit) damage: ?total hit: true targetId: @targetId }) (set @entity.pending {}) (if (> (array/len (array/filter @entity.units (fn u (and (== (object/get @u team) monster) (> (object/get @u hp) 0))))) 0) (if (== @entity.phase monster-turn) (emit MONSTER_STEP { remaining: (array/len @entity.monsterQueue) }) null) (do (set @entity.phase ended) (set @entity.units (array/map @entity.units (fn u (if (and (== (object/get @u team) hero) (> (object/get @u hp) 0)) (object/merge @u { moveLeft: (object/get @u speed) }) @u)))) (emit COMBAT_ENDED { result: won, round: @entity.round })))))))) null))) (if (== ?purpose deathsave) (do (emit DEATH_SAVE { roll: (array/first ?kept) }) (if (!= @entity.phase ended) (do (set @entity.phase monster-turn) (set @entity.turnIndex (+ @entity.turnIndex 1)) (set @entity.monsterQueue (array/filter @entity.initiative (fn iid (== (object/get (array/find @entity.units (fn u (== (object/get @u id) @iid))) team) monster)))) (emit MONSTER_STEP { remaining: (array/len @entity.monsterQueue) })) null)) null) COMBAT_END_TURN -> active when (and true (== @entity.phase player-turn)) (set @entity.phase monster-turn) (set @entity.turnIndex (+ @entity.turnIndex 1)) (set @entity.monsterQueue (array/filter @entity.initiative (fn iid (== (object/get (array/find @entity.units (fn u (== (object/get @u id) @iid))) team) monster)))) (emit MONSTER_STEP { remaining: (array/len @entity.monsterQueue) }) MONSTER_STEP -> active when (and true (== @entity.phase monster-turn)) (if (== (array/len @entity.monsterQueue) 0) (let ((hero (array/find @entity.units (fn u (== (object/get @u team) hero))))) (if (and (<= (object/get @hero hp) 0) (not (== (object/get @hero stable) true))) (do (set @entity.phase player-turn) (set @entity.round (+ @entity.round 1)) (set @entity.turnIndex (+ @entity.turnIndex 1)) (emit TURN_STARTED { round: @entity.round unitId: (object/get @hero id) }) (emit ROLL { bonus: 0 count: 1 mode: normal purpose: deathsave sides: 20 })) (if (== (object/get @hero stable) true) (do (set @entity.phase monster-turn) (set @entity.turnIndex (+ @entity.turnIndex 1)) (set @entity.monsterQueue (array/filter @entity.initiative (fn iid (== (object/get (array/find @entity.units (fn u (== (object/get @u id) @iid))) team) monster)))) (emit MONSTER_STEP { remaining: (array/len @entity.monsterQueue) })) (do (set @entity.phase player-turn) (set @entity.round (+ @entity.round 1)) (set @entity.turnIndex (+ @entity.turnIndex 1)) (set @entity.units (array/map @entity.units (fn u (if (== (object/get @u team) "hero") (object/merge @u { actionUsed: false dodging: false moveLeft: (object/get @u speed) }) @u)))) (emit TURN_STARTED { round: @entity.round unitId: (object/get @hero id) }))))) (let ((mid (array/first @entity.monsterQueue))) (if (== (array/len (array/filter @entity.units (fn u (and (== (object/get @u id) @mid) (> (object/get @u hp) 0))))) 0) (do (set @entity.monsterQueue (array/drop @entity.monsterQueue 1)) (emit MONSTER_STEP { remaining: (array/len @entity.monsterQueue) })) (let ((m (array/find @entity.units (fn u (== (object/get @u id) @mid)))) (hero (array/find @entity.units (fn u (== (object/get @u team) hero))))) (let ((walk (array/reduce (array/range 0 (object/get @m speed)) { stuck: false x: (object/get @m x) y: (object/get @m y) } (fn (acc i) (if (object/get @acc stuck) @acc (let ((dx (- (object/get @hero x) (object/get @acc x))) (dy (- (object/get @hero y) (object/get @acc y)))) (let ((useX (and (!= @dx 0) (>= (math/abs @dx) (math/abs @dy))))) (let ((cand (if @useX { x: (+ (object/get @acc x) (math/sign @dx)) y: (object/get @acc y) } (if (!= @dy 0) { x: (object/get @acc x) y: (+ (object/get @acc y) (math/sign @dy)) } null))) (alt (if @useX (if (!= @dy 0) { x: (object/get @acc x) y: (+ (object/get @acc y) (math/sign @dy)) } null) (if (!= @dx 0) { x: (+ (object/get @acc x) (math/sign @dx)) y: (object/get @acc y) } null)))) (if (and (!= @cand null) (and (grid/in-bounds @cand 20 14) (and (== (object/get (array/find @entity.combatTiles (fn t (and (== (object/get @t x) (object/get @cand x)) (== (object/get @t y) (object/get @cand y))))) passable) true) (== (array/len (array/filter @entity.units (fn o (and (!= (object/get @o id) @mid) (and (> (object/get @o hp) 0) (and (== (object/get @o x) (object/get @cand x)) (== (object/get @o y) (object/get @cand y)))))))) 0)))) { stuck: false x: (object/get @cand x) y: (object/get @cand y) } (if (and (!= @alt null) (and (grid/in-bounds @alt 20 14) (and (== (object/get (array/find @entity.combatTiles (fn t (and (== (object/get @t x) (object/get @alt x)) (== (object/get @t y) (object/get @alt y))))) passable) true) (== (array/len (array/filter @entity.units (fn o (and (!= (object/get @o id) @mid) (and (> (object/get @o hp) 0) (and (== (object/get @o x) (object/get @alt x)) (== (object/get @o y) (object/get @alt y)))))))) 0)))) { stuck: false x: (object/get @alt x) y: (object/get @alt y) } { stuck: true x: (object/get @acc x) y: (object/get @acc y) })))))))))) (do (set @entity.monsterQueue (array/drop @entity.monsterQueue 1)) (if (or (!= (object/get @walk x) (object/get @m x)) (!= (object/get @walk y) (object/get @m y))) (do (set @entity.units (array/map @entity.units (fn u (if (== (object/get @u id) @mid) (object/merge @u { x: (object/get @walk x) y: (object/get @walk y) }) @u)))) (emit UNIT_MOVED { unitId: @mid x: (object/get @walk x) y: (object/get @walk y) })) null) (if (<= (grid/manhattan-distance { x: (object/get @walk x) y: (object/get @walk y) } { x: (object/get @hero x) y: (object/get @hero y) }) 1) (do (set @entity.pending { attackerId: @mid crit: false kind: attack targetId: (object/get @hero id) }) (set @entity.units (array/map @entity.units (fn u (if (== (object/get @u id) @mid) (object/merge @u { actionUsed: true }) @u)))) (emit ROLL { bonus: (object/get @m attackBonus) count: 1 mode: (if (== (object/get @hero dodging) true) disadvantage normal) purpose: (str/concat "attack:" @mid) sides: 20 })) (emit MONSTER_STEP { remaining: (array/len @entity.monsterQueue) })))))))) HERO_DIED -> active when (and true (!= @entity.phase ended)) (set @entity.phase ended) (emit COMBAT_ENDED { result: lost, round: @entity.round }) HERO_DOWN -> active when true (set @entity.units (array/map @entity.units (fn u (if (== (object/get @u team) hero) (object/merge @u { hp: 0, stable: false }) @u)))) HERO_REVIVED -> active when true (set @entity.units (array/map @entity.units (fn u (if (== (object/get @u team) hero) (object/merge @u { hp: 1 }) @u)))) HERO_STABLE -> active when true (set @entity.units (array/map @entity.units (fn u (if (== (object/get @u team) hero) (object/merge @u { stable: true }) @u)))) RESTART -> active (set @entity.units []) (set @entity.combatTiles []) (set @entity.initiative []) (set @entity.round 0) (set @entity.turnIndex 0) (set @entity.phase idle) (set @entity.pending {}) (set @entity.monsterQueue []) } emits { ROLL -> external { sides : number count : number bonus : number mode : string purpose : string } @description "Dice request for the dice atom: initiative, attack, and damage rolls all flow through this single channel, purpose-tagged initiative:<id> / attack:<id> / damage:<id>" @tier "domain" HERO_DAMAGE -> external { amount : number crit : boolean } @description "Damage dealt to the hero unit; the hero-sheet atom applies it to hp and runs the 0-hp down path (crit doubles the death-save failures when the hero is already down)" @tier "domain" DEATH_SAVE -> external { roll : number } @description "A death-save d20 adjudicated by the hero-sheet atom; rolled organically by this atom (purpose deathsave) when the hero unit starts a turn at 0 hp" @tier "domain" HERO_GAIN_XP -> external { amount : number } @description "XP awarded to the hero when a monster is slain (the monster's xpValue); the hero-sheet atom levels on thresholds" @tier "domain" MONSTER_SLAIN -> external { id : string kind : string cr : number xpValue : number } @description "A monster dropped to 0 hp: removed from initiative but KEPT in units as a corpse (every occupancy/targeting guard filters hp > 0) so board renderers can hold its death pose; loot/quest listeners react" @tier "domain" ATTACK_RESOLVED -> external { attackerId : string targetId : string hit : boolean crit : boolean damage : number } @description "An attack fully resolved (roll + damage applied); combat log and fx listeners render the outcome" @tier "domain" TURN_STARTED -> external { unitId : string round : number } @description "A side's turn began (hero player-turn or the monster queue); UI highlights the active side" @tier "domain" UNIT_MOVED -> external { unitId : string x : number y : number } @description "A unit's grid position changed (hero MOVE or monster AI step); board renderers listen" @tier "domain" UNIT_DASHED -> external { unitId : string } @description "The hero took the Dash action: movement refilled by speed, action spent; narrators/loggers listen" @tier "domain" UNIT_DODGING -> external { unitId : string } @description "The hero took the Dodge action: attacks against them roll with disadvantage until their next turn; narrators/loggers listen" @tier "domain" COMBAT_ENDED -> external { result : string round : number } @description "Encounter over: won when the last monster died, lost on HERO_DIED; round-flow listeners route to victory/defeat" @tier "domain" MONSTER_STEP -> external { remaining : number } @description "Internal hop that drives the monster queue one monster per transition; this atom listens to its own emit to chain the queue" @tier "domain" } listens { BoardDice.DICE_ROLLED -> DICE_ROLLED BoardHero.HERO_DIED -> HERO_DIED BoardHero.HERO_DOWN -> HERO_DOWN BoardHero.HERO_REVIVED -> HERO_REVIVED BoardHero.HERO_STABLE -> HERO_STABLE DndDelverPlay.ATTACK -> ATTACK DndDelverPlay.COMBAT_DASH -> COMBAT_DASH DndDelverPlay.COMBAT_DODGE -> COMBAT_DODGE DndDelverPlay.COMBAT_END_TURN -> COMBAT_END_TURN DndDelverPlay.ENCOUNTER_START -> ENCOUNTER_START DndDelverPlay.MOVE -> MOVE DndDelverPlay.RESTART -> RESTART ENCOUNTER_START { units : [{ id : string!, team : string!, x : int, y : int, hp : int, maxHp : int, speed : int, dexMod : int, attackBonus : int, moveLeft : int, actionUsed : boolean, dodging : boolean, stable : boolean, ac : int, kind : string, damage : { count : int, sides : int, bonus : int }, cr : number, xpValue : int }] tiles : [{ id : string!, x : int!, y : int!, passable : boolean!, room : int! }] } MOVE { unitId : string x : number y : number } ATTACK { attackerId : string targetId : string } COMBAT_DASH COMBAT_DODGE DICE_ROLLED { purpose : string rolls : [number] kept : [number] total : number! } COMBAT_END_TURN MONSTER_STEP { remaining : number } @description "Internal hop that drives the monster queue one monster per transition; this atom listens to its own emit to chain the queue" @tier "domain" HERO_DIED { id : string } HERO_DOWN { id : string } HERO_REVIVED { id : string } HERO_STABLE { id : string } RESTART } config { gridHeight : number = 14 @label "Grid Height" @description "Grid row count clamping move + AI bounds" @tier "domain" gridWidth : number = 20 @label "Grid Width" @description "Grid column count clamping move + AI bounds" @tier "domain" running : boolean = true @label "Running" @description "When true, encounter intents are applied; toggle to freeze the encounter" @tier "internal" } }
INIT
ENCOUNTER_START
MOVE
ATTACK
COMBAT_DASH
COMBAT_DODGE
DICE_ROLLED
COMBAT_END_TURN
MONSTER_STEP
HERO_DIED
HERO_DOWN
HERO_REVIVED
HERO_STABLE
RESTART
nowactive
07

Records management

An inventory screen composed from library behaviors: totals, a chart and a table over browser-stored records.

Skip to content
Fieldhouse Stock

Inventory

Every product, how many are left, and what the shelves are worth.
Products

0

Low stock

0

Out of stock

0

Stock value

$0.00

01224FurnitureDecorKitchenTextiles
Product
Walnut chair
CategoryFurniture
On hand0
Reorder at8
Unit price$120.00
Value$0.00
StatusOut
Product
Ceramic vase
CategoryDecor
On hand2
Reorder at5
Unit price$38.00
Value$76.00
StatusLow
Product
Wool throw
CategoryTextiles
On hand3
Reorder at5
Unit price$79.00
Value$237.00
StatusLow
Product
Oak shelf
CategoryFurniture
On hand1
Reorder at3
Unit price$210.00
Value$210.00
StatusLow
Product
Oak dining table
CategoryFurniture
On hand6
Reorder at4
Unit price$640.00
Value$3,840.00
StatusIn stock
Product
Cast iron pan
CategoryKitchen
On hand14
Reorder at6
Unit price$54.00
Value$756.00
StatusIn stock
Product
Chef knife set
CategoryKitchen
On hand9
Reorder at4
Unit price$140.00
Value$1,260.00
StatusIn stock
Product
Brass candle holder
CategoryDecor
On hand22
Reorder at10
Unit price$26.00
Value$572.00
StatusIn stock
DemoStockPageDesk.lolololo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 trait DemoStockPageDesk -> DemoStockItem [lifecycle, instance] { state idle { INIT -> idle (fetch DemoStockItem { emit: { success: STOCK_LOADED } }) STOCK_CHANGED -> idle (fetch DemoStockItem { emit: { success: STOCK_LOADED } }) SELL_TABLES -> idle (persist update DemoStockItem { id: item-1 onHand: 1 position: 2.5 status: low stockValue: 640 } { emit: { success: STOCK_CHANGED } }) SELL_VASES -> idle (persist update DemoStockItem { id: item-3 onHand: 0 position: 0.5 status: out stockValue: 0 } { emit: { success: STOCK_CHANGED } }) RESTOCK_CHAIRS -> idle (persist update DemoStockItem { id: item-4 onHand: 24 position: 9 status: in-stock stockValue: 2880 } { emit: { success: STOCK_CHANGED } }) REORDER_SHELVES -> idle (persist update DemoStockItem { id: item-9 onHand: 12 position: 10 status: in-stock stockValue: 2520 } { emit: { success: STOCK_CHANGED } }) STOCK_RESET -> idle (persist update DemoStockItem { id: item-1 onHand: 6 position: 4 status: in-stock stockValue: 3840 }) (persist update DemoStockItem { id: item-3 onHand: 2 position: 1 status: low stockValue: 76 }) (persist update DemoStockItem { id: item-4 onHand: 0 position: 0 status: out stockValue: 0 }) (persist update DemoStockItem { id: item-5 onHand: 14 position: 5 status: in-stock stockValue: 756 }) (persist update DemoStockItem { id: item-6 onHand: 3 position: 2 status: low stockValue: 237 }) (persist update DemoStockItem { id: item-7 onHand: 22 position: 7 status: in-stock stockValue: 572 }) (persist update DemoStockItem { id: item-8 onHand: 9 position: 6 status: in-stock stockValue: 1260 }) (persist update DemoStockItem { id: item-9 onHand: 1 position: 3 status: low stockValue: 210 } { emit: { success: STOCK_CHANGED } }) } emits { STOCK_LOADED { data : [DemoStockItem] } @description "The products were read; the numbers and charts regroup them." @tier "internal" STOCK_CHANGED @description "The desk changed a stock level; the list reloads." @tier "internal" } listens { DemoStockPageTour.TOUR_STEP -> SELL_TABLES when (= ?event SELL_TABLES) DemoStockPageTour.TOUR_STEP -> SELL_VASES when (= ?event SELL_VASES) DemoStockPageTour.TOUR_STEP -> RESTOCK_CHAIRS when (= ?event RESTOCK_CHAIRS) DemoStockPageTour.TOUR_STEP -> REORDER_SHELVES when (= ?event REORDER_SHELVES) DemoStockPageTour.TOUR_RESET -> STOCK_RESET } }
INIT
STOCK_CHANGED
SELL_TABLES
SELL_VASES
RESTOCK_CHAIRS
REORDER_SHELVES
STOCK_RESET
nowidle
08

Program generation

std-agent-builder produces a program from a request: it ranks the installed behaviors by semantic similarity, constructs the program as data with quasiquote, and validates it with the compiler before saving.

Describe the app you want…

BuilderPipeline.lolololo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 trait BuilderPipeline -> BuilderProcess [lifecycle, instance] { state idle { INIT -> idle (set @entity.status idle) (render-ui main <Typography content={"Ready to build."} variant={caption} />) START -> searching (set @entity.request ?request) (set @entity.orbitalName ?orbitalName) (set @entity.context (str/default ?context "")) (set @entity.step 0) (set @entity.repairs 0) (set @entity.status searching) (emit BUILD_PROGRESS { status: searching tier: "" }) (call-service llm embed { texts: [?request] } { emit: { failure: BUILD_FAILED, success: REQUEST_EMBEDDED } }) FILL -> idle PICK -> idle CONVERSE -> idle ASSISTANT_REPLIED -> idle TOOLS_FAILED -> idle } state searching { INIT -> searching (set @entity.status searching) REQUEST_EMBEDDED -> searching when (> (array/len ?embeddings) 0) (set @entity.queryVector (array/first ?embeddings)) (emit STEP {}) REQUEST_EMBEDDED -> failed when (= (array/len ?embeddings) 0) (set @entity.error "The model returned no embedding") (set @entity.status failed) (render-ui main <Typography content={"Build failed: the model returned no embedding."} variant={caption} />) (emit BUILD_REJECTED { error: "The model returned no embedding" errors: [] }) STEP -> searching when (and (< @entity.step (array/len [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }])) (= (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) source) catalog)) (behavior/catalog { paths: (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) scope []) } { emit: { failure: BUILD_FAILED, success: CATALOG_LISTED } }) STEP -> searching when (and (< @entity.step (array/len [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }])) (= (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) source) pool)) (emit POOL_SEARCH { take: (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) take 5) vector: @entity.queryVector }) STEP -> failed when (>= @entity.step (array/len [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }])) (set @entity.error "No tier of the ladder could serve the request") (set @entity.status failed) (render-ui main <Typography content={"No tier could serve the request."} variant={caption} />) (emit BUILD_REJECTED { error: "No tier of the ladder could serve the request" errors: [] }) CATALOG_LISTED -> searching (set @entity.ranked (array/sort (array/map (array/filter ?result (fn e (> (array/len (object/get @e.vectors description [])) 0))) (fn e { behavior: @e.behavior description: (object/get @e description "") fields: {} score: (array/cosine (object/get @e.vectors description) @entity.queryVector) trait: (array/first @e.traits) value: @e.value })) score desc)) (emit RANKED {}) POOL_FOUND -> searching (set @entity.ranked (array/map ?hits (fn h { behavior: @h.behavior description: (object/get @h description "") fields: (object/get @h fields {}) score: @h.score value: @h.value }))) (emit RANKED {}) RANKED -> searching when (or (= (array/len @entity.ranked) 0) (< (object/get (array/first @entity.ranked) score) (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) threshold))) (set @entity.step (+ @entity.step 1)) (emit STEP {}) RANKED -> building when (and (> (array/len @entity.ranked) 0) (and (>= (object/get (array/first @entity.ranked) score) (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) threshold)) (= (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) action) mount))) (set @entity.pick (object/get (array/first @entity.ranked) trait)) (set @entity.status building) (emit BUILD_PROGRESS { status: building tier: (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) name) }) (program/eval (quasiquote { name: (unquote @entity.orbitalName) orbitals: [{ entity: { fields: [{ name: id, type: string }] name: BuiltView persistence: runtime } name: (unquote @entity.orbitalName) pages: [{ name: Built path: "/" traits: [{ ref: BuiltFrame }] }] traits: [{ linkedEntity: BuiltView name: BuiltFrame scope: instance stateMachine: { events: [{ key: INIT, name: Init }] states: [{ isInitial: true, name: idle }] transitions: [{ effects: [(render-ui main { children: [ [ unquote @entity.pick ] ] type: stack })] event: INIT from: idle to: idle }] } }] }] }) { emit: { failure: BUILD_FAILED, success: BUILT } }) RANKED -> done when (and (> (array/len @entity.ranked) 0) (and (>= (object/get (array/first @entity.ranked) score) (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) threshold)) (= (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) action) adopt))) (set @entity.behavior (object/get (array/first @entity.ranked) behavior)) (set @entity.status done) (render-ui main <Typography content={(str/concat "Adopted " @entity.behavior)} variant={caption} />) (emit BUILD_COMPLETE { behavior: @entity.behavior fields: (object/get (array/first @entity.ranked) fields {}) orbitalName: @entity.orbitalName tier: (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) name) value: (object/get (array/first @entity.ranked) value) }) RANKED -> describing when (and (and (> (array/len @entity.ranked) 0) (and (>= (object/get (array/first @entity.ranked) score) (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) threshold)) (= (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) action) fill))) (or (<= (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) take 1) 1) (= (array/len @entity.ranked) 1))) (set @entity.chosen (object/get (array/first @entity.ranked) behavior)) (set @entity.chosenDescription (object/get (array/first @entity.ranked) description "")) (set @entity.pickedFields {}) (set @entity.status describing) (emit BUILD_PROGRESS { status: describing tier: (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) name) }) (behavior/describe { behavior: @entity.chosen } { emit: { failure: BUILD_FAILED, success: DESCRIBED } }) RANKED -> choosing when (and (and (> (array/len @entity.ranked) 0) (and (>= (object/get (array/first @entity.ranked) score) (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) threshold)) (= (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) action) fill))) (and (> (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) take 1) 1) (and (> (array/len @entity.ranked) 1) (= chat jev)))) (set @entity.chosen "") (set @entity.pickedFields {}) (set @entity.status choosing) (emit BUILD_PROGRESS { status: choosing tier: (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) name) }) (call-service llm choose { instructions: "Which building block's interaction does what the request asks (sorting into groups, putting in order, estimating, exploring), not just the one about the same subject?" options: (array/map (array/take @entity.ranked (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) take 1)) (fn r { description: (object/get @r description "") value: @r.behavior })) state: (if (= @entity.context "") @entity.request (str/concat @entity.request "\n\n" @entity.context)) } { emit: { failure: BUILD_FAILED, success: CHOSEN } }) RANKED -> choosing when (and (and (> (array/len @entity.ranked) 0) (and (>= (object/get (array/first @entity.ranked) score) (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) threshold)) (= (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) action) fill))) (and (> (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) take 1) 1) (and (> (array/len @entity.ranked) 1) (= chat chat)))) (set @entity.chosen "") (set @entity.pickedFields {}) (set @entity.status choosing) (emit BUILD_PROGRESS { status: choosing tier: (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) name) }) (emit CONVERSE { ephemeral: true instructions: (str/concat "Several building blocks could serve the request. Pick the one whose interaction does what the request asks (sorting into groups, putting in order, estimating, exploring…), not just the one about the same subject. Call the PICK tool once with the block and every requested field, then reply with one sentence." "\nThe building blocks:\n" (str/join (array/map (array/take @entity.ranked (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) take 1)) (fn r (str/concat "- " @r.behavior ": " (object/get @r description "")))) "\n")) messages: [{ content: (if (= @entity.context "") @entity.request (str/concat @entity.request "\n\n" @entity.context)) role: user }] tools: [{ event: "BuilderPipeline.PICK" payload: [{ description: "The building block that fits the request." name: behavior required: true type: string values: (array/map (array/take @entity.ranked (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) take 1)) (fn r @r.behavior)) }, { name: fields properties: [] required: (> (array/len @config.pickFields) 0) type: object }] }] }) BUILD_FAILED -> failed (set @entity.error ?error) (set @entity.status failed) (render-ui main <Typography content={(str/concat "Build failed: " ?error)} variant={caption} />) (emit BUILD_REJECTED { error: ?error errors: [] }) } state choosing { INIT -> choosing (set @entity.status choosing) CHOSEN -> describing when (array/some (array/take @entity.ranked (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) take 1)) (fn r (= @r.behavior ?choice))) (set @entity.chosen ?choice) (set @entity.chosenDescription (object/get (array/find @entity.ranked (fn r (= @r.behavior ?choice))) description "")) (set @entity.status describing) (emit BUILD_PROGRESS { status: describing tier: (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) name) }) (behavior/describe { behavior: ?choice } { emit: { failure: BUILD_FAILED, success: DESCRIBED } }) CHOSEN -> failed when (not (array/some (array/take @entity.ranked (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) take 1)) (fn r (= @r.behavior ?choice)))) (set @entity.error "The decision model picked none of the building blocks offered") (set @entity.status failed) (render-ui main <Typography content={"Build failed: no building block was picked."} variant={caption} />) (emit BUILD_REJECTED { error: "The decision model picked none of the building blocks offered" errors: [] }) BUILD_FAILED -> failed (set @entity.error ?error) (set @entity.status failed) (render-ui main <Typography content={(str/concat "Build failed: " ?error)} variant={caption} />) (emit BUILD_REJECTED { error: ?error errors: [] }) PICK -> choosing (set @entity.chosen (str/default ?behavior "")) (set @entity.pickedFields (if (== ?fields null) {} ?fields)) ASSISTANT_REPLIED -> describing when (array/some (array/take @entity.ranked (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) take 1)) (fn r (= @r.behavior @entity.chosen))) (set @entity.chosenDescription (object/get (array/find @entity.ranked (fn r (= @r.behavior @entity.chosen))) description "")) (set @entity.status describing) (emit BUILD_PROGRESS { status: describing tier: (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) name) }) (behavior/describe { behavior: @entity.chosen } { emit: { failure: BUILD_FAILED, success: DESCRIBED } }) ASSISTANT_REPLIED -> failed when (not (array/some (array/take @entity.ranked (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) take 1)) (fn r (= @r.behavior @entity.chosen)))) (set @entity.error "The model picked none of the building blocks offered") (set @entity.status failed) (render-ui main <Typography content={"Build failed: no building block was picked."} variant={caption} />) (emit BUILD_REJECTED { error: "The model picked none of the building blocks offered" errors: [] }) TOOLS_FAILED -> failed (set @entity.error ?error) (set @entity.status failed) (render-ui main <Typography content={(str/concat "Build failed: " ?error)} variant={caption} />) (emit BUILD_REJECTED { error: ?error errors: [] }) } state describing { INIT -> describing (set @entity.status describing) DESCRIBED -> filling when (> (array/len (object/get ?result orbitals [])) 0) (let ((o (array/first (object/get ?result orbitals [])))) (do (set @entity.target (object/get @o value)) (set @entity.tool [{ name: config properties: (array/map (array/filter (object/get @o knobs []) (fn k (!= (object/get @k tier "") internal))) (fn k (object/pick @k (default description name properties required type values)))) type: object }, { name: traits properties: (array/map (object/get @o traits []) (fn t { name: (object/get @t trait) properties: [{ name: config properties: (array/map (array/filter (object/get @t knobs []) (fn k (!= (object/get @k tier "") internal))) (fn k (object/pick @k (default description name properties required type values)))) type: object }] type: object })) type: object }, { name: fields properties: (array/concat @config.fillFields @config.pickFields) required: (> (+ (array/len @config.fillFields) (array/len @config.pickFields)) 0) type: object }]) (set @entity.status filling) (emit BUILD_PROGRESS { status: filling tier: (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) name) }) (emit CONVERSE { ephemeral: true instructions: (str/concat "You adapt an existing building block to a request. Call the FILL tool once: set only the knobs the request needs (in `config` and `traits` → trait → `config`), write every requested field in `fields`, then reply with one sentence." "\nThe building block: " @entity.chosen " — " @entity.chosenDescription) messages: [{ content: (if (= @entity.context "") @entity.request (str/concat @entity.request "\n\n" @entity.context)) role: user }] tools: [{ event: "BuilderPipeline.FILL" payload: @entity.tool }] }))) DESCRIBED -> failed when (= (array/len (object/get ?result orbitals [])) 0) (set @entity.error "The best match has no orbital to fill") (set @entity.status failed) (render-ui main <Typography content={"Build failed: the best match has no orbital to fill."} variant={caption} />) (emit BUILD_REJECTED { error: "The best match has no orbital to fill" errors: [] }) BUILD_FAILED -> failed (set @entity.error ?error) (set @entity.status failed) (render-ui main <Typography content={(str/concat "Build failed: " ?error)} variant={caption} />) (emit BUILD_REJECTED { error: ?error errors: [] }) } state filling { INIT -> filling (set @entity.status filling) FILL -> filling (set @entity.filledConfig (if (== ?config null) {} ?config)) (set @entity.filledTraits (if (== ?traits null) {} ?traits)) (set @entity.filledFields (object/merge (if (== ?fields null) {} ?fields) @entity.pickedFields)) ASSISTANT_REPLIED -> filling when (and (not (array/every @config.fieldWordLimits (fn l (<= (array/len (str/split (str/trim (object/get @entity.filledFields @l.name "")) " ")) @l.words)))) (< @entity.repairs 2)) (set @entity.repairs (+ @entity.repairs 1)) (set @entity.pickedFields {}) (emit BUILD_PROGRESS { status: repairing tier: (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) name) }) (emit CONVERSE { ephemeral: true instructions: (str/concat "You adapt an existing building block to a request. Call the FILL tool once: set only the knobs the request needs (in `config` and `traits` → trait → `config`), write every requested field in `fields`, then reply with one sentence." "\nThe building block: " @entity.chosen " — " @entity.chosenDescription) messages: [{ content: @entity.request, role: user }, { content: (str/concat "Some fields are too long. The most words each field may hold: " (str/join (array/map @config.fieldWordLimits (fn l (str/concat @l.name " " (str/concat @l.words) " words"))) ", ") ". What you wrote: " (json/stringify @entity.filledFields) ". Call FILL again with the same knobs and shorter fields.") role: user }] tools: [{ event: "BuilderPipeline.FILL" payload: @entity.tool }] }) ASSISTANT_REPLIED -> building when (or (array/every @config.fieldWordLimits (fn l (<= (array/len (str/split (str/trim (object/get @entity.filledFields @l.name "")) " ")) @l.words))) (>= @entity.repairs 2)) (set @entity.status building) (emit BUILD_PROGRESS { status: building tier: (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) name) }) (program/eval (quasiquote { name: (unquote @entity.orbitalName) orbitals: [(unquote (behavior/apply @entity.target { config: @entity.filledConfig, traits: @entity.filledTraits }))] }) { final: true } { emit: { failure: BUILD_FAILED, success: BUILT } }) TOOLS_FAILED -> failed (set @entity.error ?error) (set @entity.status failed) (render-ui main <Typography content={(str/concat "Build failed: " ?error)} variant={caption} />) (emit BUILD_REJECTED { error: ?error errors: [] }) } state building { INIT -> building (set @entity.status building) BUILT -> done (set @entity.behavior (object/get ?result behavior)) (set @entity.status done) (render-ui main <Typography content={(str/concat "Built " (object/get ?result behavior))} variant={caption} />) (emit BUILD_COMPLETE { behavior: (object/get ?result behavior) fields: @entity.filledFields orbitalName: @entity.orbitalName tier: (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) name) value: (object/get ?result value) }) BUILD_FAILED -> filling when (and (= (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) action) fill) (< @entity.repairs 2)) (set @entity.repairs (+ @entity.repairs 1)) (set @entity.status filling) (emit BUILD_PROGRESS { status: repairing tier: (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) name) }) (emit CONVERSE { ephemeral: true instructions: "You adapt an existing building block to a request. Call the FILL tool once: set only the knobs the request needs (in `config` and `traits` → trait → `config`), write every requested field in `fields`, then reply with one sentence." messages: [{ content: @entity.request, role: user }, { content: (str/concat "The result did not validate. The validator's issues: " (json/stringify (if (== ?errors null) [] ?errors)) " (" ?error "). Call FILL again with corrected values.") role: user }] tools: [{ event: "BuilderPipeline.FILL" payload: @entity.tool }] }) BUILD_FAILED -> failed when (or (!= (object/get (array/nth [{ action: mount name: mount scope: (list almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @entity.step) action) fill) (>= @entity.repairs 2)) (set @entity.error ?error) (set @entity.status failed) (render-ui main <Typography content={(str/concat "Build failed: " ?error)} variant={caption} />) (emit BUILD_REJECTED { error: ?error errors: (if (== ?errors null) [] ?errors) }) } state done { INIT -> done (set @entity.status done) RESET -> idle (set @entity.status idle) (set @entity.pick null) (render-ui main <Typography content={"Ready to build."} variant={caption} />) START -> searching (set @entity.request ?request) (set @entity.orbitalName ?orbitalName) (set @entity.context (str/default ?context "")) (set @entity.step 0) (set @entity.repairs 0) (set @entity.status searching) (emit BUILD_PROGRESS { status: searching tier: "" }) (call-service llm embed { texts: [?request] } { emit: { failure: BUILD_FAILED, success: REQUEST_EMBEDDED } }) } state failed { INIT -> failed (set @entity.status failed) RESET -> idle (set @entity.status idle) (set @entity.pick null) (render-ui main <Typography content={"Ready to build."} variant={caption} />) START -> searching (set @entity.request ?request) (set @entity.orbitalName ?orbitalName) (set @entity.context (str/default ?context "")) (set @entity.step 0) (set @entity.repairs 0) (set @entity.status searching) (emit BUILD_PROGRESS { status: searching tier: "" }) (call-service llm embed { texts: [?request] } { emit: { failure: BUILD_FAILED, success: REQUEST_EMBEDDED } }) } emits { BUILD_COMPLETE -> external { orbitalName : string! behavior : string! value : behavior! tier : string! fields : Map string string } @description "A tier served the request: the behavior (its specifier and its value), the ladder step that served it, and the extra fields the fill turn wrote (or that the adopted pool entry carries)." @tier "domain" BUILD_REJECTED -> external { error : string! errors : [BuildIssue] } @description "No tier could serve the request, or the build failed; the validator's issues come back as data." @tier "domain" BUILD_PROGRESS -> external { status : string! tier : string } @description "The build moved on (searching, describing, filling, repairing, building) at a ladder step, for a page that shows the build as it streams." @tier "domain" POOL_SEARCH -> external { vector : [number]! take : number } @description "A pool step asks the pool for its best entries for the request's vector; std-agent-pool's SEARCH answers with POOL_FOUND." @tier "domain" CONVERSE -> external { messages : [AgentChatMessage]! instructions : string tools : [AgentToolInput] ephemeral : boolean } @tier "internal" STEP @tier "internal" RANKED @tier "internal" REQUEST_EMBEDDED { embeddings : [[number]]! } @tier "internal" CATALOG_LISTED { result : [CatalogHit]! } @tier "internal" DESCRIBED { result : { behavior : string!, knobs : [KnobField]!, orbitals : [{ value : orbital!, knobs : [KnobField]!, traits : [{ trait : string!, knobs : [KnobField]! }]! }]! }! } @tier "internal" CHOSEN { choice : string! confidence : number! } @tier "internal" BUILT { result : { behavior : string!, value : behavior! }! } @tier "internal" BUILD_FAILED { error : string! errors : [BuildIssue] } @tier "internal" } listens { BuilderTools.ASSISTANT_REPLIED -> ASSISTANT_REPLIED BuilderTools.ASSISTANT_REPLY_FAILED -> TOOLS_FAILED START -> external { request : string! orbitalName : string! context : string } @description "Build a behavior for the request; orbitalName names the program a mount or fill writes; context is any extra the fill turn should know." FILL -> external { config : Map string SExpr traits : Map string FilledTrait fields : Map string string } @description "The model's knob settings for the building block and the extra fields it was asked to write." PICK -> external { behavior : string! fields : Map string string } @description "The model's pick among the building blocks a fill step offered." ASSISTANT_REPLIED { reply : string } TOOLS_FAILED { error : string! } POOL_FOUND { hits : [{ id : string!, behavior : string!, value : behavior!, name : string, kind : string, topic : string, fields : Map string string, description : string, score : number! }]! } @description "The pool's answer to POOL_SEARCH: its best entries, best first." RESET } config { fieldWordLimits : [FieldWordLimit] = [] @label "Most words per fill field" @description "A fill field written longer than its limit goes back to the model as a repair turn; after the last repair turn the build goes ahead with what was written." @tier "policy" fillEvent : EventAddress = "BuilderPipeline.FILL" @label "Fill tool event" @description "The address the model's FILL tool fires; a consumer that renames this trait sets it to its own name." @tier "internal" fillFields : [AgentToolField] = [] @label "Extra fields the fill turn writes" @description "Fields the model fills alongside the knobs (e.g. a one-line hint); they come back in BUILD_COMPLETE's `fields`." @tier "domain" fillInstructions : string = "You adapt an existing building block to a request. Call the FILL tool once: set only the knobs the request needs (in `config` and `traits` → trait → `config`), write every requested field in `fields`, then reply with one sentence." @label "How the fill turn is briefed" @tier "domain" ladder : [BuilderStep] = [{ action: mount name: mount scope: (almadar-std/ui/core/molecules) source: catalog take: 1 threshold: 0 }] @label "Caching tiers, cheapest first" @description "Each step ranks its source (a registry catalog under `scope`, or the pool) against the request and, when the best match reaches `threshold`, runs `action` on it: `mount` (a page around its first trait), `adopt` (serve it as it is, no model call) or `fill` (one model turn setting its knobs). A step whose best match falls short hands over to the next one; when no step serves, the build is rejected." @synonyms "tiers, cache levels, retrieval ladder" @tier "domain" maxRepairs : number = 2 @label "Repair turns" @description "How many times validator issues go back to the model before the build fails." @tier "policy" pickDecider : "chat" | "jev" = chat @label "Who picks the building block" @description "`chat`: a model turn picks it (and writes `pickFields`). `jev`: the decision model picks it in one typed choice (`llm choose`), and the fill turn writes `pickFields`." @tier "policy" pickEvent : EventAddress = "BuilderPipeline.PICK" @label "Pick tool event" @description "The address the model's PICK tool fires; a consumer that renames this trait sets it to its own name." @tier "internal" pickFields : [AgentToolField] = [] @label "Fields the pick turn writes" @description "Fields the model writes while it picks the building block, before it sees the block's knobs (e.g. a how-to-play hint that must not lean on the content). They win over the fill turn's; with no pick turn the fill turn writes them." @tier "domain" pickInstructions : string = "Several building blocks could serve the request. Pick the one whose interaction does what the request asks (sorting into groups, putting in order, estimating, exploring…), not just the one about the same subject. Call the PICK tool once with the block and every requested field, then reply with one sentence." @label "How the pick turn is briefed" @description "Used when a fill step takes more than one candidate: the model picks the building block before filling it." @tier "domain" pickQuestion : string = "Which building block's interaction does what the request asks (sorting into groups, putting in order, estimating, exploring), not just the one about the same subject?" @label "The decision model's question" @tier "domain" statusSlot : slot = main @label "Status slot" @description "Where the builder shows its one-line status; a page running it in the background sends it to `system`." @tier "presentation" } }
INIT
START
FILL
PICK
CONVERSE
ASSISTANT_REPLIED
TOOLS_FAILED
INIT
REQUEST_EMBEDDED
REQUEST_EMBEDDED
STEP
STEP
STEP
CATALOG_LISTED
POOL_FOUND
RANKED
RANKED
RANKED
RANKED
RANKED
RANKED
BUILD_FAILED
INIT
CHOSEN
CHOSEN
BUILD_FAILED
PICK
ASSISTANT_REPLIED
ASSISTANT_REPLIED
TOOLS_FAILED
INIT
DESCRIBED
DESCRIBED
BUILD_FAILED
INIT
FILL
ASSISTANT_REPLIED
ASSISTANT_REPLIED
TOOLS_FAILED
INIT
BUILT
BUILD_FAILED
BUILD_FAILED
INIT
RESET
START
INIT
RESET
START
nowidle
searching
choosing
describing
filling
building
done
failed
09

Compilation targets

The compiler produces each of the following from the same .lolo source.

TypeScript + React

Python

Rust

Swift for iOS

Kotlin for Android

Getting started

Install Orb with npx, or give the prompt above to an agent.

Orb

A programming language of composable state machines.

© 2026 Almadar. Ljubljana, Slovenia.
Not reported here