Skip to content

Scene AI: a JS app in a flow exports run(), one feeding a field get() - #563

Merged
mariusandra merged 2 commits into
mainfrom
ai-flow-run-vs-get
Oct 17, 2026
Merged

mariusandra merged 2 commits into
mainfrom
ai-flow-run-vs-get

Conversation

@mariusandra

Copy link
Copy Markdown
Collaborator

The bug

The scene AI, asked to make a frame button toggle the chess puzzle's solution, wired button → toggleSolution → dispatch render, where toggleSolution's app.ts exported only get(). In a flow, the frame calls run(). So a press did nothing, for three turns, and no error showed anywhere.

Three things taught the model to write get() or let it slide:

  • The linter demanded get(). lintJsAppSource told every non-render JS app "must export function get(app, context) … nothing else is called", including logic apps. A correct run() app came back as an error. The repo's own logic/jsLogic template failed it too, and so did chess-puzzle-of-the-day@11, the version that does export run.
  • docs/js-apps-and-code-nodes.md (which the AI can read_doc) had one row: "data / logic → export function get".
  • The runtime said nothing. __frameosInvoke returns undefined when an export is missing. Catalog Nim apps in a flow already raise "cannot be run; use get()".

The fix

  • Guide (docs/scene-guide.md, regenerated for both AIs and both MCPs): "Edges" now says every event node starts a flow, not just render. "Exports" says where the node sits decides the call: a node feeding a field calls get() (data), a node in a flow calls run() (logic), and the other export is never called. It also shows the button pattern: button → logic app with run() → dispatch render. The checklist says the same.
  • Linter (scene-lint.ts):
    • A logic app must export run, a data app get. An app with no category anywhere must export one of the two, and its node's place decides which (it used to default to "data" and demand get).
    • The category comes from config.json first, as on the frame. The chess app's apps entry had no top-level category.
    • New node-level errors: a scene app in a flow without run(), and a scene app feeding a field without get().
    • Exports are read from export function, export const and export { x as run }. A default export is left alone.
    • Also fixed: the lint message that still said JS Date is "UTC only".
  • Runtime (app_runtime.nim prelude): when a node calls an export the app does not have, the frame logs once per interpreter: "This app has no run(), so it does nothing in a flow…", and the same for get(). It only logs and changes no behaviour. A scene that "works" today with an inert app in its render flow keeps working.
  • Docs: the js-apps-and-code-nodes.md table now has separate data and logic rows.
  • Eval: new case modify-weather-button-unit ("when someone presses a button, switch between Celsius and Fahrenheit and redraw") with a new flow_sets_state check. The check walks the button event's flow and fails on any JS app there without run().

Measured

  • Old vs new lint over all 357 local store versions plus the bundled examples: no new errors in any public scene or example. The only new errors are the real bug: chess-puzzle-of-the-day @3, @4, @9, @10 and habit-tracker @2, @3 (a get()-only habitTickProcessor in both its button flow and its cloud flow). The one error that goes away is the false one on chess-puzzle-of-the-day@11.
  • AI evals (gpt-5.6-terra, effort low) vs the 2026-10-17 10:01 run:
    • 22/23 passed (before: 20/22), judge mean 4.73 (before: 4.50), lint clean 100%, render ok 100%.
    • The new modify-weather-button-unit passed twice. The model wrote button → a logic app exporting run() that calls frameos.setState('temperatureUnit', …) → dispatch render, with 0 bounces.
    • create-split-dashboard failed in both runs. In the first, the model gave up after 4 payload-validator bounces ("Scene 0 must include nodes"), which is not this lint. The rerun failed only on the one check the baseline also failed: it drew its own weather instead of using the catalog app.

Parity: the backend AI reads the same guide. The backend has no scene linter, so the lint half is cloud-only. The runtime log is the same on Linux, the ESP32 and the wasm preview, from 2026.10.16.

Tests

  • scene-lint.test.ts: the chess scene as delivered (two errors), run, export { toggle as run }, export default, a run()-only app feeding a field, and the jsLogic template in a button flow. Both new tests fail on the old linter.
  • evals/lib/checks.test.ts: flow_sets_state.
  • tools.test.ts: the Scene AI: a scene app that no node runs bounces back to the model #559 fixture ("delivers the app together with its node") was itself the bug: a get()-only toggle wired into a button flow. It now exports run().
  • test_js_app_runtime.nim: a get()-only app called as run() logs once, a run()-only app called as get() logs once. The other 21 Nim test files that run JS apps pass.
  • pnpm verify from cloud/: 28/28 tasks, auth-web 2380/2380. auth-web test:integration: 520/520. The frame-hub and ledger suites were not run: nothing they import changed.
  • generate_scene_guide.py --check is clean (the backend suite runs it).

