@@ -24,14 +24,20 @@ import { Context } from './context';
2424import performTools from './performTools' ;
2525import expectTools from './expectTools' ;
2626
27- import type * as channels from '@protocol/channels' ;
2827import type * as actions from './actions' ;
2928import type { ToolDefinition } from './tool' ;
3029import type * as loopTypes from '@lowire/loop' ;
30+ import type { Progress } from '../progress' ;
3131
32- export async function pageAgentPerform ( context : Context , options : loopTypes . LoopEvents & channels . PageAgentPerformParams ) {
33- const cacheKey = ( options . cacheKey ?? options . task ) . trim ( ) ;
34- if ( await cachedPerform ( context , cacheKey ) )
32+ export type CallParams = {
33+ cacheKey ?: string ;
34+ maxTokens ?: number ;
35+ maxTurns ?: number ;
36+ } ;
37+
38+ export async function pageAgentPerform ( progress : Progress , context : Context , userTask : string , callParams : CallParams ) {
39+ const cacheKey = ( callParams . cacheKey ?? userTask ) . trim ( ) ;
40+ if ( await cachedPerform ( progress , context , cacheKey ) )
3541 return ;
3642
3743 const task = `
@@ -40,16 +46,17 @@ export async function pageAgentPerform(context: Context, options: loopTypes.Loop
4046- Your reply should be a tool call that performs action the page".
4147
4248### Task
43- ${ options . task }
49+ ${ userTask }
4450` ;
4551
46- await runLoop ( context , performTools , task , undefined , options ) ;
52+ await runLoop ( progress , context , performTools , task , undefined , callParams ) ;
53+ context . history . push ( { type : 'perform' , description : userTask } ) ;
4754 await updateCache ( context , cacheKey ) ;
4855}
4956
50- export async function pageAgentExpect ( context : Context , options : loopTypes . LoopEvents & channels . PageAgentExpectParams ) {
51- const cacheKey = ( options . cacheKey ?? options . expectation ) . trim ( ) ;
52- if ( await cachedPerform ( context , cacheKey ) )
57+ export async function pageAgentExpect ( progress : Progress , context : Context , expectation : string , callParams : CallParams ) {
58+ const cacheKey = ( callParams . cacheKey ?? expectation ) . trim ( ) ;
59+ if ( await cachedPerform ( progress , context , cacheKey ) )
5360 return ;
5461
5562 const task = `
@@ -58,76 +65,86 @@ export async function pageAgentExpect(context: Context, options: loopTypes.LoopE
5865- You can call exactly one tool and it can't be report_results, must be one of the assertion tools.
5966
6067### Expectation
61- ${ options . expectation }
68+ ${ expectation }
6269` ;
6370
64- await runLoop ( context , expectTools , task , undefined , options ) ;
71+ await runLoop ( progress , context , expectTools , task , undefined , callParams ) ;
72+ context . history . push ( { type : 'expect' , description : expectation } ) ;
6573 await updateCache ( context , cacheKey ) ;
6674}
6775
68- export async function runLoop ( context : Context , toolDefinitions : ToolDefinition [ ] , userTask : string , resultSchema : loopTypes . Schema | undefined , options : loopTypes . LoopEvents & {
69- api ?: string ,
70- apiEndpoint ?: string ,
71- apiKey ?: string ,
72- model ?: string ,
73- maxTurns ?: number ;
74- maxTokens ?: number ;
75- } ) : Promise < {
76+ export async function pageAgentExtract ( progress : Progress , context : Context , query : string , schema : loopTypes . Schema , callParams : CallParams ) : Promise < any > {
77+
78+ const task = `
79+ ### Instructions
80+ Extract the following information from the page. Do not perform any actions, just extract the information.
81+
82+ ### Query
83+ ${ query } `;
84+ const { result } = await runLoop ( progress , context , [ ] , task , schema , callParams ) ;
85+ context . history . push ( { type : 'extract' , description : query } ) ;
86+ return result ;
87+ }
88+
89+ async function runLoop ( progress : Progress , context : Context , toolDefinitions : ToolDefinition [ ] , userTask : string , resultSchema : loopTypes . Schema | undefined , params : CallParams ) : Promise < {
7690 result : any
7791} > {
7892 const { page } = context ;
93+ if ( ! context . agentParams . api || ! context . agentParams . apiKey || ! context . agentParams . model )
94+ throw new Error ( `This action requires the API and API key to be set on the page agent. Are you running with --run-agents=none mode?` ) ;
7995
80- if ( ! context . options ?. api || ! context . options ?. apiKey || ! context . options ?. model )
81- throw new Error ( `This action requires the API and API key to be set on the browser context` ) ;
82-
83- const { full } = await page . snapshotForAI ( context . progress ) ;
84- const { tools, callTool } = toolsForLoop ( context , toolDefinitions , { resultSchema } ) ;
96+ const { full } = await page . snapshotForAI ( progress ) ;
97+ const { tools, callTool, reportedResult } = toolsForLoop ( progress , context , toolDefinitions , { resultSchema } ) ;
8598
8699 const loop = new Loop ( {
87- api : context . options . api as any ,
88- apiEndpoint : context . options . apiEndpoint ,
89- apiKey : context . options . apiKey ,
90- model : context . options . model ,
91- maxTurns : context . options . maxTurns ,
92- maxTokens : context . options . maxTokens ,
100+ api : context . agentParams . api as any ,
101+ apiEndpoint : context . agentParams . apiEndpoint ,
102+ apiKey : context . agentParams . apiKey ,
103+ model : context . agentParams . model ,
104+ maxTurns : params . maxTurns ?? context . agentParams . maxTurns ,
105+ maxTokens : params . maxTokens ?? context . agentParams . maxTokens ,
93106 summarize : true ,
94107 debug,
95108 callTool,
96109 tools,
110+ ...context . events ,
97111 } ) ;
98112
99113 const task = `${ userTask }
100114
115+ ### Context history
116+ ${ context . history . map ( h => `- ${ h . type } : ${ h . description } ` ) . join ( '\n' ) }
117+
101118### Page snapshot
102119${ full }
103120` ;
104121
105- const { result } = await loop . run ( task ) ;
106- return { result } ;
122+ await loop . run ( task ) ;
123+ return { result : resultSchema ? reportedResult ( ) : undefined } ;
107124}
108125
109126type CachedActions = Record < string , {
110127 timestamp : number ,
111128 actions : actions . ActionWithCode [ ] ,
112129} > ;
113130
114- async function cachedPerform ( context : Context , cacheKey : string ) : Promise < actions . ActionWithCode [ ] | undefined > {
115- if ( ! context . options ?. cacheFile )
131+ async function cachedPerform ( progress : Progress , context : Context , cacheKey : string ) : Promise < actions . ActionWithCode [ ] | undefined > {
132+ if ( ! context . agentParams ?. cacheFile )
116133 return ;
117134
118- const cache = await cachedActions ( context . options ?. cacheFile ) ;
135+ const cache = await cachedActions ( context . agentParams ?. cacheFile ) ;
119136 const entry = cache . actions [ cacheKey ] ;
120137 if ( ! entry )
121138 return ;
122139
123140 for ( const action of entry . actions )
124- await runAction ( context . progress , 'run' , context . page , action , context . options . secrets ?? [ ] ) ;
141+ await runAction ( progress , 'run' , context . page , action , context . agentParams . secrets ?? [ ] ) ;
125142 return entry . actions ;
126143}
127144
128145async function updateCache ( context : Context , cacheKey : string ) {
129- const cacheFile = context . options ?. cacheFile ;
130- const cacheOutFile = context . options ?. cacheOutFile ;
146+ const cacheFile = context . agentParams ?. cacheFile ;
147+ const cacheOutFile = context . agentParams ?. cacheOutFile ;
131148 const cacheFileKey = cacheFile ?? cacheOutFile ;
132149
133150 const cache = cacheFileKey ? await cachedActions ( cacheFileKey ) : { actions : { } , newActions : { } } ;
0 commit comments