From e30ed6f7ed64cd29a0209692e2385270a30c5224 Mon Sep 17 00:00:00 2001 From: PJ Date: Fri, 12 Jun 2026 10:25:51 +0530 Subject: [PATCH] feat(spec): add llm() action-backend marker --- pkg/spec/src/action-tree.ts | 5 ++++- pkg/spec/src/actions.ts | 9 +++++++++ pkg/spec/src/index.ts | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/pkg/spec/src/action-tree.ts b/pkg/spec/src/action-tree.ts index 910b149..d606f59 100644 --- a/pkg/spec/src/action-tree.ts +++ b/pkg/spec/src/action-tree.ts @@ -57,10 +57,13 @@ export type ActionDescriptor = // weighted: probabilistic choice over child nodes, scanned ascending. // actions: author callback returning a list to pick uniformly from. // builtin: host-backed leaf identified by a verb. +// llm: marker selecting the LLM action backend; inert on the JS picker +// (walk returns null), Go reads config.model off globalThis.actions. export type GeneratorNode = | { kind: "weighted"; branches: ReadonlyArray } | { kind: "actions"; generate: () => ActionDescriptor[] } - | { kind: "builtin"; verb: BuiltinVerb }; + | { kind: "builtin"; verb: BuiltinVerb } + | { kind: "llm"; config: { model: string } }; // Candidate is one host-enumerated target for a builtin verb. The host // resolves geometry (and a native selector) so no element handle crosses into diff --git a/pkg/spec/src/actions.ts b/pkg/spec/src/actions.ts index 5e11445..a254606 100644 --- a/pkg/spec/src/actions.ts +++ b/pkg/spec/src/actions.ts @@ -34,6 +34,15 @@ export function actions(generator: () => Action[]): GeneratorNode { return { kind: "actions", generate: generator as () => ActionDescriptor[] }; } +// llm selects the LLM action backend: instead of the seeded picker drawing a +// random candidate, Go drives an OpenRouter model that chooses which candidate +// to act on from the screenshot + the candidate list. The returned marker is +// inert on the JS picker (pick.ts walks it to null); Go reads its config.model +// off globalThis.actions. API key comes from OPENROUTER_API_KEY. +export function llm(config: { model: string }): GeneratorNode { + return { kind: "llm", config }; +} + export function whenRoute( routeExtractor: { readonly current: string | null }, routes: string | readonly string[], diff --git a/pkg/spec/src/index.ts b/pkg/spec/src/index.ts index 809f4bf..4ac8c31 100644 --- a/pkg/spec/src/index.ts +++ b/pkg/spec/src/index.ts @@ -42,6 +42,7 @@ export { actions, doubleTaps, from, + llm, longPresses, pressKeys, scrolls,