🤖 Generated with Claude Code

Asked to toggle the chess puzzle's solution from a frame button, the scene
AI wired button -> toggleSolution -> dispatch render with an app.ts that
exported only get(). In a flow the frame calls run(), so the press did
nothing, three turns running, with no error anywhere.

- scene-lint: the source contract demanded get() from every non-render
  app, logic apps included, so a correct run() app (and the repo's own
  logic/jsLogic template) bounced. Now logic needs run, data needs get, an
  uncategorised app either; the category is config.json's first, as on the
  frame. New node errors: a scene app in a flow without run(), and one
  feeding a field without get().
- scene guide: every event node starts a flow, not only render; where a
  node sits decides which export runs; the button pattern spelled out.
  docs/js-apps-and-code-nodes.md had "data / logic -> get" in one row.
- runtime: an app without the export its node calls logs that once
  instead of silently returning undefined (behaviour unchanged).
- evals: modify-weather-button-unit with a flow_sets_state check.

Over 357 local store versions and the examples, the lint adds errors only
to the scenes with this bug (chess-puzzle-of-the-day, habit-tracker) and
drops a false one. Evals: 22/23 (was 20/22), judge 4.73 (was 4.50).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

ESP32 firmware size

Built from 8cf510f by this run; compared with the latest release v2026.10.15.

Image This PR v2026.10.15 Δ
esp32-s3 app (OTA image) 3,145,904
87.3% of 3520K slot, 448 KB free
3,138,272 +7,632 (+0.2%)
esp32-s3 merged flash image 3,211,440 3,203,808 +7,632 (+0.2%)
esp32-s3-32mb app (OTA image) 3,145,904
76.2% of 4032K slot, 960 KB free
3,138,272 +7,632 (+0.2%)
esp32-s3-32mb merged flash image 3,276,976 3,269,344 +7,632 (+0.2%)

Breakdown by subsystem — esp32-s3

Subsystem This PR v2026.10.15 Δ
FrameOS core (Nim) 480,679 477,042 +3,637 (+0.8%)
QuickJS 360,369 360,373 -4 (-0.0%)
pixie 304,370 304,354 +16 (+0.0%)
Wi-Fi stack 295,304 295,304 ±0
Nim stdlib 251,547 251,436 +111 (+0.0%)
FrameOS apps (Nim) 190,416 190,356 +60 (+0.0%)
ESP-IDF misc 181,367 181,564 -197 (-0.1%)
Embedded font 146,362 146,362 ±0
String pool (attributed to efuse) 136,170 136,134 +36 (+0.0%)
fos_* firmware shell (C) 136,121 132,233 +3,888 (+2.9%)
mbedTLS + certificates 132,439 132,439 ±0
lwIP / HTTP / WebSocket 126,816 126,800 +16 (+0.0%)
libc / libm / newlib 116,263 116,263 ±0
Storage (SPIFFS / FatFS / SD / NVS) 94,076 94,080 -4 (-0.0%)
Nim packages (chrono, zippy, chroma, qrgen, ...) 71,857 71,849 +8 (+0.0%)
Display drivers (C) 64,962 64,946 +16 (+0.0%)
Crypto (monocypher) 35,141 35,141 ±0
Total mapped flash 3,124,259 3,116,676 +7,583 (+0.2%)
Inside each subsystem

FrameOS core (Nim) — 480,679

