@@ -6,72 +6,77 @@ const kernel = new Kernel();
66
77const app = kernel . app ( 'ts-stagehand' ) ;
88
9- interface SearchQueryInput {
10- query : string ;
9+ interface CompanyInput {
10+ company : string ;
1111}
1212
13- interface SearchQueryOutput {
14- url : string ;
13+ interface TeamSizeOutput {
14+ teamSize : string ;
1515}
1616
1717// LLM API Keys are set in the environment during `kernel deploy <filename> -e OPENAI_API_KEY=XXX`
18- // See https://onkernel.com/docs/launch/deploy#environment-variables
18+ // See https://www.onkernel.com/docs/apps/deploy#environment-variables
19+
1920const OPENAI_API_KEY = process . env . OPENAI_API_KEY ;
2021
2122if ( ! OPENAI_API_KEY ) {
2223 throw new Error ( 'OPENAI_API_KEY is not set' ) ;
2324}
2425
25- app . action < SearchQueryInput , SearchQueryOutput > (
26- 'stagehand -task' ,
27- async ( ctx : KernelContext , payload ?: SearchQueryInput ) : Promise < SearchQueryOutput > => {
28- // A function that returns the first search result of a given search query from Google
29-
26+ app . action < CompanyInput , TeamSizeOutput > (
27+ 'teamsize -task' ,
28+ async ( ctx : KernelContext , payload ?: CompanyInput ) : Promise < TeamSizeOutput > => {
29+ // A function that returns the team size of a Y Combinator startup
30+
3031 // Args:
3132 // ctx: Kernel context containing invocation information
32- // payload: A search query string
33-
33+ // payload: A startup name to search for on YCombinator's website
34+
3435 // Returns:
35- // output: The URL of the first search result
36+ // output: The team size (number of employees) of the startup
3637
37- if ( ! payload ?. query ) {
38- throw new Error ( 'Query is required' ) ;
39- }
38+ const company = payload ?. company || 'kernel' ;
4039
4140 const kernelBrowser = await kernel . browsers . create ( {
4241 invocation_id : ctx . invocation_id ,
4342 stealth : true ,
4443 } ) ;
45-
44+
4645 console . log ( "Kernel browser live view url: " , kernelBrowser . browser_live_view_url ) ;
4746
4847 const stagehand = new Stagehand ( {
4948 env : "LOCAL" ,
50- verbose : 1 ,
51- domSettleTimeoutMs : 30_000 ,
52- modelName : "openai/gpt-4o" ,
53- modelClientOptions : {
54- apiKey : OPENAI_API_KEY ,
55- } ,
5649 localBrowserLaunchOptions : {
5750 cdpUrl : kernelBrowser . cdp_ws_url ,
58- }
51+ } ,
52+ model : "openai/gpt-4.1" ,
53+ apiKey : OPENAI_API_KEY ,
54+ verbose : 1 ,
55+ domSettleTimeout : 30_000
5956 } ) ;
6057 await stagehand . init ( ) ;
6158
6259 /////////////////////////////////////
6360 // Your Stagehand implementation here
6461 /////////////////////////////////////
65- const page = stagehand . page ;
66- await page . act ( `Type in ${ payload . query } into the search bar` ) ;
67- await page . act ( "Click the search button" ) ;
68- const output = await page . extract ( {
69- instruction : "Extract the url of the first search result" ,
70- schema : z . object ( { url : z . string ( ) } )
71- } ) ;
62+ const page = stagehand . context . pages ( ) [ 0 ] ;
63+ await page . goto ( "https://www.ycombinator.com/companies" ) ;
7264
65+ await stagehand . act ( `Type in ${ company } into the search box` ) ;
66+ await stagehand . act ( "Click on the first search result" ) ;
67+
68+ // Schema definition
69+ const teamSizeSchema = z . object ( {
70+ teamSize : z . string ( ) ,
71+ } ) ;
72+ // Extract team size from the YC startup page
73+ const output = await stagehand . extract (
74+ "Extract the team size (number of employees) shown on this Y Combinator company page." ,
75+ teamSizeSchema
76+ ) ;
7377 await stagehand . close ( ) ;
74-
78+ await kernel . browsers . deleteByID ( kernelBrowser . session_id ) ;
79+
7580 return output ;
7681 } ,
7782) ;
0 commit comments