@tangle-network/browser-agent-driver 0.23.0 → 0.24.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-decomposer.js","sourceRoot":"","sources":["../../src/runner/goal-decomposer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Parallel Runner — executes compound goals across multiple browser tabs.
3
+ *
4
+ * Gen 21: takes decomposed sub-goals from GoalDecomposer, creates one
5
+ * BrowserAgent per sub-goal in separate Pages (shared BrowserContext),
6
+ * runs them concurrently, and merges results via EvidenceMerger.
7
+ *
8
+ * Uses the same PlaywrightDriver + BrowserAgent stack as single-page runs.
9
+ * The parallel execution layer is thin — the intelligence is in the
10
+ * GoalDecomposer (split) and EvidenceMerger (combine).
11
+ */
12
+ import type { BrowserContext } from 'playwright';
13
+ import type { PlaywrightDriverOptions } from '../drivers/playwright.js';
14
+ import type { Scenario, AgentConfig, AgentResult, Turn } from '../types.js';
15
+ import type { SubGoal } from './goal-decomposer.js';
16
+ import type { ProjectStore } from '../memory/project-store.js';
17
+ export interface ParallelRunOptions {
18
+ /** Browser context to create new pages in */
19
+ context: BrowserContext;
20
+ /** Agent config (shared across sub-agents) */
21
+ config: AgentConfig;
22
+ /** The original compound goal */
23
+ originalGoal: string;
24
+ /** Decomposed sub-goals */
25
+ subGoals: SubGoal[];
26
+ /** Original scenario (for timeout, memory, etc.) */
27
+ scenario: Scenario;
28
+ /** Per-turn callback with sub-agent label */
29
+ onTurn?: (label: string, turn: Turn) => void;
30
+ /** Driver options */
31
+ driverOptions?: PlaywrightDriverOptions;
32
+ /** Project store for memory */
33
+ projectStore?: ProjectStore;
34
+ /** Total timeout in ms (default: 600000) */
35
+ timeoutMs?: number;
36
+ /** Total token budget (will be split across sub-agents) */
37
+ totalTokenBudget?: number;
38
+ }
39
+ export interface ParallelRunResult {
40
+ /** Merged final result text */
41
+ mergedResult: string;
42
+ /** Whether the overall goal was achieved */
43
+ success: boolean;
44
+ /** Per-sub-agent results */
45
+ subResults: Array<{
46
+ subGoal: SubGoal;
47
+ result: AgentResult;
48
+ }>;
49
+ /** Total tokens across all sub-agents */
50
+ totalTokens: number;
51
+ /** Total wall time */
52
+ totalMs: number;
53
+ }
54
+ /**
55
+ * Run sub-goals in parallel across separate browser tabs.
56
+ *
57
+ * Creates one Page + PlaywrightDriver + BrowserAgent per sub-goal,
58
+ * runs them concurrently with per-agent timeouts, and collects results.
59
+ */
60
+ export declare function runParallel(options: ParallelRunOptions): Promise<ParallelRunResult>;
61
+ //# sourceMappingURL=parallel-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallel-runner.d.ts","sourceRoot":"","sources":["../../src/runner/parallel-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAEvE,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAE9D,MAAM,WAAW,kBAAkB;IACjC,6CAA6C;IAC7C,OAAO,EAAE,cAAc,CAAA;IACvB,8CAA8C;IAC9C,MAAM,EAAE,WAAW,CAAA;IACnB,iCAAiC;IACjC,YAAY,EAAE,MAAM,CAAA;IACpB,2BAA2B;IAC3B,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,oDAAoD;IACpD,QAAQ,EAAE,QAAQ,CAAA;IAClB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAAA;IAC5C,qBAAqB;IACrB,aAAa,CAAC,EAAE,uBAAuB,CAAA;IACvC,+BAA+B;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2DAA2D;IAC3D,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,+BAA+B;IAC/B,YAAY,EAAE,MAAM,CAAA;IACpB,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAA;IAChB,4BAA4B;IAC5B,UAAU,EAAE,KAAK,CAAC;QAChB,OAAO,EAAE,OAAO,CAAA;QAChB,MAAM,EAAE,WAAW,CAAA;KACpB,CAAC,CAAA;IACF,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAA;IACnB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA8FzF"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Parallel Runner — executes compound goals across multiple browser tabs.
3
+ *
4
+ * Gen 21: takes decomposed sub-goals from GoalDecomposer, creates one
5
+ * BrowserAgent per sub-goal in separate Pages (shared BrowserContext),
6
+ * runs them concurrently, and merges results via EvidenceMerger.
7
+ *
8
+ * Uses the same PlaywrightDriver + BrowserAgent stack as single-page runs.
9
+ * The parallel execution layer is thin — the intelligence is in the
10
+ * GoalDecomposer (split) and EvidenceMerger (combine).
11
+ */
12
+ import { PlaywrightDriver } from '../drivers/playwright.js';
13
+ import { BrowserAgent } from './runner.js';
14
+ /**
15
+ * Run sub-goals in parallel across separate browser tabs.
16
+ *
17
+ * Creates one Page + PlaywrightDriver + BrowserAgent per sub-goal,
18
+ * runs them concurrently with per-agent timeouts, and collects results.
19
+ */
20
+ export async function runParallel(options) {
21
+ const startTime = Date.now();
22
+ const { context, config, subGoals, scenario, onTurn } = options;
23
+ // Per-sub-agent timeout: split the total timeout proportionally
24
+ const totalTimeout = options.timeoutMs || 600_000;
25
+ const perAgentTimeout = Math.floor(totalTimeout * 0.85); // 85% of total, leave room for merge
26
+ // Create and run sub-agents in parallel
27
+ const subPromises = subGoals.map(async (subGoal, index) => {
28
+ const label = `sub-${index}`;
29
+ let page;
30
+ try {
31
+ page = await context.newPage();
32
+ const driver = new PlaywrightDriver(page, {
33
+ ...options.driverOptions,
34
+ showCursor: false, // no cursor overlay on parallel tabs
35
+ });
36
+ // Set up resource blocking if configured
37
+ const blocking = config.resourceBlocking;
38
+ if (blocking) {
39
+ await driver.setupResourceBlocking(blocking);
40
+ }
41
+ const subConfig = {
42
+ ...config,
43
+ // Scale token budget by sub-goal's budget fraction
44
+ tokenBudget: options.totalTokenBudget
45
+ ? Math.floor(options.totalTokenBudget * subGoal.budgetFraction)
46
+ : undefined,
47
+ };
48
+ const agent = new BrowserAgent({
49
+ driver,
50
+ config: subConfig,
51
+ onTurn: onTurn ? (turn) => onTurn(label, turn) : undefined,
52
+ projectStore: options.projectStore,
53
+ // extensions passed through if available
54
+ });
55
+ const subScenario = {
56
+ ...scenario,
57
+ goal: subGoal.goal,
58
+ startUrl: subGoal.startUrl || scenario.startUrl,
59
+ // Scale max turns by budget fraction
60
+ maxTurns: Math.max(10, Math.floor((scenario.maxTurns || 30) * subGoal.budgetFraction * 1.5)),
61
+ };
62
+ const result = await Promise.race([
63
+ agent.run(subScenario),
64
+ new Promise((_, reject) => setTimeout(() => reject(new Error(`Sub-agent ${label} timed out`)), perAgentTimeout)),
65
+ ]);
66
+ return { subGoal, result };
67
+ }
68
+ catch (err) {
69
+ // Sub-agent failed — return a failure result
70
+ return {
71
+ subGoal,
72
+ result: {
73
+ success: false,
74
+ reason: `Sub-agent error: ${err instanceof Error ? err.message : String(err)}`,
75
+ turns: [],
76
+ totalMs: Date.now() - startTime,
77
+ },
78
+ };
79
+ }
80
+ finally {
81
+ // Close the page but not the context (shared with other sub-agents)
82
+ if (page && !page.isClosed()) {
83
+ await page.close().catch(() => { });
84
+ }
85
+ }
86
+ });
87
+ const subResults = await Promise.all(subPromises);
88
+ // Merge results
89
+ const mergedResult = mergeEvidence(options.originalGoal, subResults);
90
+ const totalTokens = subResults.reduce((sum, sr) => {
91
+ const tokens = sr.result.totalTokensUsed || 0;
92
+ return sum + tokens;
93
+ }, 0);
94
+ return {
95
+ mergedResult: mergedResult.text,
96
+ success: mergedResult.success,
97
+ subResults,
98
+ totalTokens,
99
+ totalMs: Date.now() - startTime,
100
+ };
101
+ }
102
+ /**
103
+ * Merge evidence from parallel sub-agents into one coherent answer.
104
+ *
105
+ * For now: deterministic merge (concatenate results with labels).
106
+ * Future: LLM-based synthesis for complex comparisons.
107
+ */
108
+ function mergeEvidence(originalGoal, subResults) {
109
+ const successCount = subResults.filter(sr => sr.result.success).length;
110
+ const allSucceeded = successCount === subResults.length;
111
+ const anySucceeded = successCount > 0;
112
+ // Build merged result text
113
+ const parts = [`Goal: ${originalGoal}`, ''];
114
+ for (const { subGoal, result } of subResults) {
115
+ const status = result.success ? 'COMPLETED' : 'FAILED';
116
+ parts.push(`[${status}] ${subGoal.goal}:`);
117
+ if (result.reason) {
118
+ parts.push(result.reason);
119
+ }
120
+ parts.push('');
121
+ }
122
+ if (!anySucceeded) {
123
+ parts.push('None of the sub-goals could be completed.');
124
+ }
125
+ else if (!allSucceeded) {
126
+ parts.push(`${successCount}/${subResults.length} sub-goals completed.`);
127
+ }
128
+ return {
129
+ text: parts.join('\n'),
130
+ success: anySucceeded, // succeed if at least one sub-goal worked
131
+ };
132
+ }
133
+ //# sourceMappingURL=parallel-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parallel-runner.js","sourceRoot":"","sources":["../../src/runner/parallel-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Pattern Extractor — learns reusable navigation patterns from completed runs.
3
+ *
4
+ * Gen 26b: after a successful run, mechanically extract domain-level patterns
5
+ * from the turn log and record them as AppKnowledge facts. No LLM call needed —
6
+ * patterns are detected by observing action/state sequences.
7
+ *
8
+ * Extracted patterns:
9
+ * - Cookie/consent banner dismissal (which action dismissed it, on which turn)
10
+ * - Page load timing (how long the site takes to settle)
11
+ * - Form structure (which refs are used for key form fields)
12
+ * - Navigation paths (effective URL patterns for search/results)
13
+ * - Blockers encountered (modals, auth walls, rate limits)
14
+ *
15
+ * Design constraints:
16
+ * - No bloat: only records patterns with clear signal (not every action)
17
+ * - Cleanable: all facts have confidence scores; low-confidence facts auto-prune
18
+ * - Workspace-isolated: patterns stored per-domain in the knowledge store
19
+ * - Smart: confirms patterns on repeat observation, decays on contradiction
20
+ */
21
+ import type { Turn } from '../types.js';
22
+ import type { AppKnowledge, Fact } from '../memory/knowledge.js';
23
+ interface ExtractedPattern {
24
+ type: Fact['type'];
25
+ key: string;
26
+ value: string;
27
+ }
28
+ /**
29
+ * Extract reusable patterns from a completed run's turns.
30
+ * Only extracts from SUCCESSFUL runs — failed runs produce unreliable patterns.
31
+ */
32
+ export declare function extractPatterns(turns: Turn[], domain: string, success: boolean): ExtractedPattern[];
33
+ /**
34
+ * Record extracted patterns into the knowledge store.
35
+ * Respects the existing confidence system — repeated patterns gain confidence,
36
+ * contradicted patterns decay.
37
+ */
38
+ export declare function recordPatterns(knowledge: AppKnowledge, patterns: ExtractedPattern[]): void;
39
+ export {};
40
+ //# sourceMappingURL=pattern-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-extractor.d.ts","sourceRoot":"","sources":["../../src/runner/pattern-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAA;AAEhE,UAAU,gBAAgB;IACxB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,IAAI,EAAE,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,GACf,gBAAgB,EAAE,CA6FpB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,YAAY,EACvB,QAAQ,EAAE,gBAAgB,EAAE,GAC3B,IAAI,CAIN"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Pattern Extractor — learns reusable navigation patterns from completed runs.
3
+ *
4
+ * Gen 26b: after a successful run, mechanically extract domain-level patterns
5
+ * from the turn log and record them as AppKnowledge facts. No LLM call needed —
6
+ * patterns are detected by observing action/state sequences.
7
+ *
8
+ * Extracted patterns:
9
+ * - Cookie/consent banner dismissal (which action dismissed it, on which turn)
10
+ * - Page load timing (how long the site takes to settle)
11
+ * - Form structure (which refs are used for key form fields)
12
+ * - Navigation paths (effective URL patterns for search/results)
13
+ * - Blockers encountered (modals, auth walls, rate limits)
14
+ *
15
+ * Design constraints:
16
+ * - No bloat: only records patterns with clear signal (not every action)
17
+ * - Cleanable: all facts have confidence scores; low-confidence facts auto-prune
18
+ * - Workspace-isolated: patterns stored per-domain in the knowledge store
19
+ * - Smart: confirms patterns on repeat observation, decays on contradiction
20
+ */
21
+ /**
22
+ * Extract reusable patterns from a completed run's turns.
23
+ * Only extracts from SUCCESSFUL runs — failed runs produce unreliable patterns.
24
+ */
25
+ export function extractPatterns(turns, domain, success) {
26
+ if (!success || turns.length < 2)
27
+ return [];
28
+ const patterns = [];
29
+ // 1. Cookie/consent banner dismissal
30
+ // Look for early turns where the agent clicked something that looks like
31
+ // cookie/consent/accept and then proceeded normally
32
+ for (let i = 0; i < Math.min(turns.length, 5); i++) {
33
+ const turn = turns[i];
34
+ const action = turn.action;
35
+ if (action.action === 'click' || action.action === 'clickAt' || action.action === 'clickLabel') {
36
+ const reasoning = turn.reasoning?.toLowerCase() || '';
37
+ const snapshot = turn.state?.snapshot?.toLowerCase() || '';
38
+ if (/cookie|consent|accept.*cookie|gdpr|privacy/i.test(reasoning + snapshot)) {
39
+ const selector = 'selector' in action ? action.selector : `clickAt(${action.x},${action.y})`;
40
+ patterns.push({
41
+ type: 'pattern',
42
+ key: 'cookie-dismiss',
43
+ value: `Turn ${i + 1}: ${action.action} ${selector}`,
44
+ });
45
+ break; // only record the first one
46
+ }
47
+ }
48
+ }
49
+ // 2. Page load timing — how many turns before first meaningful action
50
+ const firstMeaningfulTurn = turns.findIndex(t => t.action.action !== 'wait' && t.action.action !== 'scroll' &&
51
+ !t.error && t.action.action !== 'navigate');
52
+ if (firstMeaningfulTurn >= 2) {
53
+ patterns.push({
54
+ type: 'timing',
55
+ key: 'first-meaningful-action',
56
+ value: `Turn ${firstMeaningfulTurn + 1} (${firstMeaningfulTurn} setup turns)`,
57
+ });
58
+ }
59
+ // 3. Effective search/navigation URL pattern
60
+ // If the agent used navigate with URL params, record the pattern
61
+ for (const turn of turns) {
62
+ if (turn.action.action === 'navigate' && turn.action.url) {
63
+ try {
64
+ const url = new URL(turn.action.url);
65
+ if (url.hostname.includes(domain) && url.search.length > 5) {
66
+ // Generalize: replace specific values with placeholders
67
+ const pattern = url.pathname + url.search
68
+ .replace(/=[^&]+/g, '={value}')
69
+ .slice(0, 100);
70
+ patterns.push({
71
+ type: 'pattern',
72
+ key: 'search-url',
73
+ value: pattern,
74
+ });
75
+ break; // only record the first effective search URL
76
+ }
77
+ }
78
+ catch { /* invalid URL, skip */ }
79
+ }
80
+ }
81
+ // 4. Turn efficiency — how many turns the task took
82
+ patterns.push({
83
+ type: 'timing',
84
+ key: 'typical-turns',
85
+ value: `${turns.length} turns`,
86
+ });
87
+ // 5. Form fields used — record which refs were used for form filling
88
+ const fillTurns = turns.filter(t => t.action.action === 'fill' || t.action.action === 'type');
89
+ if (fillTurns.length >= 2) {
90
+ const fields = fillTurns
91
+ .map(t => {
92
+ if (t.action.action === 'fill' && 'fields' in t.action && t.action.fields) {
93
+ return Object.keys(t.action.fields).join(',');
94
+ }
95
+ if (t.action.action === 'type' && 'selector' in t.action) {
96
+ return t.action.selector;
97
+ }
98
+ return '';
99
+ })
100
+ .filter(Boolean)
101
+ .slice(0, 5);
102
+ if (fields.length > 0) {
103
+ patterns.push({
104
+ type: 'selector',
105
+ key: 'form-fields',
106
+ value: fields.join(' → '),
107
+ });
108
+ }
109
+ }
110
+ return patterns;
111
+ }
112
+ /**
113
+ * Record extracted patterns into the knowledge store.
114
+ * Respects the existing confidence system — repeated patterns gain confidence,
115
+ * contradicted patterns decay.
116
+ */
117
+ export function recordPatterns(knowledge, patterns) {
118
+ for (const p of patterns) {
119
+ knowledge.recordFact(p.type, p.key, p.value);
120
+ }
121
+ }
122
+ //# sourceMappingURL=pattern-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pattern-extractor.js","sourceRoot":"","sources":["../../src/runner/pattern-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAWH;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,MAAc,EACd,OAAgB;IAEhB,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IAE3C,MAAM,QAAQ,GAAuB,EAAE,CAAA;IAEvC,qCAAqC;IACrC,yEAAyE;IACzE,oDAAoD;IACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACnD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QAC1B,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;YAC/F,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,CAAA;YACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,CAAA;YAC1D,IAAI,6CAA6C,CAAC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,EAAE,CAAC;gBAC7E,MAAM,QAAQ,GAAG,UAAU,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAY,MAAyB,CAAC,CAAC,IAAK,MAAyB,CAAC,CAAC,GAAG,CAAA;gBACpI,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,SAAS;oBACf,GAAG,EAAE,gBAAgB;oBACrB,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,MAAM,IAAI,QAAQ,EAAE;iBACrD,CAAC,CAAA;gBACF,MAAK,CAAC,4BAA4B;YACpC,CAAC;QACH,CAAC;IACH,CAAC;IAED,sEAAsE;IACtE,MAAM,mBAAmB,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAC9C,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ;QAC1D,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,UAAU,CAC3C,CAAA;IACD,IAAI,mBAAmB,IAAI,CAAC,EAAE,CAAC;QAC7B,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,QAAQ;YACd,GAAG,EAAE,yBAAyB;YAC9B,KAAK,EAAE,QAAQ,mBAAmB,GAAG,CAAC,KAAK,mBAAmB,eAAe;SAC9E,CAAC,CAAA;IACJ,CAAC;IAED,6CAA6C;IAC7C,iEAAiE;IACjE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;YACzD,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;gBACpC,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC3D,wDAAwD;oBACxD,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM;yBACtC,OAAO,CAAC,SAAS,EAAE,UAAU,CAAC;yBAC9B,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;oBAChB,QAAQ,CAAC,IAAI,CAAC;wBACZ,IAAI,EAAE,SAAS;wBACf,GAAG,EAAE,YAAY;wBACjB,KAAK,EAAE,OAAO;qBACf,CAAC,CAAA;oBACF,MAAK,CAAC,6CAA6C;gBACrD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAC,uBAAuB,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,oDAAoD;IACpD,QAAQ,CAAC,IAAI,CAAC;QACZ,IAAI,EAAE,QAAQ;QACd,GAAG,EAAE,eAAe;QACpB,KAAK,EAAE,GAAG,KAAK,CAAC,MAAM,QAAQ;KAC/B,CAAC,CAAA;IAEF,qEAAqE;IACrE,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,CAAA;IAC7F,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,SAAS;aACrB,GAAG,CAAC,CAAC,CAAC,EAAE;YACP,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC1E,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC/C,CAAC;YACD,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,UAAU,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;gBACzD,OAAO,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAA;YAC1B,CAAC;YACD,OAAO,EAAE,CAAA;QACX,CAAC,CAAC;aACD,MAAM,CAAC,OAAO,CAAC;aACf,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QACd,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,UAAU;gBAChB,GAAG,EAAE,aAAa;gBAClB,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;aAC1B,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,SAAuB,EACvB,QAA4B;IAE5B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAA;IAC9C,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner/runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAkC,MAAM,aAAa,CAAC;AAKvH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAuB/D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAa,MAAM,aAAa,CAAC;AAGtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAiDzF;AA4CD,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,6BAA6B;IAC7B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC9B,wDAAwD;IACxD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACnG,wDAAwD;IACxD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,sEAAsE;IACtE,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,sDAAsD;IACtD,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,kBAAkB,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAgB3D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CA2BtF;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,MAAM,CAAC,CAAuB;IACtC,OAAO,CAAC,aAAa,CAAC,CAAqF;IAC3G,OAAO,CAAC,mBAAmB,CAAC,CAAS;IACrC,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,WAAW,CAAC,CAAc;IAClC,OAAO,CAAC,SAAS,CAAC,CAAe;IACjC,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,eAAe,CAAwB;IAC/C,OAAO,CAAC,GAAG,CAAe;IAC1B,OAAO,CAAC,YAAY,CAAM;IAK1B,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,UAAU,CAAC,CAAqB;gBAE5B,OAAO,EAAE,mBAAmB;IAyBlC,GAAG,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC;IAm4DnD,OAAO,CAAC,qBAAqB;IA2B7B,qEAAqE;IACrE,OAAO,CAAC,UAAU;IAkClB;;;;;;;;;;;;OAYG;IACH;;;;;;;;;;;;;;;;;;;OAmBG;YACW,WAAW;YAofX,YAAY;YAkCZ,+BAA+B;YAgE/B,mCAAmC;YAwCnC,6BAA6B;YA4C7B,qCAAqC;YAqBrC,4BAA4B;YA4B5B,4BAA4B;YAkC5B,wBAAwB;CASvC;AAED,2BAA2B;AAC3B,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,QAAQ,CAAC,GAC5C,OAAO,CAAC,WAAW,CAAC,CAGtB"}
@@ -282,6 +282,37 @@ export class BrowserAgent {
282
282
  this.runRegistry = options.runRegistry;
283
283
  }