Part This PR v2026.10.15 Δ
frameos/js_runtime 117,577 115,444 +2,133 (+1.8%)
frameos/utils 112,365 112,401 -36 (-0.0%)
frameos/interpreter.nim 99,972 100,264 -292 (-0.3%)
embedded_main.nim 19,252 19,252 ±0
embedded_runtime.nim 17,830 17,834 -4 (-0.0%)
lib/tz.nim 16,722 16,722 ±0
frameos_nim_glue.c.obj 10,793 10,635 +158 (+1.5%)
frameos/planner.nim 9,689 9,681 +8 (+0.1%)
frameos/event_loop.nim 8,412 8,412 ±0
frameos/types.nim 7,909 7,909 ±0
frameos/values.nim 7,699 7,699 ±0
frameos/single_scene_host.nim 6,687 6,712 -25 (-0.4%)
frameos/apps.nim 6,585 6,585 ±0
frameos/spool.nim 5,787 5,787 ±0
frameos/input_state.nim 5,079 3,766 +1,313 (+34.9%)
embedded_scene.nim 4,945 4,945 ±0
frameos/events_gen.nim 3,926 3,948 -22 (-0.6%)
frameos/app_config.nim 2,995 2,935 +60 (+2.0%)
fos_netguard.c.obj 2,786 2,179 +607 (+27.9%)
frameos/reboot_reason.nim 2,648 2,648 ±0
frameos/node_config.nim 2,618 2,618 ±0
frameos/app_capabilities.nim 2,489 2,489 ±0
frameos/events.nim 2,410 2,410 ±0
frameos/refresh_interval.nim 1,635 1,639 -4 (-0.2%)
frameos/runtime_diagnostics.nim 767 767 ±0
frameos/event_log.nim 427 431 -4 (-0.9%)
fos_version.c.obj 328 328 ±0
frameos/cloud — 255 -255 (-100.0%)
frameos/channels.nim 152 152 ±0
frameos/ids.nim 137 137 ±0
frameos/hal 44 44 ±0
frameos/retired_apps.nim 14 14 ±0

QuickJS — 360,369

Part This PR v2026.10.15 Δ
quickjs.c.obj 287,842 287,846 -4 (-0.0%)
libunicode.c.obj 50,178 50,178 ±0
libregexp.c.obj 13,999 13,999 ±0
dtoa.c.obj 5,685 5,685 ±0
cutils.c.obj 2,141 2,141 ±0
fos_qjs_glue.c.obj 449 449 ±0
fos_quickjs_tz.c.obj 75 75 ±0

pixie — 304,370

Part This PR v2026.10.15 Δ
pixie/fontformats/opentype.nim 55,460 55,460 ±0
pixie/fileformats/webp.nim 37,493 37,493 ±0
pixie/fileformats/svg.nim 36,975 36,983 -8 (-0.0%)
pixie/paths.nim 32,895 32,875 +20 (+0.1%)
pixie/fileformats/jpeg.nim 29,424 29,436 -12 (-0.0%)
pixie/fileformats/png.nim 22,097 22,101 -4 (-0.0%)
pixie/images.nim 15,771 15,779 -8 (-0.1%)
pixie/fonts.nim 10,995 10,995 ±0
pixie/paints.nim 9,869 9,869 ±0
pixie/fileformats/bmp.nim 8,278 8,258 +20 (+0.2%)
pixie/common.nim 7,405 7,413 -8 (-0.1%)
pixie/blends.nim 6,516 6,516 ±0
pixie/fileformats/gif.nim 5,957 5,965 -8 (-0.1%)
pixie/inflatestream.nim 5,233 5,233 ±0
pixie.nim 5,224 5,224 ±0
pixie/fileformats/webp_vp8_tables.nim 3,881 3,881 ±0
pixie/fileformats/ppm.nim 3,717 3,713 +4 (+0.1%)
pixie/contexts.nim 3,054 3,054 ±0
pixie/fileformats/qoi.nim 2,722 2,702 +20 (+0.7%)
pixie/internal.nim 754 754 ±0
pixie/rgb565.nim 385 385 ±0
pixie/fontformats/svgfont.nim 215 215 ±0
pixie/decodebudget.nim 50 50 ±0

Wi-Fi stack — 295,304

Part This PR v2026.10.15 Δ
libnet80211.a 136,168 136,168 ±0
libpp.a 62,154 62,154 ±0
libwpa_supplicant.a 54,904 54,904 ±0
libphy.a 34,176 34,176 ±0
libesp_wifi.a 4,780 4,780 ±0
libesp_phy.a 2,541 2,541 ±0
libesp_coex.a 291 291 ±0
libcore.a 287 287 ±0
libespnow.a 3 3 ±0

Nim stdlib — 251,547

