Repository navigation
L0: l0_ai_text kit stamp and the AI-written mark (for Octoscript #53) - #68
Merged
Merged
Conversation
Octoscript #53 lets L0 cards show model-written text and lowers it as `l0_ai_text(node)`. Add the kit function (stamps `ai: 1`), read `ai` in octoscript-node/octoscript-render, and draw the mark: a sparkle in the icon face plus an `AI` eyebrow above the words, in their own ink a step quieter, placed beside the first text so it stays on the same fill (bubble, band). The rewrite lives in octoscript_node::ai so every backend draws the same mark; octoscript-makepad runs it before emit. Model text stays a plain Label literal: no markup, no autolinking. ` l0_ai: true` from makepad::lower needs no change: makepad's Script apply reads declared fields only, so it is ignored like `l0_event:`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OctoScript#53, the L0 side of model-written text and the in-card chat, is on main as 5991dfae: the runtime pin (runtime.json) and the octoscript-ui-l0 git rev move to it, so this kit stamp and the Octoscript lowerings that call it ship together. Checked: cargo test -p octoscript-makepad -p octoscript-node, with the l0_ai_text tests, against Octoscript at 5991dfae. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ymote
added a commit
to OctoSense-org/OctoSense
that referenced
this pull request
Oct 2, 2026
…0c (L0 AI text and chat merged) The two changes this pull request builds against are on their mains: OctoSense-org/OctoScript#53 (5991dfae, model-written text in text slots, strict actions, in-card chat) and OctoSense-org/OctoScript-Makepad#68 (8f103d0c, the l0_ai_text kit stamp and the AI-written mark; its runtime.json pins Octoscript 5991dfae and Makepad e29a0eaa, unchanged). native-runtime.lock.json (here and AppCard's) and the root manifest's Octoscript and Octoscript-Makepad revs move to them; the crates resolve from .sources through [patch], so Cargo.lock does not change. Checked: python3 tools/setup.py --update, then --check --cargo; python3 tools/native_apps.py --check; cargo check -p octosense; cargo test -p octosense-shell --features app-hub --lib (715 passed). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
OctoSense-org/OctoScript#53 lets L0 cards show text the model wrote (a digest summary, a draft, the agent's side of an in-card chat), marked AI-written. Its three lowerings emit the mark, but the kit side was missing:
kit::lowerwraps model text inl0_ai_text(…), which did not exist, so a card holding model text would not evaluate. This PR adds the kit function, reads the stamp, and draws the mark.What changes
components/l0/_kit.octoscript): addsfn l0_ai_text(node) { node.ai = 1 return node }. Likel0_live, it only stamps the node.octoscript-node): addsAttrs::ai. A new module,octoscript_node::ai, holds the treatment as aUiNode → UiNoderewrite (expand_ai_marks). Any backend can run the same rewrite, so they all draw the same mark.octoscript-renderre-exports it.octoscript-render/src/eval.rs): readsai.octoscript-makepad):to_makepad_uiandto_makepad_l0_ui[_with_events]expand the marks before the ink pass. The beauty inspector JSON reportsai.The mark
It follows the "AI SUMMARY" eyebrow from the OctoSense mail MVP (#261): a small sparkle and an
AIeyebrow drawn above the words. Details:wand-magic-sparkles(U+E2CA), drawn in the icon face. The ✦ character (U+2726) is not in any text face the kit ships (Roboto, NotoSans, Inter, LXGW, NotoColorEmoji), so it would render as tofu.Plain text only
Model text stays the
text:of a plain makepadLabel, emitted as an escaped string literal. There is no Markdown, HTML, TextFlow or link widget, and no autolinking. Tests check that markdown,javascript:links, HTML, an injectedon_click, andl0:{…}targets all stay inert literals.l0_ai: true(the Makepad lowering)No change is needed. makepad's
#[derive(Script)]apply reads only declared fields by name (value_for_apply(value, id!(field))), so an undeclared key on a widget object is never read.l0_ai: trueis ignored exactly asl0_event:/l0_key:already are. Nothing in this repo consumesmakepad::lower's output. The mark the user sees comes from the kit path above.ChatEntry
Per #53,
ChatEntrylowers to the existing bubbles:user→l0_bubble_me,model→l0_ai_text(l0_bubble_them(…)),host→l0_bubble_them, plus the*_longforms. A test renders all three roles. The user's bubble is right-aligned on the accent, the agent's and host's are left-aligned on the panel fill, and only the model's bubble is marked. The mark sits inside its bubble.Tests
crates/octoscript-node/src/ai.rs: 4 unit tests. They cover: untouched when unstamped; mark above the words in the same ink, quieter; idempotent; inside a bubble; text kept verbatim.crates/octoscript-makepad/tests/l0_ai_text.rs: 9 tests against the real kit. The kit calls are copied from the shapes Repin makepad to main f08eec53 (terminal draws Chinese text) #53'stests/ai_text.rsasserts. They cover:These tests are independent of the pinned Octoscript revision. I also ran them against Repin makepad to main f08eec53 (terminal draws Chinese text) #53's head (
3ca709c), along with a scratch end-to-end test (l0::prepareof Repin makepad to main f08eec53 (terminal draws Chinese text) #53's summary card andchat.cardin 4 moods), and they pass.cargo test --workspace: all green (octoscript-makepad 115 passed, 8 ignored as before).cargo clippy -p octoscript-node -p octoscript-render -p octoscript-makepad --all-targets -- -D warnings: no new findings. The crate already failed onmainbecause of 3 findings in code this PR does not touch, so this run is not fully clean:clippy::needless_borrow,l0.rs:98clippy::erasing_op,material.rs:672build_with_sys_stub,tests/l0_cards.rsWith those three allowed, it is clean.
Downstream (OctoSense)
octoscript-makepadandoctoscript-noderevs inCargo.toml, andnative-runtime.lock.json) to this PR's merge, together with Octoscript (octoscript-ui-l0and friends) to Repin makepad to main f08eec53 (terminal draws Chinese text) #53's merge. The.sourcescheckout supplies_kit.octoscriptthroughOCTOSENSE_WORKSPACE. This repo's ownoctoscript-ui-l0pin (Cargo.toml,runtime.json) also moves to Repin makepad to main f08eec53 (terminal draws Chinese text) #53 once that merges.apps/appcard/app/app/src/app/l0_eval.rsbuildsAttrs { … }exhaustively, so it will stop compiling until it addsai: int_prop(vm, value, id!(ai)),.l0_widgets::to_dsl(the device renderer) must calloctoscript_node::ai::expand_ai_marks(&mut tree)on a clone before emitting. Otherwise the stamp is read but nothing is drawn.glance_cardandphonealready go throughoctoscript_makepad::to_makepad_*, which do this.🤖 Generated with Claude Code