diff --git a/pkg/spec/src/action-tree.ts b/pkg/spec/src/action-tree.ts index d606f59..d34b73c 100644 --- a/pkg/spec/src/action-tree.ts +++ b/pkg/spec/src/action-tree.ts @@ -63,7 +63,7 @@ export type GeneratorNode = | { kind: "weighted"; branches: ReadonlyArray } | { kind: "actions"; generate: () => ActionDescriptor[] } | { kind: "builtin"; verb: BuiltinVerb } - | { kind: "llm"; config: { model: string } }; + | { kind: "llm"; config: { model: string; instructions?: 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 6a69bcf..86022f3 100644 --- a/pkg/spec/src/actions.ts +++ b/pkg/spec/src/actions.ts @@ -38,9 +38,11 @@ export function actions(generator: () => Action[]): GeneratorNode { // random candidate, Go drives an OpenAI-compatible 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 +// config off globalThis.actions. API key comes from OPENROUTER_API_KEY // (OpenRouter) or OPENAI_API_KEY (OpenAI); OpenRouter wins when both are set. -export function llm(config: { model: string }): GeneratorNode { +// Optional `instructions` are appended to the model's prompt as generic +// bug-hunting guidance for this spec; the model still only ranks candidates. +export function llm(config: { model: string; instructions?: string }): GeneratorNode { return { kind: "llm", config }; }