Part This PR v2026.10.15 Δ
pure/collections/tables.nim 72,312 72,312 ±0
system.nim 48,501 48,457 +44 (+0.1%)
pure/unicode.nim 17,405 17,405 ±0
pure/times.nim 16,884 16,888 -4 (-0.0%)
pure/json.nim 13,722 13,722 ±0
std/private/dragonbox.nim 10,351 10,351 ±0
pure/strutils.nim 8,047 8,047 ±0
pure/parsexml.nim 6,003 6,011 -8 (-0.1%)
pure/algorithm.nim 5,372 5,372 ±0
pure/base64.nim 5,290 5,290 ±0
pure/hashes.nim 4,181 4,181 ±0
pure/xmlparser.nim 3,555 3,555 ±0
pure/parsejson.nim 3,553 3,553 ±0
std/formatfloat.nim 3,504 3,504 ±0
pure/uri.nim 3,225 3,225 ±0
pure/streams.nim 2,820 2,820 ±0
pure/strformat.nim 2,546 2,546 ±0
std/syncio.nim 2,339 2,355 -16 (-0.7%)
pure/collections/sets.nim 2,075 2,075 ±0
pure/xmltree.nim 2,047 2,047 ±0
pure/lexbase.nim 1,801 1,801 ±0
pure/parseutils.nim 1,750 1,750 ±0
system/exceptions.nim 1,598 1,598 ±0
pure/strtabs.nim 1,572 1,572 ±0
pure/pathnorm.nim 1,336 1,336 ±0
pure/options.nim 1,016 1,016 ±0
std/private/ospaths2.nim 994 994 ±0
pure/collections/lists.nim 979 979 ±0
pure/math.nim 841 841 ±0
pure/collections/deques.nim 822 822 ±0
pure/random.nim 696 696 ±0
std/private/digitsutils.nim 651 651 ±0
std/oserrors.nim 633 633 ±0
std/private/osdirs.nim 572 572 ±0
system/dollars.nim 529 529 ±0
std/monotimes.nim 501 406 +95 (+23.4%)
std/private/oscommon.nim 329 329 ±0
std/envvars.nim 250 250 ±0
std/private/decode_helpers.nim 240 240 ±0
std/private/ossymlinks.nim 187 187 ±0
pure/bitops.nim 162 162 ±0
pure/os.nim 99 99 ±0
std/private/osfiles.nim 96 96 ±0
std/assertions.nim 87 87 ±0
core/macros.nim 65 65 ±0
system/ctypes.nim 9 9 ±0

FrameOS apps (Nim) — 190,416

Part This PR v2026.10.15 Δ
apps/data/icalJson 50,745 50,733 +12 (+0.0%)
apps/render/calendar 30,886 30,874 +12 (+0.0%)
apps/data/localImage 10,432 10,432 ±0
apps/render/split 9,732 9,772 -40 (-0.4%)
apps/data/eventsToAgenda 9,068 9,068 ±0
apps/render/zoomPan 8,668 8,648 +20 (+0.2%)
apps/apps.nim 7,251 7,247 +4 (+0.1%)
apps/render/text 5,483 5,455 +28 (+0.5%)
apps/data/xmlToJson 5,428 5,428 ±0
apps/render/svg 5,208 5,192 +16 (+0.3%)
apps/render/image 4,708 4,708 ±0
apps/data/rotateImage 3,465 3,465 ±0
apps/logic/setAsState 3,453 3,453 ±0
apps/data/downloadImage 3,321 3,325 -4 (-0.1%)
apps/render/gradient 3,213 3,229 -16 (-0.5%)
apps/data/qr 3,118 3,122 -4 (-0.1%)
apps/data/downloadUrl 3,053 3,053 ±0
apps/render/color 2,844 2,824 +20 (+0.7%)
apps/data/newImage 2,668 2,668 ±0
apps/data/resizeImage 2,558 2,558 ±0
apps/render/opacity 2,320 2,296 +24 (+1.0%)
apps/data/log 2,299 2,299 ±0
apps/data/prettyJson 2,225 2,225 ±0
apps/data/clock 1,871 1,875 -4 (-0.2%)
apps/data/parseJson 1,848 1,856 -8 (-0.4%)
apps/logic/nextSleepDuration 1,663 1,663 ±0
apps/logic/ifElse 1,494 1,494 ±0
apps/logic/breakIfRendering 1,394 1,394 ±0

ESP-IDF misc — 181,367

