feat(runtime): exec_actions + get_fragments tools; semantic fragment targets - #41
Open
joelgwebber wants to merge 2 commits into
Open
feat(runtime): exec_actions + get_fragments tools; semantic fragment targets#41joelgwebber wants to merge 2 commits into
joelgwebber wants to merge 2 commits into
Conversation
…targets (sites-b573, sites-6a1a) A + B-lite of the exec-actions decomposition (sites-10b3), stacked on the L1 executor (#36). B-lite (generator): carry each step's corpus-vocabulary target into the IR as Step.target -- the source compquery for a query step, the destination view name for navigate/goto/waitFor-view (a goto deep link resolves via ViewForURL), the key for keypress. Fragment labels + the execActions tail/interrupt projection render this instead of reconstructing raw locators, so agents compose/read in component/view names. Label/provenance only; the runtime still selects via the compiled query (firewall holds). Golden IRs + frozen example plans re-stamped. A (runtime): register exec_actions + get_fragments as always-on WebMCP tools. exec_actions consumes fragment REFERENCES (+ arg overrides), expands them to compiled steps, runs the resumable executor, and returns the status with the untried tail re-expressed as fragment refs -- so raw steps never cross the tool boundary and a resume is just a re-call with 'remaining'. get_fragments returns the current view's base set (ensure_view filtered; the 1-hop guidance horizon is sites-90dc). Registration dedups against the shared native registry via getTools() so the tools appear exactly once across the multiple execution contexts an Angular/Zone SPA boots the bundle in. Verified live on JB: 6 tools 1x each; get_fragments returns component-vocabulary labels (FlightCard/FareOption/SelectFareButton/SortControl, goto -> SelectFlights); exec_actions runs a fragment-ref list to completion (done 3/3) and, on a bad arg, interrupts cleanly with reason + observed path + remaining refs + readable view. 65 runtime tests pass (meta-tools.test.ts added); generator golden tests pass. Signed-off-by: Joel Webber <joel@fullstory.com>
joelgwebber
added this pull request to stack #42
September 11, 2026 23:35
…rred boot When boot is deferred to post-settle on an Angular/Zone SPA (sites-67f3), the always-on meta tools (exec_actions/get_fragments) failed to register: - Angular's Zone re-wraps document.modelContext between boot and the async registerMetaTools pass, so the ctx captured at boot goes stale and its registerTool never lands. Re-read the live document.modelContext at call time. - Two same-tick native registerTool calls race and JetBlue drops the second (exec_actions present, get_fragments missing). Await the two registrations sequentially. Found running the full JB checkout with #40's deferred boot + these tools together; verified 6 tools 1x each afterward. (sites-06d2) Signed-off-by: Joel Webber <joel@fullstory.com>
joelgwebber
added a commit
that referenced
this pull request
Sep 12, 2026
…orizon (sites-90dc) get_fragments returned only the current view's tools. It now also returns the 1-hop horizon: tools one navigation away, reached via the current view's tools' guidance graph (Suggestion[]), so an agent can pre-compose the next step instead of hitting a hard cut at the view boundary. Each fragment carries view (owning tool's view) and distance (0 = here, 1 = one hop). Reachability rides per-tool guidance only; one hop deliberately (deeper is journey territory). New scopedFragments(ir, path) in the executor (pure, testable); boot's currentFragments delegates to it. projectFragments now also tags each fragment with its owning tool's view. 67 runtime tests (scopedFragments base/horizon/distance + a get_fragments horizon test added). Stacks on #41. Signed-off-by: Joel Webber <joel@fullstory.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.
Stacked on #36 (L1 executor). This is A + B-lite of the exec-actions decomposition (sites-10b3): expose the resumable executor as a real WebMCP fallback, composed over corpus-vocabulary fragments.
A — exec_actions + get_fragments (always-on fallback surface)
Two always-on WebMCP tools register alongside the view-scoped tools:
{id, tool, op, label, uses}. Returns the current view's base set (ensure_view filtered); the 1-hop guidance horizon + distance tiering is the follow-up (sites-90dc).remaining. On an interruption (unexpected modal, missing field) it stops instead of hanging and reports the reason + observed path + remaining refs + a readableremainingView.Registration dedups against the shared native registry (
getTools()), so the tools appear exactly once even though an Angular/Zone SPA boots the injected bundle in several execution contexts (a per-instance flag can't dedup across them).B-lite — semantic fragment targets (generator)
The generator now carries each step's corpus-vocabulary target into the IR (
Step.target): the source compquery for a query step (FormField[label*="First" i] FieldInput), the destination view name for navigate/goto/waitFor-view (agotodeep link resolves to its view viaViewForURL), the key for keypress. Fragment labels and the executor's tail/interrupt projection render this instead of reconstructing raw locators, so an agent composes and reads in component/view names. It is label/provenance only — the runtime still selects via the compiledquery, so the IR firewall holds. Golden IRs and the frozen example plans are re-stamped.Verification (live on JetBlue,
--webmcp)click FlightCard[flight_no*="{{flight}}"] FareOption[label*="{{cabin}}"],SortControl, andgoto→SelectFlights— no raw selectors/URLs.select_fare.0/.1/.2) to completion (done:true, 3/3); on a bad arg it interrupts cleanly with{interrupt:{at,action,reason,observed.path}, remaining:[refs], remainingView:[…]}.meta-tools.test.tscovers registration, view-filteredget_fragments, and the interrupt→resume ref tail); generator golden tests pass.Part of sites-10b3. Follow-up: contextual fragment filtering / 1-hop horizon (sites-90dc).