@roll-agent/browser-use-agent 0.26.1 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +36 -8
- package/dist/browser-observation.d.ts +1 -0
- package/dist/execution-visual-feedback.d.ts +61 -0
- package/dist/goal/compact-request.d.ts +5 -0
- package/dist/goal/contracts.d.ts +1732 -0
- package/dist/goal/decisions.d.ts +55 -0
- package/dist/goal/dependency-observation.d.ts +7 -0
- package/dist/goal/execution-context.d.ts +593 -0
- package/dist/goal/form-context.d.ts +639 -0
- package/dist/goal/form-handoff.d.ts +152 -0
- package/dist/goal/form-loop-progress.d.ts +9 -0
- package/dist/goal/form-policy.d.ts +13 -0
- package/dist/goal/host.d.ts +6 -0
- package/dist/goal/interaction-feedback.d.ts +82 -0
- package/dist/goal/loop.d.ts +12 -0
- package/dist/goal/observation-retry.d.ts +3 -0
- package/dist/goal/observation.d.ts +981 -0
- package/dist/goal/operate-handoff.d.ts +3 -0
- package/dist/goal/picker-observation.d.ts +56 -0
- package/dist/goal/picker-state.d.ts +96 -0
- package/dist/goal/reachability.d.ts +2 -0
- package/dist/goal/task-evidence.d.ts +33 -0
- package/dist/goal/task-freshness.d.ts +86 -0
- package/dist/goal/task-loop.d.ts +5 -0
- package/dist/goal/task-observation.d.ts +5 -0
- package/dist/goal/task-policy.d.ts +174 -0
- package/dist/goal/task-progress-policy.d.ts +25 -0
- package/dist/goal/task-progress.d.ts +353 -0
- package/dist/goal/task-sources.d.ts +13 -0
- package/dist/index.js +1 -1
- package/dist/native-visual-activity-session.d.ts +38 -1
- package/dist/tools/browser-operate.d.ts +252 -0
- package/dist/tools/zhipin-diagnose-browser-state.d.ts +4 -4
- package/dist/tools/zhipin-generate-reply-preview.d.ts +1 -1
- package/dist/tools/zhipin-get-candidate-info.d.ts +1 -1
- package/dist/tools/zhipin-scroll-view.d.ts +5 -5
- package/package.json +3 -3
- package/references/browser-exploration.md +52 -0
- package/references/env.yaml +11 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const PickerEvidenceSchema: z.ZodObject<{
|
|
3
|
+
part: z.ZodEnum<["trigger", "option"]>;
|
|
4
|
+
relationship: z.ZodEnum<["aria", "local-dom", "unknown"]>;
|
|
5
|
+
triggerPath: z.ZodOptional<z.ZodString>;
|
|
6
|
+
panelPaths: z.ZodArray<z.ZodString, "many">;
|
|
7
|
+
label: z.ZodOptional<z.ZodString>;
|
|
8
|
+
labelSource: z.ZodOptional<z.ZodEnum<["label", "placeholder", "empty-display"]>>;
|
|
9
|
+
expanded: z.ZodOptional<z.ZodBoolean>;
|
|
10
|
+
panelVisible: z.ZodOptional<z.ZodBoolean>;
|
|
11
|
+
selection: z.ZodEnum<["empty", "value", "unknown"]>;
|
|
12
|
+
selectionEvidence: z.ZodEnum<["native-select", "backing-input", "unknown"]>;
|
|
13
|
+
committedText: z.ZodOptional<z.ZodString>;
|
|
14
|
+
queryText: z.ZodOptional<z.ZodString>;
|
|
15
|
+
optionText: z.ZodOptional<z.ZodString>;
|
|
16
|
+
optionLabel: z.ZodOptional<z.ZodString>;
|
|
17
|
+
optionPath: z.ZodOptional<z.ZodString>;
|
|
18
|
+
optionSelected: z.ZodOptional<z.ZodBoolean>;
|
|
19
|
+
}, "strip", z.ZodTypeAny, {
|
|
20
|
+
selection: "value" | "unknown" | "empty";
|
|
21
|
+
part: "option" | "trigger";
|
|
22
|
+
relationship: "unknown" | "aria" | "local-dom";
|
|
23
|
+
panelPaths: string[];
|
|
24
|
+
selectionEvidence: "unknown" | "native-select" | "backing-input";
|
|
25
|
+
label?: string | undefined;
|
|
26
|
+
expanded?: boolean | undefined;
|
|
27
|
+
triggerPath?: string | undefined;
|
|
28
|
+
labelSource?: "label" | "placeholder" | "empty-display" | undefined;
|
|
29
|
+
panelVisible?: boolean | undefined;
|
|
30
|
+
committedText?: string | undefined;
|
|
31
|
+
queryText?: string | undefined;
|
|
32
|
+
optionText?: string | undefined;
|
|
33
|
+
optionLabel?: string | undefined;
|
|
34
|
+
optionPath?: string | undefined;
|
|
35
|
+
optionSelected?: boolean | undefined;
|
|
36
|
+
}, {
|
|
37
|
+
selection: "value" | "unknown" | "empty";
|
|
38
|
+
part: "option" | "trigger";
|
|
39
|
+
relationship: "unknown" | "aria" | "local-dom";
|
|
40
|
+
panelPaths: string[];
|
|
41
|
+
selectionEvidence: "unknown" | "native-select" | "backing-input";
|
|
42
|
+
label?: string | undefined;
|
|
43
|
+
expanded?: boolean | undefined;
|
|
44
|
+
triggerPath?: string | undefined;
|
|
45
|
+
labelSource?: "label" | "placeholder" | "empty-display" | undefined;
|
|
46
|
+
panelVisible?: boolean | undefined;
|
|
47
|
+
committedText?: string | undefined;
|
|
48
|
+
queryText?: string | undefined;
|
|
49
|
+
optionText?: string | undefined;
|
|
50
|
+
optionLabel?: string | undefined;
|
|
51
|
+
optionPath?: string | undefined;
|
|
52
|
+
optionSelected?: boolean | undefined;
|
|
53
|
+
}>;
|
|
54
|
+
export type PickerEvidence = z.infer<typeof PickerEvidenceSchema>;
|
|
55
|
+
/** Fixed read-only DOM code. No class names, site labels, coordinates or desired values. */
|
|
56
|
+
export declare const INSPECT_PICKER = "function(pathFor) {\n const el=this, doc=el.ownerDocument, view=doc.defaultView;\n if(el.getRootNode()!==doc)return undefined;\n const clean=s=>String(s||'').replace(/[\\uE000-\\uF8FF]/g,'').replace(/\\s+/g,' ').trim();\n const panelSelector='ul,ol,[role=\"listbox\"],[role=\"menu\"],[role=\"tree\"],[role=\"grid\"],[role=\"dialog\"],dialog';\n const optionSelector='li,option,[role=\"option\"],[role=\"menuitem\"],[role=\"treeitem\"]';\n const triggerSelector='input,select,button,[tabindex],[role=\"combobox\"],[aria-haspopup],[aria-controls],[aria-owns]';\n const ids=node=>[...(node.getAttribute('aria-controls')||'').split(/\\s+/),...(node.getAttribute('aria-owns')||'').split(/\\s+/)].filter(Boolean);\n const explicitPanels=node=>ids(node).map(id=>doc.getElementById(id)).filter(p=>p && p!==node);\n const hiddenValue=node=>{\n const inputs=[...node.querySelectorAll('input[type=\"hidden\"]')];\n return inputs.length===1?inputs[0]:undefined;\n };\n // A unique visible text input paired with one hidden selection token is a\n // grounded autocomplete even when the application omits ARIA combobox markup.\n const inputBacking=node=>{\n if(node.tagName!=='INPUT' || !['text','search',''].includes(node.getAttribute('type')||''))return undefined;\n for(let p=node.parentElement,depth=0;p && p!==doc.body && p.tagName!=='FORM' && depth<2;p=p.parentElement,depth++){\n const fields=[...p.querySelectorAll('input:not([type=\"hidden\"]),textarea,select')];\n if(fields.length>1)return undefined;\n const hidden=[...p.querySelectorAll('input[type=\"hidden\"]')];\n if(fields.length===1 && fields[0]===node && hidden.length===1)return hidden[0];\n }\n return undefined;\n };\n const triggerLike=node=>Boolean(inputBacking(node)) ||node.tagName==='SELECT' || node.getAttribute('role')==='combobox' ||\n Boolean(node.getAttribute('aria-haspopup') && node.getAttribute('aria-haspopup')!=='false') ||\n explicitPanels(node).some(p=>p.matches(panelSelector)||p.querySelector('[role=\"listbox\"],[role=\"menu\"],[role=\"tree\"]')) ||\n (node.tabIndex>=0 && hiddenValue(node));\n const triggersWithin=node=>{\n const all=[...node.querySelectorAll(triggerSelector)].filter(triggerLike);\n return all.filter(t=>!all.some(other=>other!==t && other.contains(t)));\n };\n const visible=node=>{\n if(!node.isConnected || !node.getClientRects().length)return false;\n for(let p=node;p;p=p.parentElement){const s=view.getComputedStyle(p);if(p.hidden || p.getAttribute('aria-hidden')==='true' || s.display==='none' || s.visibility!=='visible' || s.opacity==='0')return false;}\n return true;\n };\n const localPanels=trigger=>{\n if(trigger.tagName==='SELECT')return [];\n const nested=[...trigger.querySelectorAll(panelSelector)].filter(p=>p.querySelector(optionSelector));\n if(nested.length && !triggersWithin(trigger).length)return nested.filter(p=>!nested.some(other=>other!==p && other.contains(p)));\n for(let parent=trigger.parentElement,depth=0;parent && parent!==doc.body && depth<5;parent=parent.parentElement,depth++){\n const triggers=triggersWithin(parent);\n if(triggers.length>1)return [];\n if(triggers.length!==1 || triggers[0]!==trigger)continue;\n const panels=[...parent.querySelectorAll(panelSelector)].filter(p=>!trigger.contains(p) && p.querySelector(optionSelector));\n if(panels.length)return panels.filter(p=>!panels.some(other=>other!==p && other.contains(p)));\n }\n return [];\n };\n const option=el.closest(optionSelector);\n const ownRole=option && option.getAttribute('role');\n let trigger,panels=[],relationship='unknown',part;\n if(triggerLike(el) && !option){\n trigger=el;part='trigger';panels=explicitPanels(el);\n if(panels.length)relationship='aria';else {panels=localPanels(el);if(panels.length)relationship='local-dom';}\n if(el.tagName!=='SELECT' && !panels.length && !el.hasAttribute('aria-haspopup') && el.getAttribute('role')!=='combobox' && !inputBacking(el))return undefined;\n }else if(option){\n part='option';const panel=option.closest(panelSelector);\n if(!panel && option.tagName!=='OPTION')return undefined;\n const all=[...doc.querySelectorAll('[aria-controls],[aria-owns]')];\n const explicit=all.length<=512 ? all.filter(t=>triggerLike(t) && explicitPanels(t).some(p=>p.contains(option))) : [];\n let ambiguous=explicit.length>1 || all.length>512;\n if(explicit.length===1){trigger=explicit[0];panels=explicitPanels(trigger);relationship='aria';}\n if(!trigger && !ambiguous && panel){\n for(let parent=panel.parentElement,depth=0;parent && parent!==doc.body && depth<5;parent=parent.parentElement,depth++){\n const triggers=triggersWithin(parent).filter(t=>!panel.contains(t));\n if(triggers.length>1){ambiguous=true;break;}\n if(triggers.length===1){\n const candidate=triggers[0],owned=explicitPanels(candidate).length?explicitPanels(candidate):localPanels(candidate);\n if(owned.some(p=>p.contains(option))){trigger=candidate;panels=owned;relationship='local-dom';break;}\n }\n }\n }\n if(!trigger && !ambiguous && !['option','menuitem','treeitem'].includes(ownRole))return undefined;\n }else return undefined;\n const result={part,relationship,panelPaths:panels.map(pathFor).filter(Boolean),selection:'unknown',selectionEvidence:'unknown'};\n if(option && part==='option'){\n result.optionText=clean(option.innerText||option.textContent).slice(0,2000);\n result.optionLabel=clean(option.getAttribute('aria-label') || (option.innerText||option.textContent||'').split(/\\n/).find(line=>line.trim()) || '').slice(0,2000);\n const optionPath=pathFor(option);if(optionPath)result.optionPath=optionPath;\n if(option.hasAttribute('aria-selected'))result.optionSelected=option.getAttribute('aria-selected')==='true';\n else if(option.tagName==='OPTION')result.optionSelected=option.selected;\n }\n if(!trigger)return result;\n const path=pathFor(trigger);if(path)result.triggerPath=path;else result.relationship='unknown';\n const label=clean(trigger.getAttribute('aria-label') || [...(trigger.labels||[])].map(l=>l.textContent).join(' ') ||\n (trigger.getAttribute('aria-labelledby')||'').split(/\\s+/).map(id=>doc.getElementById(id)?.textContent||'').join(' '));\n if(label){result.label=label.slice(0,200);result.labelSource='label';}\n const backing=inputBacking(trigger);\n const hidden=hiddenValue(trigger)||backing,display=[];\n const walker=doc.createTreeWalker(trigger,4);let node;\n while((node=walker.nextNode())){\n const parent=node.parentElement;\n if(parent && visible(parent) && !parent.closest('script,style') && !panels.some(p=>p.contains(parent)))display.push(node.textContent||'');\n }\n const text=backing?clean(trigger.value):clean(display.join(''));\n if(trigger.tagName==='SELECT'){\n result.selection=trigger.selectedIndex<0 || (trigger.required && trigger.value==='')?'empty':'value';result.selectionEvidence='native-select';\n if(result.selection==='value')result.committedText=[...trigger.selectedOptions].map(o=>o.label).join(', ');\n }else if(hidden){\n result.selection=hidden.value!==''?'value':hidden.hasAttribute('value')?'unknown':'empty';result.selectionEvidence='backing-input';\n if(result.selection==='value' && text)result.committedText=text.slice(0,2000);\n if(!label && result.selection==='empty' && text){result.label=text.slice(0,200);result.labelSource='empty-display';}\n }\n if(['INPUT','TEXTAREA'].includes(trigger.tagName) && trigger.type!=='hidden'){\n if(!backing || !hidden.value || panels.some(visible))result.queryText=trigger.value;\n if(!label && trigger.placeholder){result.label=clean(trigger.placeholder).slice(0,200);result.labelSource='placeholder';}\n }\n if(panels.length)result.panelVisible=panels.some(visible);\n if(trigger.hasAttribute('aria-expanded'))result.expanded=trigger.getAttribute('aria-expanded')==='true';\n else if(panels.length)result.expanded=result.panelVisible;\n return result;\n}";
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { BrowserElementRef } from "@roll-agent/browser";
|
|
3
|
+
import type { GoalSnapshot } from "./observation.ts";
|
|
4
|
+
declare const FieldSchema: z.ZodObject<Pick<{
|
|
5
|
+
part: z.ZodEnum<["trigger", "option"]>;
|
|
6
|
+
relationship: z.ZodEnum<["aria", "local-dom", "unknown"]>;
|
|
7
|
+
triggerPath: z.ZodOptional<z.ZodString>;
|
|
8
|
+
panelPaths: z.ZodArray<z.ZodString, "many">;
|
|
9
|
+
label: z.ZodOptional<z.ZodString>;
|
|
10
|
+
labelSource: z.ZodOptional<z.ZodEnum<["label", "placeholder", "empty-display"]>>;
|
|
11
|
+
expanded: z.ZodOptional<z.ZodBoolean>;
|
|
12
|
+
panelVisible: z.ZodOptional<z.ZodBoolean>;
|
|
13
|
+
selection: z.ZodEnum<["empty", "value", "unknown"]>;
|
|
14
|
+
selectionEvidence: z.ZodEnum<["native-select", "backing-input", "unknown"]>;
|
|
15
|
+
committedText: z.ZodOptional<z.ZodString>;
|
|
16
|
+
queryText: z.ZodOptional<z.ZodString>;
|
|
17
|
+
optionText: z.ZodOptional<z.ZodString>;
|
|
18
|
+
optionLabel: z.ZodOptional<z.ZodString>;
|
|
19
|
+
optionPath: z.ZodOptional<z.ZodString>;
|
|
20
|
+
optionSelected: z.ZodOptional<z.ZodBoolean>;
|
|
21
|
+
}, "label" | "expanded" | "selection" | "relationship" | "panelVisible" | "selectionEvidence" | "committedText" | "queryText"> & {
|
|
22
|
+
id: z.ZodString;
|
|
23
|
+
triggerRef: z.ZodOptional<z.ZodString>;
|
|
24
|
+
labelOrigin: z.ZodEnum<["dom-label", "dom-placeholder", "dom-empty-display", "earlier-dom-label", "earlier-dom-placeholder", "earlier-dom-empty-display", "unknown"]>;
|
|
25
|
+
optionRefs: z.ZodArray<z.ZodString, "many">;
|
|
26
|
+
}, "strip", z.ZodTypeAny, {
|
|
27
|
+
id: string;
|
|
28
|
+
selection: "value" | "unknown" | "empty";
|
|
29
|
+
relationship: "unknown" | "aria" | "local-dom";
|
|
30
|
+
selectionEvidence: "unknown" | "native-select" | "backing-input";
|
|
31
|
+
labelOrigin: "unknown" | "dom-label" | "dom-placeholder" | "dom-empty-display" | "earlier-dom-label" | "earlier-dom-placeholder" | "earlier-dom-empty-display";
|
|
32
|
+
optionRefs: string[];
|
|
33
|
+
label?: string | undefined;
|
|
34
|
+
expanded?: boolean | undefined;
|
|
35
|
+
panelVisible?: boolean | undefined;
|
|
36
|
+
committedText?: string | undefined;
|
|
37
|
+
queryText?: string | undefined;
|
|
38
|
+
triggerRef?: string | undefined;
|
|
39
|
+
}, {
|
|
40
|
+
id: string;
|
|
41
|
+
selection: "value" | "unknown" | "empty";
|
|
42
|
+
relationship: "unknown" | "aria" | "local-dom";
|
|
43
|
+
selectionEvidence: "unknown" | "native-select" | "backing-input";
|
|
44
|
+
labelOrigin: "unknown" | "dom-label" | "dom-placeholder" | "dom-empty-display" | "earlier-dom-label" | "earlier-dom-placeholder" | "earlier-dom-empty-display";
|
|
45
|
+
optionRefs: string[];
|
|
46
|
+
label?: string | undefined;
|
|
47
|
+
expanded?: boolean | undefined;
|
|
48
|
+
panelVisible?: boolean | undefined;
|
|
49
|
+
committedText?: string | undefined;
|
|
50
|
+
queryText?: string | undefined;
|
|
51
|
+
triggerRef?: string | undefined;
|
|
52
|
+
}>;
|
|
53
|
+
declare const PartSchema: z.ZodObject<Pick<{
|
|
54
|
+
part: z.ZodEnum<["trigger", "option"]>;
|
|
55
|
+
relationship: z.ZodEnum<["aria", "local-dom", "unknown"]>;
|
|
56
|
+
triggerPath: z.ZodOptional<z.ZodString>;
|
|
57
|
+
panelPaths: z.ZodArray<z.ZodString, "many">;
|
|
58
|
+
label: z.ZodOptional<z.ZodString>;
|
|
59
|
+
labelSource: z.ZodOptional<z.ZodEnum<["label", "placeholder", "empty-display"]>>;
|
|
60
|
+
expanded: z.ZodOptional<z.ZodBoolean>;
|
|
61
|
+
panelVisible: z.ZodOptional<z.ZodBoolean>;
|
|
62
|
+
selection: z.ZodEnum<["empty", "value", "unknown"]>;
|
|
63
|
+
selectionEvidence: z.ZodEnum<["native-select", "backing-input", "unknown"]>;
|
|
64
|
+
committedText: z.ZodOptional<z.ZodString>;
|
|
65
|
+
queryText: z.ZodOptional<z.ZodString>;
|
|
66
|
+
optionText: z.ZodOptional<z.ZodString>;
|
|
67
|
+
optionLabel: z.ZodOptional<z.ZodString>;
|
|
68
|
+
optionPath: z.ZodOptional<z.ZodString>;
|
|
69
|
+
optionSelected: z.ZodOptional<z.ZodBoolean>;
|
|
70
|
+
}, "part" | "optionText" | "optionLabel" | "optionSelected"> & {
|
|
71
|
+
fieldId: z.ZodOptional<z.ZodString>;
|
|
72
|
+
}, "strip", z.ZodTypeAny, {
|
|
73
|
+
part: "option" | "trigger";
|
|
74
|
+
optionText?: string | undefined;
|
|
75
|
+
optionLabel?: string | undefined;
|
|
76
|
+
optionSelected?: boolean | undefined;
|
|
77
|
+
fieldId?: string | undefined;
|
|
78
|
+
}, {
|
|
79
|
+
part: "option" | "trigger";
|
|
80
|
+
optionText?: string | undefined;
|
|
81
|
+
optionLabel?: string | undefined;
|
|
82
|
+
optionSelected?: boolean | undefined;
|
|
83
|
+
fieldId?: string | undefined;
|
|
84
|
+
}>;
|
|
85
|
+
export type PickerField = z.infer<typeof FieldSchema>;
|
|
86
|
+
export type PickerPart = z.infer<typeof PartSchema>;
|
|
87
|
+
export type PickerState = {
|
|
88
|
+
fields: PickerField[];
|
|
89
|
+
parts: Record<string, PickerPart>;
|
|
90
|
+
};
|
|
91
|
+
/** Observation memory, not a plan or approval ledger. Never infer a relation from proximity. */
|
|
92
|
+
export declare function createPickerMemory(): {
|
|
93
|
+
observe(snapshot: GoalSnapshot): PickerState;
|
|
94
|
+
};
|
|
95
|
+
export declare function pickerActionLabel(ref: Pick<BrowserElementRef, "ref" | "role" | "name">, state: PickerState, operation?: string): string;
|
|
96
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/** Fixed read-only geometry probe. Revealing still uses the native driver's CDP path. */
|
|
2
|
+
export declare const INSPECT_REACHABILITY = "function(el,origins) {\n let revealViaScroll=false;\n const result=(availability)=>({availability,...(availability==='offscreen' && revealViaScroll?{revealViaScroll:true}:{})});\n const transformed=s=>s.transform!=='none' || s.perspective!=='none' || (s.translate && s.translate!=='none') || (s.rotate && s.rotate!=='none') || (s.scale && s.scale!=='none') || (s.zoom && s.zoom!=='normal' && Number(s.zoom)!==1);\n const layer=(node,view)=>{for(let p=node;p;p=p.parentElement){if(p.matches('dialog[open],[role=\"dialog\"],[aria-modal=\"true\"]'))return p;const s=view.getComputedStyle(p);if(s.position==='fixed' || s.position==='sticky')return p;}return null;};\n const modal=node=>node && (node.matches('dialog[open],[role=\"dialog\"],[aria-modal=\"true\"]') || Boolean(node.closest('dialog[open],[role=\"dialog\"],[aria-modal=\"true\"]')));\n const edgeLayer=(cover,ownLayer,view)=>{\n if(!cover || cover===ownLayer || modal(cover))return false;\n const cr=cover.getBoundingClientRect();\n return (cr.height<view.innerHeight/2 && (cr.top<=1 || cr.bottom>=view.innerHeight-1)) || (cr.width<view.innerWidth/2 && (cr.left<=1 || cr.right>=view.innerWidth-1));\n };\n const bounds=(node)=>{const r=node.getBoundingClientRect();return {left:r.left+node.clientLeft,top:r.top+node.clientTop,right:r.left+node.clientLeft+node.clientWidth,bottom:r.top+node.clientTop+node.clientHeight};};\n const room=(node,axis,direction)=>{const offset=axis==='x'?node.scrollLeft:node.scrollTop,max=axis==='x'?node.scrollWidth-node.clientWidth:node.scrollHeight-node.clientHeight;return direction<0?offset>1:offset<max-1;};\n try {\n let view=el.ownerDocument.defaultView,node=el;\n if(!view || !origins.includes(view.location.origin))return result('unavailable');\n const r=el.getBoundingClientRect();let point={x:r.left+r.width/2,y:r.top+r.height/2},reveal=false;\n for(let depth=0;depth<33;depth++){\n if(depth===32 || !origins.includes(view.location.origin))return result('unavailable');\n const doc=node.ownerDocument,root=doc.scrollingElement,ownLayer=layer(node,view);\n const activeModal=[...doc.querySelectorAll('dialog[open],[aria-modal=\"true\"]')].find(p=>{const s=view.getComputedStyle(p);return p.getClientRects().length && s.display!=='none' && s.visibility==='visible' && s.opacity!=='0' && !p.contains(node);});\n if(activeModal)return result('covered');\n const viewport={left:0,top:0,right:view.innerWidth,bottom:view.innerHeight};\n let scope=node,visible={...viewport},localReveal=false;\n const movable=[];\n for(let p=node;p;p=p.parentElement){\n const s=view.getComputedStyle(p);\n if(transformed(s))return result('unavailable');\n if(s.display==='none' || s.visibility!=='visible' || s.opacity==='0' || p.hasAttribute('inert'))return result('covered');\n if(p===node || p===root || p===doc.body)continue;\n const b=bounds(p);\n const axes=[['x','overflowX','left','right'],['y','overflowY','top','bottom']];\n for(const [axis,overflow,low,high] of axes){\n if(!/^(auto|scroll|hidden|clip)$/.test(s[overflow]))continue;\n const scrollable=/^(auto|scroll)$/.test(s[overflow]);\n if(scrollable)movable.push({node:p,axis,b});\n if(point[axis]<b[low] || point[axis]>=b[high]){\n if(!scrollable || !room(p,axis,point[axis]<b[low]?-1:1))return result('covered');\n point[axis]=Math.max(b[low]+1,Math.min(b[high]-2,point[axis]));scope=p;localReveal=true;visible={left:Math.max(0,b.left),top:Math.max(0,b.top),right:Math.min(view.innerWidth,b.right),bottom:Math.min(view.innerHeight,b.bottom)};\n }\n visible[low]=Math.max(visible[low],b[low]);visible[high]=Math.min(visible[high],b[high]);\n }\n }\n const rootStyle=root && view.getComputedStyle(root),bodyStyle=doc.body && view.getComputedStyle(doc.body);\n for(const [axis,overflow,low,high] of [['x','overflowX','left','right'],['y','overflowY','top','bottom']]){\n const scrollable=root && !ownLayer && ![rootStyle?.[overflow],bodyStyle?.[overflow]].some(value=>value==='hidden' || value==='clip');\n if(scrollable)movable.push({node:root,axis,b:viewport});\n if(point[axis]<viewport[low] || point[axis]>=viewport[high]){\n if(!scrollable || !room(root,axis,point[axis]<viewport[low]?-1:1))return result('covered');\n point[axis]=Math.max(viewport[low]+1,Math.min(viewport[high]-2,point[axis]));scope=root;localReveal=true;visible={...viewport};\n }\n }\n const same=(hit)=>hit && (hit===node || node.contains(hit));\n const exposed=(hit,container)=>{\n if(!hit || !(hit===container || container.contains(hit)))return false;\n const hitLayer=layer(hit,view);\n return !hitLayer || hitLayer===ownLayer;\n };\n const sample=(container,region)=>{\n if(region.right-region.left<4 || region.bottom-region.top<4)return null;\n for(const fy of [0.5,0.25,0.75,0.05,0.95])for(const fx of [0.5,0.25,0.75,0.05,0.95]){\n const p={x:region.left+(region.right-region.left)*fx,y:region.top+(region.bottom-region.top)*fy};\n if(exposed(doc.elementFromPoint(p.x,p.y),container))return p;\n }\n return null;\n };\n const hit=doc.elementFromPoint(point.x,point.y);\n if(localReveal){\n if(!exposed(hit,scope)){\n if(!edgeLayer(hit && layer(hit,view),ownLayer,view))return result('covered');\n revealViaScroll=true;\n }\n const probe=exposed(hit,scope)?point:sample(scope,visible);\n if(!probe)return result('covered');point=probe;reveal=true;\n }else if(!same(hit)){\n // A small edge-docked fixed/sticky toolbar may cover a scrollable target.\n // Dialogs, central overlays and full-screen layers are never reveal routes.\n const cover=hit && layer(hit,view),cr=cover && cover.getBoundingClientRect();\n if(!edgeLayer(cover,ownLayer,view))return result('covered');\n let probe=null;\n for(const candidate of movable){\n const axis=candidate.axis,coordinate=axis==='x'?point.x:point.y;\n const start=axis==='x'?cr.left:cr.top,end=axis==='x'?cr.right:cr.bottom;\n if(coordinate<start || coordinate>=end)continue;\n const towardStart=start>=(axis==='x'?view.innerWidth:view.innerHeight)/2;\n if(!room(candidate.node,axis,towardStart?1:-1))continue;\n const region={left:Math.max(visible.left,candidate.b.left),top:Math.max(visible.top,candidate.b.top),right:Math.min(visible.right,candidate.b.right),bottom:Math.min(visible.bottom,candidate.b.bottom)};\n if(axis==='y'){if(towardStart)region.bottom=Math.min(region.bottom,cr.top);else region.top=Math.max(region.top,cr.bottom);}\n else if(towardStart)region.right=Math.min(region.right,cr.left);else region.left=Math.max(region.left,cr.right);\n probe=sample(candidate.node,region);if(probe)break;\n }\n if(!probe)return result('covered');point=probe;reveal=true;revealViaScroll=true;\n }\n if(view===view.top)return result(reveal?'offscreen':'ready');\n const owner=view.frameElement,parent=owner?.ownerDocument.defaultView;\n if(!owner || !parent || !origins.includes(parent.location.origin))return result('unavailable');\n const box=owner.getBoundingClientRect();point={x:point.x+box.left+owner.clientLeft,y:point.y+box.top+owner.clientTop};\n node=owner;view=parent;\n }\n }catch{return result('unavailable');}\n return result('unavailable');\n}";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ReadDocument, ReadTask, TaskProgress } from "./task-progress.ts";
|
|
2
|
+
export declare function evidenceCandidates(documents: readonly ReadDocument[]): {
|
|
3
|
+
key: string;
|
|
4
|
+
doc: {
|
|
5
|
+
url: string;
|
|
6
|
+
frameId: string;
|
|
7
|
+
panelsComplete: boolean;
|
|
8
|
+
observedAt: string;
|
|
9
|
+
regions: {
|
|
10
|
+
id: string;
|
|
11
|
+
truncated: boolean;
|
|
12
|
+
name: string;
|
|
13
|
+
text: string;
|
|
14
|
+
kind: "content" | "panel";
|
|
15
|
+
}[];
|
|
16
|
+
};
|
|
17
|
+
region: {
|
|
18
|
+
id: string;
|
|
19
|
+
truncated: boolean;
|
|
20
|
+
name: string;
|
|
21
|
+
text: string;
|
|
22
|
+
kind: "content" | "panel";
|
|
23
|
+
};
|
|
24
|
+
spans: {
|
|
25
|
+
id: string;
|
|
26
|
+
text: string;
|
|
27
|
+
start: number;
|
|
28
|
+
end: number;
|
|
29
|
+
}[];
|
|
30
|
+
}[];
|
|
31
|
+
export type EvidenceCandidate = ReturnType<typeof evidenceCandidates>[number];
|
|
32
|
+
/** Commit one complete, same-observation packet. Never stitch fields from different records. */
|
|
33
|
+
export declare function commitEvidence(progress: TaskProgress, contract: ReadTask, candidate: EvidenceCandidate, selected: readonly string[], observationId: string, documentId: string): boolean;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { BrowserElementRef } from "@roll-agent/browser";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { GoalControl, GoalSnapshot } from "./observation.ts";
|
|
4
|
+
export declare const ActionDependenciesSchema: z.ZodObject<{
|
|
5
|
+
documentId: z.ZodNullable<z.ZodString>;
|
|
6
|
+
browserInstance: z.ZodNullable<z.ZodString>;
|
|
7
|
+
pageId: z.ZodNullable<z.ZodString>;
|
|
8
|
+
targetIdentity: z.ZodString;
|
|
9
|
+
relatedIdentities: z.ZodArray<z.ZodString, "many">;
|
|
10
|
+
reusable: z.ZodBoolean;
|
|
11
|
+
unavailableReasons: z.ZodArray<z.ZodString, "many">;
|
|
12
|
+
notedCoverageWarnings: z.ZodArray<z.ZodString, "many">;
|
|
13
|
+
fingerprint: z.ZodString;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
browserInstance: string | null;
|
|
16
|
+
pageId: string | null;
|
|
17
|
+
documentId: string | null;
|
|
18
|
+
fingerprint: string;
|
|
19
|
+
targetIdentity: string;
|
|
20
|
+
relatedIdentities: string[];
|
|
21
|
+
reusable: boolean;
|
|
22
|
+
unavailableReasons: string[];
|
|
23
|
+
notedCoverageWarnings: string[];
|
|
24
|
+
}, {
|
|
25
|
+
browserInstance: string | null;
|
|
26
|
+
pageId: string | null;
|
|
27
|
+
documentId: string | null;
|
|
28
|
+
fingerprint: string;
|
|
29
|
+
targetIdentity: string;
|
|
30
|
+
relatedIdentities: string[];
|
|
31
|
+
reusable: boolean;
|
|
32
|
+
unavailableReasons: string[];
|
|
33
|
+
notedCoverageWarnings: string[];
|
|
34
|
+
}>;
|
|
35
|
+
export type ActionDependencies = z.infer<typeof ActionDependenciesSchema>;
|
|
36
|
+
/** Position guides visual ordering, but movement alone is not a semantic change.
|
|
37
|
+
* Availability includes live hit testing and must remain part of every guard.
|
|
38
|
+
* Keep all other metadata, including ownership paths and constraint provenance.
|
|
39
|
+
*/
|
|
40
|
+
export declare function semanticGoalControl(control: GoalControl): Omit<GoalControl, "position">;
|
|
41
|
+
/** Capture only the current action's observed dependencies, never the whole page text.
|
|
42
|
+
* An incomplete observation is explicitly non-reusable. Callers must re-observe
|
|
43
|
+
* or escalate; a matching fingerprint never replaces the native dispatch guard.
|
|
44
|
+
*/
|
|
45
|
+
export declare function captureActionDependencies(snapshot: GoalSnapshot, target: BrowserElementRef, relatedIdentities?: readonly string[]): ActionDependencies;
|
|
46
|
+
export declare function actionDependenciesMatch(expected: ActionDependencies, fresh: GoalSnapshot): boolean;
|
|
47
|
+
export declare const FormCompletionDependenciesSchema: z.ZodObject<{
|
|
48
|
+
documentId: z.ZodNullable<z.ZodString>;
|
|
49
|
+
browserInstance: z.ZodNullable<z.ZodString>;
|
|
50
|
+
pageId: z.ZodNullable<z.ZodString>;
|
|
51
|
+
controlIdentities: z.ZodArray<z.ZodString, "many">;
|
|
52
|
+
fieldCount: z.ZodNumber;
|
|
53
|
+
reusable: z.ZodBoolean;
|
|
54
|
+
unavailableReasons: z.ZodArray<z.ZodString, "many">;
|
|
55
|
+
notedCoverageWarnings: z.ZodArray<z.ZodString, "many">;
|
|
56
|
+
fingerprint: z.ZodString;
|
|
57
|
+
}, "strip", z.ZodTypeAny, {
|
|
58
|
+
browserInstance: string | null;
|
|
59
|
+
pageId: string | null;
|
|
60
|
+
documentId: string | null;
|
|
61
|
+
fingerprint: string;
|
|
62
|
+
reusable: boolean;
|
|
63
|
+
unavailableReasons: string[];
|
|
64
|
+
notedCoverageWarnings: string[];
|
|
65
|
+
controlIdentities: string[];
|
|
66
|
+
fieldCount: number;
|
|
67
|
+
}, {
|
|
68
|
+
browserInstance: string | null;
|
|
69
|
+
pageId: string | null;
|
|
70
|
+
documentId: string | null;
|
|
71
|
+
fingerprint: string;
|
|
72
|
+
reusable: boolean;
|
|
73
|
+
unavailableReasons: string[];
|
|
74
|
+
notedCoverageWarnings: string[];
|
|
75
|
+
controlIdentities: string[];
|
|
76
|
+
fieldCount: number;
|
|
77
|
+
}>;
|
|
78
|
+
export type FormCompletionDependencies = z.infer<typeof FormCompletionDependenciesSchema>;
|
|
79
|
+
/** For a prepared form's final review only. This is an observation-change guard,
|
|
80
|
+
* not a completion oracle. Preserve every observed control and AX/context error;
|
|
81
|
+
* exclude only the independent pageText blob, which mixes unrelated clocks with
|
|
82
|
+
* page content. Non-form or incomplete observations must use the caller's global
|
|
83
|
+
* fallback. In particular, this cannot certify text absent from AX/DOM metadata.
|
|
84
|
+
*/
|
|
85
|
+
export declare function captureFormCompletionDependencies(snapshot: GoalSnapshot): FormCompletionDependencies;
|
|
86
|
+
export declare function formCompletionDependenciesMatch(expected: FormCompletionDependencies, fresh: GoalSnapshot): boolean;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { BrowserOperateInput, BrowserOperateOutput } from "./contracts.ts";
|
|
2
|
+
import type { DecisionProvider } from "./decisions.ts";
|
|
3
|
+
import type { GoalDriver } from "./loop.ts";
|
|
4
|
+
/** Interaction only: the selected engine decides; Roll owns preparation and final verification. */
|
|
5
|
+
export declare function runBrowserTask(input: BrowserOperateInput, driver: GoalDriver, decide: DecisionProvider, signal: AbortSignal): Promise<BrowserOperateOutput>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { NativeCdpController } from "@roll-agent/browser";
|
|
2
|
+
import type { GoalSnapshot } from "./observation.ts";
|
|
3
|
+
export declare const READ_GOAL_TEXT = "function(origins, limit, captureEvidence) {\n const doc=this.ownerDocument || this, view=doc && doc.defaultView;\n if(!view || !origins.includes(view.location.origin)) return {text:'',truncated:true};\n if(!doc.body)return {text:'',truncated:false};\n const visible=el=>el.checkVisibility({checkOpacity:true,checkVisibilityCSS:true}) && [...el.getClientRects()].some(r=>r.width>0 && r.height>0 && r.bottom>0 && r.top<view.innerHeight && r.right>0 && r.left<view.innerWidth);\n const text=el=>(el?.innerText || el?.textContent || '').replace(/\\s+/g,' ').trim();\n const panels=[...doc.querySelectorAll('dialog[open],[role=\"dialog\"],[aria-modal=\"true\"],[class*=\"dialog\"],[class*=\"modal\"],[class*=\"popup\"]')].filter(el=>{\n if(!visible(el))return false;\n const style=view.getComputedStyle(el);\n return el.matches('dialog[open],[role=\"dialog\"],[aria-modal=\"true\"]') || ['fixed','absolute'].includes(style.position) && /(?:^|[\\s_-])(dialog|modal|popup)(?:[\\s_-]|$)/i.test(String(el.className));\n });\n const pageState={\n panels:panels.filter(el=>!panels.some(parent=>parent!==el && parent.contains(el))).slice(0,16).map(el=>(el.getAttribute('aria-label') || text(el.querySelector('h1,h2,h3,h4,[role=\"heading\"],[class*=\"title\"]')) || text(el) || 'Unlabelled visible panel').slice(0,400)),\n selectedTabs:[...doc.querySelectorAll('[role=\"tab\"][aria-selected=\"true\"],[class*=\"tab\"].active,[class*=\"tab\"].selected,[class*=\"tab\"][aria-current=\"page\"]')].filter(visible).slice(0,32).map(el=>text(el).slice(0,200)),\n busy:[...doc.querySelectorAll('[aria-busy=\"true\"],[role=\"progressbar\"]')].some(visible)\n };\n const pathOf=el=>{const parts=[];for(let p=el;p&&p!==doc.body;p=p.parentElement){let n=1;for(let q=p.previousElementSibling;q;q=q.previousElementSibling)if(q.tagName===p.tagName)n++;parts.unshift(p.tagName.toLowerCase()+':'+n)}return parts.join('/')};\n const outerPanels=panels.filter(el=>!panels.some(parent=>parent!==el&&parent.contains(el)));\n const contentRegions=!captureEvidence ? [] : outerPanels.length ? outerPanels : [...doc.querySelectorAll('main,article,[role=\"main\"]')].filter(visible).filter(el=>!el.parentElement?.closest('main,article,[role=\"main\"]'));\n const readDocument=captureEvidence ? {url:doc.location.href,panelsComplete:outerPanels.length<=4,\n regions:contentRegions.slice(0,4).map(el=>{const raw=el.innerText||'';return {id:pathOf(el),name:(el.getAttribute('aria-label')||text(el.querySelector('h1,h2,h3,h4,[role=\"heading\"],[class*=\"title\"]'))||'Unlabelled content region').slice(0,400),kind:outerPanels.includes(el)?'panel':'content',text:raw.slice(0,16000),truncated:raw.length>16000}})} : undefined;\n const walker=doc.createTreeWalker(doc.body,4), range=doc.createRange(), parts=[];\n let node, length=0, visited=0;\n while((node=walker.nextNode()) && visited++<5000){\n const parent=node.parentElement, text=(node.textContent||'').replace(/\\s+/g,' ').trim();\n if(!text || !parent || parent.closest('script,style,noscript,template,[aria-hidden=\"true\"]'))continue;\n if(!parent.checkVisibility({checkOpacity:true,checkVisibilityCSS:true}))continue;\n range.selectNodeContents(node);const r=range.getBoundingClientRect();\n if(!r.width || !r.height || r.bottom<=0 || r.top>=view.innerHeight || r.right<=0 || r.left>=view.innerWidth)continue;\n parts.push(text.slice(0,Math.max(0,limit-length)));length+=text.length+1;\n if(length>=limit)return {text:parts.join('\\n').slice(0,limit),truncated:true,pageState,...(readDocument?{readDocument}:{})};\n }\n return {text:parts.join('\\n').slice(0,limit),truncated:visited>=5000,pageState,...(readDocument?{readDocument}:{})};\n}";
|
|
4
|
+
/** Text has its own budget; static layout must never consume the control budget. */
|
|
5
|
+
export declare function attachTaskText(controller: Pick<NativeCdpController, "resolveBackendNode" | "callFunctionOnObject" | "releaseObject">, snapshot: GoalSnapshot, origins: readonly string[], signal: AbortSignal, captureEvidence?: boolean): Promise<GoalSnapshot>;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import type { ExecutionContext } from "./execution-context.ts";
|
|
2
|
+
import type { TaskProgress } from "./task-progress.ts";
|
|
3
|
+
import type { BrowserAxNode, BrowserElementRef } from "@roll-agent/browser";
|
|
4
|
+
import type { BrowserOperateInput, BrowserOperateOutput } from "./contracts.ts";
|
|
5
|
+
import type { DecisionRequest } from "./decisions.ts";
|
|
6
|
+
import type { PickerState } from "./picker-state.ts";
|
|
7
|
+
import type { GoalSnapshot } from "./observation.ts";
|
|
8
|
+
export declare const taskNodes: (nodes: readonly BrowserAxNode[]) => BrowserAxNode[];
|
|
9
|
+
export declare function taskControlIdentity(ref: BrowserElementRef): string;
|
|
10
|
+
export declare function taskElements(snapshot: GoalSnapshot): {
|
|
11
|
+
ref: string;
|
|
12
|
+
identity: string;
|
|
13
|
+
role: string;
|
|
14
|
+
name: string;
|
|
15
|
+
disabled: boolean;
|
|
16
|
+
readonly: string | number | boolean | undefined;
|
|
17
|
+
value: string | undefined;
|
|
18
|
+
valueKind: string;
|
|
19
|
+
displayText: string | undefined;
|
|
20
|
+
checked: string | number | boolean | undefined;
|
|
21
|
+
selected: string | number | boolean | undefined;
|
|
22
|
+
fieldLabel: string | undefined;
|
|
23
|
+
pickerIdentity: string | undefined;
|
|
24
|
+
readable: boolean | undefined;
|
|
25
|
+
peerGroup: {
|
|
26
|
+
count: number;
|
|
27
|
+
key: string;
|
|
28
|
+
position: number;
|
|
29
|
+
} | undefined;
|
|
30
|
+
pickerOwnerPath: string | undefined;
|
|
31
|
+
pickerOptionPath: string | undefined;
|
|
32
|
+
pickerOptionLabel: string | undefined;
|
|
33
|
+
required: boolean | undefined;
|
|
34
|
+
requiredSource: "html" | "aria" | "label-required" | "label-optional" | undefined;
|
|
35
|
+
constraints: {
|
|
36
|
+
multiple?: boolean | undefined;
|
|
37
|
+
pattern?: string | undefined;
|
|
38
|
+
min?: string | undefined;
|
|
39
|
+
max?: string | undefined;
|
|
40
|
+
step?: string | undefined;
|
|
41
|
+
minlength?: string | undefined;
|
|
42
|
+
maxlength?: string | undefined;
|
|
43
|
+
} | undefined;
|
|
44
|
+
position: {
|
|
45
|
+
left: number;
|
|
46
|
+
top: number;
|
|
47
|
+
} | undefined;
|
|
48
|
+
scrollContainerPaths: string[] | undefined;
|
|
49
|
+
revealViaScroll: boolean | undefined;
|
|
50
|
+
inputType: string | undefined;
|
|
51
|
+
expanded: string | number | boolean | undefined;
|
|
52
|
+
validationErrors: string[] | undefined;
|
|
53
|
+
invalid: string | number | boolean | undefined;
|
|
54
|
+
context: string[];
|
|
55
|
+
availability: "hidden" | "ready" | "offscreen" | "covered" | "unavailable";
|
|
56
|
+
editable: boolean | undefined;
|
|
57
|
+
layer: string | undefined;
|
|
58
|
+
modal: boolean | undefined;
|
|
59
|
+
nativeSelect: boolean | undefined;
|
|
60
|
+
options: {
|
|
61
|
+
value: string;
|
|
62
|
+
label: string;
|
|
63
|
+
disabled: boolean;
|
|
64
|
+
selected: boolean;
|
|
65
|
+
}[] | undefined;
|
|
66
|
+
optionsTruncated: boolean | undefined;
|
|
67
|
+
}[];
|
|
68
|
+
export declare function taskFingerprint(snapshot: GoalSnapshot): string;
|
|
69
|
+
export declare function taskState(input: BrowserOperateInput, snapshot: GoalSnapshot, history: BrowserOperateOutput["steps"], guidance?: string, resolvedValues?: NonNullable<BrowserOperateOutput["resolvedValues"]>, pickers?: PickerState): {
|
|
70
|
+
originalGoal: string;
|
|
71
|
+
pickerFields: {
|
|
72
|
+
id: string;
|
|
73
|
+
selection: "value" | "unknown" | "empty";
|
|
74
|
+
relationship: "unknown" | "aria" | "local-dom";
|
|
75
|
+
selectionEvidence: "unknown" | "native-select" | "backing-input";
|
|
76
|
+
labelOrigin: "unknown" | "dom-label" | "dom-placeholder" | "dom-empty-display" | "earlier-dom-label" | "earlier-dom-placeholder" | "earlier-dom-empty-display";
|
|
77
|
+
optionRefs: string[];
|
|
78
|
+
label?: string | undefined;
|
|
79
|
+
expanded?: boolean | undefined;
|
|
80
|
+
panelVisible?: boolean | undefined;
|
|
81
|
+
committedText?: string | undefined;
|
|
82
|
+
queryText?: string | undefined;
|
|
83
|
+
triggerRef?: string | undefined;
|
|
84
|
+
}[];
|
|
85
|
+
activePanels: string[];
|
|
86
|
+
selectedTabs: string[] | undefined;
|
|
87
|
+
pageBusy: boolean | undefined;
|
|
88
|
+
valueSemantics: string;
|
|
89
|
+
delegatedDecisions: string[];
|
|
90
|
+
pageText: string;
|
|
91
|
+
pageTextTruncated: boolean | undefined;
|
|
92
|
+
facts: {
|
|
93
|
+
[k: string]: {
|
|
94
|
+
name: string;
|
|
95
|
+
text: string;
|
|
96
|
+
fullLength: number;
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
elements: {
|
|
100
|
+
value: string | undefined;
|
|
101
|
+
fullLength: number | undefined;
|
|
102
|
+
sourceValueMatches: string[];
|
|
103
|
+
writtenValueMatches: string[];
|
|
104
|
+
picker?: {
|
|
105
|
+
part: "option" | "trigger";
|
|
106
|
+
optionText?: string | undefined;
|
|
107
|
+
optionLabel?: string | undefined;
|
|
108
|
+
optionSelected?: boolean | undefined;
|
|
109
|
+
fieldId?: string | undefined;
|
|
110
|
+
};
|
|
111
|
+
displayText?: string;
|
|
112
|
+
valueKind: string;
|
|
113
|
+
options?: {
|
|
114
|
+
disabled?: boolean;
|
|
115
|
+
selected?: boolean;
|
|
116
|
+
label: string;
|
|
117
|
+
}[];
|
|
118
|
+
modal?: boolean;
|
|
119
|
+
layer?: string;
|
|
120
|
+
context: string[];
|
|
121
|
+
availability?: "hidden" | "offscreen" | "covered" | "unavailable";
|
|
122
|
+
invalid?: string | number | true;
|
|
123
|
+
validationErrors?: string[];
|
|
124
|
+
expanded?: string | number | boolean;
|
|
125
|
+
inputType?: string;
|
|
126
|
+
position?: {
|
|
127
|
+
left: number;
|
|
128
|
+
top: number;
|
|
129
|
+
};
|
|
130
|
+
constraints?: {
|
|
131
|
+
multiple?: boolean | undefined;
|
|
132
|
+
pattern?: string | undefined;
|
|
133
|
+
min?: string | undefined;
|
|
134
|
+
max?: string | undefined;
|
|
135
|
+
step?: string | undefined;
|
|
136
|
+
minlength?: string | undefined;
|
|
137
|
+
maxlength?: string | undefined;
|
|
138
|
+
};
|
|
139
|
+
requiredSource?: "html" | "aria" | "label-required" | "label-optional";
|
|
140
|
+
required?: boolean;
|
|
141
|
+
fieldLabel?: string;
|
|
142
|
+
selected?: string | number | boolean;
|
|
143
|
+
checked?: string | number | boolean;
|
|
144
|
+
nativeSelect?: boolean;
|
|
145
|
+
editable?: boolean;
|
|
146
|
+
readonly?: boolean;
|
|
147
|
+
disabled?: boolean;
|
|
148
|
+
ref: string;
|
|
149
|
+
role: string;
|
|
150
|
+
name: string;
|
|
151
|
+
frame: number;
|
|
152
|
+
}[];
|
|
153
|
+
contexts: Record<string, string>;
|
|
154
|
+
resolvedValues: {
|
|
155
|
+
id: string;
|
|
156
|
+
field: string;
|
|
157
|
+
source: "selected" | "supplied" | "derived" | "generated";
|
|
158
|
+
sourceIds: string[];
|
|
159
|
+
text: string;
|
|
160
|
+
fullLength: number;
|
|
161
|
+
}[];
|
|
162
|
+
recentActions: {
|
|
163
|
+
operation: string;
|
|
164
|
+
target: string | undefined;
|
|
165
|
+
valueName: string | undefined;
|
|
166
|
+
executed: boolean;
|
|
167
|
+
error: string | undefined;
|
|
168
|
+
}[];
|
|
169
|
+
guidance: string;
|
|
170
|
+
forbiddenControlNames: string[];
|
|
171
|
+
truncated: boolean;
|
|
172
|
+
coverageWarnings: string[] | undefined;
|
|
173
|
+
};
|
|
174
|
+
export declare function buildTaskDecisionRequest(input: BrowserOperateInput, snapshot: GoalSnapshot, history: BrowserOperateOutput["steps"], guidance?: string, suppressedClicks?: ReadonlySet<string>, resolvedValues?: NonNullable<BrowserOperateOutput["resolvedValues"]>, pickers?: PickerState, progress?: TaskProgress, execution?: ExecutionContext): DecisionRequest;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DecisionRequest } from "./decisions.ts";
|
|
2
|
+
import type { GoalSnapshot } from "./observation.ts";
|
|
3
|
+
import type { ReadTask, TaskProgress } from "./task-progress.ts";
|
|
4
|
+
export declare function progressSummary(progress: TaskProgress, contract: ReadTask): {
|
|
5
|
+
taskRunId: string;
|
|
6
|
+
phase: "collect" | "return" | "done";
|
|
7
|
+
target: string;
|
|
8
|
+
captureView: string;
|
|
9
|
+
outputs: string[];
|
|
10
|
+
captured: {
|
|
11
|
+
field: string;
|
|
12
|
+
evidenceId: string;
|
|
13
|
+
text: string;
|
|
14
|
+
}[];
|
|
15
|
+
missing: string[];
|
|
16
|
+
terminal: {
|
|
17
|
+
view: string;
|
|
18
|
+
selectedTab?: string | undefined;
|
|
19
|
+
};
|
|
20
|
+
remaining: string;
|
|
21
|
+
};
|
|
22
|
+
/** All questions consume the SAME observed state; branches never read one another's answers. */
|
|
23
|
+
export declare function withTaskProgress(request: DecisionRequest, snapshot: GoalSnapshot, contract: ReadTask | undefined, progress: TaskProgress | undefined): DecisionRequest;
|
|
24
|
+
export declare function acceptProgressEvidence(progress: TaskProgress, contract: ReadTask, snapshot: GoalSnapshot, choices: Record<string, string>): boolean;
|
|
25
|
+
export declare function terminalObservationMatches(progress: TaskProgress, contract: ReadTask, snapshot: GoalSnapshot): boolean;
|