Part This PR v2026.10.15 Δ
libesp_hw_support.a 37,636 37,632 +4 (+0.0%)
libhal.a 21,865 21,865 ±0
libfreertos.a 17,240 17,240 ±0
libesp_system.a 13,736 13,780 -44 (-0.3%)
libesp_driver_uart.a 11,627 11,627 ±0
libheap.a 8,660 8,660 ±0
libesp_driver_i2c.a 8,062 8,062 ±0
libesp_driver_spi.a 7,756 7,756 ±0
libconsole.a 5,733 5,733 ±0
libjson.a 4,940 4,940 ±0
libesp_driver_gpio.a 3,878 3,878 ±0
libbootloader_support.a 3,813 3,813 ±0
libxtensa.a 3,691 3,691 ±0
libesp_driver_usb_serial_jtag.a 3,408 3,408 ±0
libesp_ringbuf.a 3,322 3,322 ±0
libesp_event.a 3,253 3,253 ±0
libesp_driver_ledc.a 3,054 3,054 ±0
libesp_mm.a 2,451 2,451 ±0
libapp_update.a 2,414 2,414 ±0
libesp_timer.a 2,337 2,337 ±0
libesp_psram.a 2,172 2,329 -157 (-6.7%)
libsoc.a 2,316 2,316 ±0
libesp_adc.a 2,285 2,285 ±0
libpthread.a 1,397 1,397 ±0
liblog.a 1,375 1,375 ±0
libesp_security.a 1,050 1,050 ±0
libesp_rom.a 902 902 ±0
libesp_app_format.a 507 507 ±0
libxt_hal.a 437 437 ±0
libesp_common.a 26 26 ±0
libesp_pm.a 24 24 ±0

Embedded font — 146,362

Part This PR v2026.10.15 Δ
assets/fonts.nim 146,362 146,362 ±0

String pool (attributed to efuse) — 136,170

Part This PR v2026.10.15 Δ
esp_efuse_utility.c.obj 135,124 135,088 +36 (+0.0%)
esp_efuse_rtc_calib.c.obj 566 566 ±0
esp_efuse_table.c.obj 268 268 ±0
esp_efuse_api.c.obj 151 151 ±0
esp_efuse_startup.c.obj 61 61 ±0

fos_ firmware shell (C)* — 136,121

Part This PR v2026.10.15 Δ
fos_http.c.obj 22,185 22,185 ±0
fos_cloud.c.obj 19,622 19,258 +364 (+1.9%)
fos_console.c.obj 13,950 13,950 ±0
fos_client.c.obj 12,933 12,266 +667 (+5.4%)
fos_settings.c.obj 7,618 7,618 ±0
fos_scenes.c.obj 7,515 7,578 -63 (-0.8%)
fos_ota.c.obj 5,467 5,467 ±0
fos_cloud_contract.c.obj 4,768 4,744 +24 (+0.5%)
fos_config.c.obj 4,619 4,619 ±0
fos_wifi.c.obj 3,189 3,189 ±0
fos_assets.c.obj 3,124 3,124 ±0
fos_sd_probe.c.obj 2,753 2,753 ±0
fos_buttons.c.obj 2,737 2,493 +244 (+9.8%)
fos_schedule.c.obj 2,614 2,602 +12 (+0.5%)
fos_assets_sd.c.obj 2,484 2,484 ±0
fos_events.c.obj 2,332 2,320 +12 (+0.5%)
fos_panel_draw.c.obj 2,229 — +2,229
fos_status_screen.c.obj 893 2,049 -1,156 (-56.4%)
main.c.obj 1,703 1,699 +4 (+0.2%)
fos_config_parse.c.obj 1,467 1,467 ±0
fos_url_guard.c.obj 1,397 1,397 ±0
fos_tz.c.obj 1,294 1,294 ±0
fos_buzzer.c.obj 1,162 901 +261 (+29.0%)
fos_battery.c.obj 1,140 1,140 ±0
fos_minisig.c.obj 1,140 1,140 ±0
fos_backend_http.c.obj 1,072 1,072 ±0
fos_commands.c.obj 940 940 ±0
fos_lan_access.c.obj 841 — +841
fos_scene_state.c.obj 650 650 ±0
fos_framebuffer.c.obj 483 483 ±0
fos_button_timing.c.obj 434 — +434
fos_board.c.obj 334 334 ±0
fos_assets_path.c.obj 259 259 ±0
fos_power.c.obj 241 241 ±0
fos_battery_filter.c.obj 214 214 ±0
fos_wake.c.obj 199 184 +15 (+8.2%)
fos_json_guard.c.obj 119 119 ±0