284
284
  async run(scenario) {
285
+ // Gen 21: parallel tab execution for compound goals.
286
+ // Pre-flight: check if the goal should be decomposed into parallel sub-goals.
287
+ if (this.config.parallelTabs?.enabled && scenario.goal && scenario.startUrl) {
288
+ const context = this.driver.getPage?.()?.context();
289
+ if (context) {
290
+ const { decomposeGoal } = await import('./goal-decomposer.js');
291
+ const decomposition = await decomposeGoal(scenario.goal, scenario.startUrl, {
292
+ provider: this.config.provider || 'openai',
293
+ model: this.config.navModel || 'gpt-4.1-mini',
294
+ apiKey: this.config.apiKey,
295
+ });
296
+ if (decomposition.type === 'compound' && decomposition.subGoals) {
297
+ const { runParallel } = await import('./parallel-runner.js');
298
+ const result = await runParallel({
299
+ context,
300
+ config: this.config,
301
+ originalGoal: scenario.goal,
302
+ subGoals: decomposition.subGoals,
303
+ scenario,
304
+ onTurn: this.onTurn ? (_label, turn) => this.onTurn(turn) : undefined,
305
+ projectStore: this.projectStore,
306
+ });
307
+ return {
308
+ success: result.success,
309
+ reason: result.mergedResult,
310
+ turns: [],
311
+ totalMs: result.totalMs,
312
+ };
313
+ }
314
+ }
315
+ }
285
316
  // Gen 14: vision mode gets more turns — each turn takes ~15s (screenshot
286
317
  // encode + image tokens) vs ~5s for DOM-first. Without the boost, vision
287
318
  // runs out of turns before completing multi-step tasks.
@@ -322,7 +353,7 @@ export class BrowserAgent {
322
353
  phaseTimings,
323
354
  wasteMetrics: deriveWasteMetrics(turns, runState.verificationRejectionCount, runState.firstSufficientEvidenceTurn),
324
355
  };
325
- this.saveMemory(scenario, agentResult);
356
+ this.saveMemory(scenario, agentResult, turns);
326
357
  // Complete run manifest
327
358
  const lastTurn = agentResult.turns[agentResult.turns.length - 1];
328
359
  this.runRegistry?.completeRun(runId, {
@@ -410,8 +441,9 @@ export class BrowserAgent {
410
441
  });
411
442
  const supervisorConfig = {
412
443
  enabled: this.config.supervisor?.enabled ?? DEFAULT_SUPERVISOR.enabled,
413
- model: this.config.supervisor?.model || this.config.model || 'gpt-5.4',
414
- provider: this.config.supervisor?.provider || this.config.provider || 'openai',
444
+ // Gen 28: models.supervisor overrides supervisor.model, falls back to main
445
+ model: this.config.models?.supervisor?.model || this.config.supervisor?.model || this.config.model || 'gpt-5.4',
446
+ provider: (this.config.models?.supervisor?.provider || this.config.supervisor?.provider || this.config.provider || 'openai'),
415
447
  useVision: this.config.supervisor?.useVision ?? DEFAULT_SUPERVISOR.useVision,
416
448
  minTurnsBeforeInvoke: this.config.supervisor?.minTurnsBeforeInvoke ?? DEFAULT_SUPERVISOR.minTurnsBeforeInvoke,
417
449
  cooldownTurns: this.config.supervisor?.cooldownTurns ?? DEFAULT_SUPERVISOR.cooldownTurns,
@@ -1931,10 +1963,29 @@ export class BrowserAgent {
1931
1963
  return selected;
1932
1964
  }
1933
1965
  /** Persist knowledge, selector cache, and session history to disk */
1934
- saveMemory(scenario, result) {
1966
+ saveMemory(scenario, result, turns) {
1935
1967
  try {
1936
1968
  if (this.knowledge && scenario && result) {
1937
1969
  this.knowledge.recordSession(buildSession(scenario, result));
1970
+ // Gen 26b: extract reusable patterns from successful runs.
1971
+ // Patterns gain confidence with repeated observation and auto-decay
1972
+ // when contradicted. Low-confidence facts are pruned automatically.
1973
+ if (result.success && turns && turns.length > 0) {
1974
+ const domain = safeHostname(scenario.startUrl || '') || '';
1975
+ if (domain) {
1976
+ // Dynamic import to keep the module tree clean
1977
+ import('./pattern-extractor.js').then(({ extractPatterns, recordPatterns }) => {
1978
+ const patterns = extractPatterns(turns, domain, result.success);
1979
+ if (patterns.length > 0) {
1980
+ recordPatterns(this.knowledge, patterns);
1981
+ this.knowledge.save();
1982
+ if (this.config.debug) {
1983
+ console.log(`[Runner] Recorded ${patterns.length} patterns for ${domain}`);
1984
+ }
1985
+ }
1986
+ }).catch(() => { });
1987
+ }
1988
+ }
1938
1989
  }
1939
1990
  this.knowledge?.save();
1940
1991
  this.selectorCache?.save();