Added
-
Rnamespace — reactors native to the fluent builder (Python + TypeScript parity). Signals and rules are now first-class builder concerns, matching the weight ofS/C/M. The 100x move is a registry-backed facade that turns signals into name-addressed cells and predicates into name-addressed factories, plusBuilder.on(predicate, handler?, opts?)for declarative rule attachment andR.compile(builders, {bus})for tree-walking compilation acrossPipeline/FanOut/Loop:# before — hand-built sequence of four distinct objects bus = EventBus() temp = Signal("temp", 72).attach(bus) r = Reactor() r.when(temp.rising.where(lambda v: v > 90), handler, priority=10) r.start() # after — name-addressed, declarative, composable temp = R.signal("temp", 72) cooler = (Agent("cooler", "gemini-2.5-flash") .instruct("Plan a cool-down.") .on(R.rising("temp").where(lambda v: v > 90), handler, priority=10)) reactor = R.compile([cooler], bus=bus); reactor.start()
Both ports ship with an end-to-end cookbook example (
81_reactor_native.py/.ts) and 21 tests apiece (test_reactor_namespace.py/reactor-namespace.test.ts). -
SignalRegistry— thread-safe (Python) / async-safe (TS) name→signal map backing theRfacade. One per session. Exposes.signal(name, initial),.get(name),.has(name),.names(),.rule(...),.attach(bus),.clear().R.scope()returns a fresh isolated registry for tests and multi-tenant workflows. -
RuleSpec— frozen declarative rule record ({predicate, handler, name, priority, preemptive}) stored on builders via.on()and materialised into liveReactorRuleinstances byR.compile(). Stored asbuilder._reactor_rules(read-only view). -
ReactorPlugin— owns the reactor's lifecycle as an ADKBasePlugin.on_session_startstarts the reactor,on_session_endstops it. Drop-in replacement for manualreactor.start()/stop()calls. -
R.computed(name, fn)— derived signal with auto-tracked dependencies. Reads viaSignal.get()insidefnare transparently subscribed; the computed signal recomputes when any dep changes. Exported ascomputedat the package root in TS.
Changed
SignalPredicate.debounce(ms)/.throttle(ms)are now immutable (Python + TS). Previously both methods mutatedselfand returnedself— callingbase.debounce(50)silently rewrote every other user ofbase. They now return a freshSignalPredicatewith the updated window and leave the receiver untouched. This is a quiet correctness fix: any code that chained.debounce()/.throttle()onto a throw-away predicate continues to work; code that intentionally shared a base predicate now gets the correct isolation.- Harness re-exports —
R,SignalRegistry,RuleSpec,ReactorPlugin,computed,make_rule_spec/makeRuleSpecare now exported from the top-level package in both Python (from adk_fluent import R, SignalRegistry, ...) and TypeScript (import { R, SignalRegistry, ... } from "adk-fluent-ts").
Documentation
CLAUDE.md+ts/CLAUDE.mdregenerated — the auto-generated reactor section inshared/scripts/llms_generator.py(_TS_HARNESS_PACKAGES) now documents theRnamespace,Builder.on(), theSignalRegistry/RuleSpec/ReactorPlugintrio, and the debounce/throttle immutability fix. The same text flows throughjust llmstodocs/llms.txt,docs/llms-ts.txt,.clinerules/adk-fluent.md,.cursor/rules/adk-fluent.mdc,.github/instructions/adk-fluent.instructions.md, and.windsurfrules.