mbedTLS + certificates — 132,439

Part This PR v2026.10.15 Δ
libmbedcrypto.a 71,295 71,291 +4 (+0.0%)
libmbedtls.a 45,799 45,799 ±0
libmbedx509.a 7,088 7,092 -4 (-0.1%)
libesp-tls.a 6,705 6,705 ±0
libesp_https_server.a 1,552 1,552 ±0

lwIP / HTTP / WebSocket — 126,816

Part This PR v2026.10.15 Δ
liblwip.a 78,461 78,445 +16 (+0.0%)
libhttp_parser.a 10,350 10,350 ±0
libesp_http_server.a 10,020 10,020 ±0
libtcp_transport.a 8,245 8,245 ±0
libespressif__esp_websocket_client.a 6,822 6,822 ±0
libesp_http_client.a 6,666 6,666 ±0
libesp_netif.a 6,252 6,252 ±0

libc / libm / newlib — 116,263

Part This PR v2026.10.15 Δ
libc.a 76,471 76,471 ±0
libm.a 31,563 31,563 ±0
libnewlib.a 6,609 6,609 ±0
libstdc++.a 1,476 1,476 ±0
libgcc.a 98 98 ±0
libcxx.a 46 46 ±0

Storage (SPIFFS / FatFS / SD / NVS) — 94,076

Part This PR v2026.10.15 Δ
libspiffs.a 20,380 20,380 ±0
libfatfs.a 20,133 20,133 ±0
libspi_flash.a 14,168 14,168 ±0
libnvs_flash.a 13,681 13,685 -4 (-0.0%)
libsdmmc.a 13,013 13,013 ±0
libvfs.a 6,196 6,196 ±0
libesp_driver_sdspi.a 3,866 3,866 ±0
libesp_partition.a 1,956 1,956 ±0
libesp_vfs_console.a 678 678 ±0
libnvs_sec_provider.a 5 5 ±0

Nim packages (chrono, zippy, chroma, qrgen, ...) — 71,857

Part This PR v2026.10.15 Δ
QRgen 3.1.0 22,056 22,060 -4 (-0.0%)
chrono 0.3.1 15,598 15,586 +12 (+0.1%)
zippy 0.10.19 15,200 15,200 ±0
chroma 1.0.0 14,714 14,714 ±0
checksums 0.2.1 3,371 3,371 ±0
flatty 0.3.4 533 533 ±0
jsony 1.1.5 272 272 ±0
bumpy 1.1.3 113 113 ±0

Display drivers (C) — 64,962

Part This PR v2026.10.15 Δ
(everything else) 21,278 21,282 -4 (-0.0%)
frameos_panel_table.c.obj 6,685 6,685 ±0
EPD_13in3e.c.obj 1,796 1,796 ±0
EPD_3in7.c.obj 1,564 1,564 ±0
EPD_5in79.c.obj 1,481 1,481 ±0
DEV_Debug.c.obj 1,313 1,317 -4 (-0.3%)
EPD_2in7.c.obj 1,292 1,292 ±0
EPD_4in2.c.obj 1,262 1,262 ±0
EPD_7in3e.c.obj 1,208 1,208 ±0
EPD_4in2_V2.c.obj 1,184 1,184 ±0
DEV_Config_esp.c.obj 1,180 1,180 ±0
EPD_4in26.c.obj 1,123 1,123 ±0
29 smaller rows 23,596 23,572 +24 (+0.1%)

Crypto (monocypher) — 35,141

Part This PR v2026.10.15 Δ
monocypher.c.obj 31,916 31,916 ±0
monocypher-ed25519.c.obj 3,225 3,225 ±0
Biggest movers (per object)
Object Δ This PR Baseline
frameos/input_state.nim +5,079 5,079 —
pkgs/QRgen-3.1.0/QRgen/renderer.nim -3,780 — 3,780
frameos/js_runtime/app_runtime.nim +2,073 74,708 72,635
fos_client.c.obj +667 12,933 12,266
fos_cloud.c.obj +364 19,622 19,258
frameos/interpreter.nim -292 99,972 100,264
frameos_nim_glue.c.obj +158 10,793 10,635
fos_scenes.c.obj -63 7,515 7,578
frameos/js_runtime/runtime.nim +52 31,738 31,686
nim/lib/system.nim +44 48,501 48,457
esp_efuse_utility.c.obj +36 135,124 135,088
apps/render/split/app_loader.nim -36 4,666 4,702
frameos/single_scene_host.nim -25 6,687 6,712
fos_cloud_contract.c.obj +24 4,768 4,744
frameos/events_gen.nim -22 3,926 3,948
Largest 30 objects
Object Subsystem This PR v2026.10.15 Δ
quickjs.c.obj QuickJS 287,842 287,846 -4 (-0.0%)
assets/fonts.nim Embedded font 146,362 146,362 ±0
esp_efuse_utility.c.obj String pool (attributed to efuse) 135,124 135,088 +36 (+0.0%)
frameos/interpreter.nim FrameOS core (Nim) 99,972 100,264 -292 (-0.3%)
frameos/js_runtime/app_runtime.nim FrameOS core (Nim) 74,708 72,635 +2,073 (+2.9%)
nim/lib/pure/collections/tables.nim Nim stdlib 72,312 72,312 ±0
pkgs/pixie-6.1.0/pixie/fontformats/opentype.nim pixie 55,460 55,460 ±0
libunicode.c.obj QuickJS 50,178 50,178 ±0
nim/lib/system.nim Nim stdlib 48,501 48,457 +44 (+0.1%)
apps/data/icalJson/ical.nim FrameOS apps (Nim) 45,028 45,016 +12 (+0.0%)
pkgs/pixie-6.1.0/pixie/fileformats/webp.nim pixie 37,493 37,493 ±0
pkgs/pixie-6.1.0/pixie/fileformats/svg.nim pixie 36,975 36,983 -8 (-0.0%)
frameos/utils/image.nim FrameOS core (Nim) 35,942 35,942 ±0
pkgs/pixie-6.1.0/pixie/paths.nim pixie 32,895 32,875 +20 (+0.1%)
monocypher.c.obj Crypto (monocypher) 31,916 31,916 ±0
frameos/js_runtime/runtime.nim FrameOS core (Nim) 31,738 31,686 +52 (+0.2%)
pkgs/pixie-6.1.0/pixie/fileformats/jpeg.nim pixie 29,424 29,436 -12 (-0.0%)
apps/render/calendar/app.nim FrameOS apps (Nim) 23,817 23,817 ±0
fos_http.c.obj fos_* firmware shell (C) 22,185 22,185 ±0
pkgs/pixie-6.1.0/pixie/fileformats/png.nim pixie 22,097 22,101 -4 (-0.0%)
fos_cloud.c.obj fos_* firmware shell (C) 19,622 19,258 +364 (+1.9%)
embedded_main.nim FrameOS core (Nim) 19,252 19,252 ±0
frameos/utils/status_screen.nim FrameOS core (Nim) 17,939 17,943 -4 (-0.0%)
x509_crt_bundle.S.obj mbedTLS + certificates 17,928 17,928 ±0
embedded_runtime.nim FrameOS core (Nim) 17,830 17,834 -4 (-0.0%)
nim/lib/pure/unicode.nim Nim stdlib 17,405 17,405 ±0
frameos/utils/asset_colors.nim FrameOS core (Nim) 17,333 17,333 ±0
nim/lib/pure/times.nim Nim stdlib 16,884 16,888 -4 (-0.0%)
lib/tz.nim FrameOS core (Nim) 16,722 16,722 ±0
pkgs/pixie-6.1.0/pixie/images.nim pixie 15,771 15,779 -8 (-0.1%)

Flash = .text + .rodata from the linker map via esp_idf_size; "Inside each subsystem" splits every bucket one level down (the Nim core by directory, apps by app, packages by package, ESP-IDF by archive) over all objects, not just the largest. "String pool (attributed to efuse)" is the linker's merged string-literal pool for the whole image, not efuse code — see docs/esp32-image-size.md.

# Conflicts:
#	backend/app/utils/scene_guide_gen.py
#	cloud/apps/auth-web/src/lib/ai/scene-guide.gen.ts
@mariusandra
mariusandra merged commit b61b1e8 into main Oct 17, 2026
20 checks passed
@mariusandra
mariusandra deleted the ai-flow-run-vs-get branch October 17, 2026 23:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant