Custom output format

With this example you can define what output format the agent should return to you.
import { Agent, Controller } from "browsernode";
import { ChatOpenAI } from "browsernode/llm";
import { z } from "zod";

// Zod schemas for Post and Posts
const PostSchema = z.object({
	post_title: z.string().describe("The title of the post"),
	post_url: z.string().describe("The URL of the post"),
	num_comments: z.number().describe("Number of comments on the post"),
	hours_since_post: z.number().describe("Hours since the post was created"),
});

const PostsSchema = z.object({
	posts: z.array(PostSchema).describe("Array of posts from Hacker News"),
});

type Post = z.infer<typeof PostSchema>;
type Posts = z.infer<typeof PostsSchema>;

async function main() {
	// Check for required environment variable
	if (!process.env.OPENAI_API_KEY) {
		throw new Error("OPENAI_API_KEY is not set in environment variables");
	}

	// Initialize controller with output model for structured data extraction
	const controller = new Controller([], PostsSchema);

	// Task to extract structured data from Hacker News
	const task = "Go to hackernews show hn and give me the first 5 posts";

	// Initialize the language model
	const model = new ChatOpenAI({
		model: "gpt-4o",
		apiKey: process.env.OPENAI_API_KEY,
	});

	// Create and run the agent
	const agent = new Agent({
		task: task,
		model: model,
		controller: controller,
	});

	try {
		console.log("🚀 Starting agent to extract Hacker News posts...\n");

		const history = await agent.run();

		// Extract the final result from the agent history
		const result = history.finalResult();

		if (result) {
			// Parse the structured result using Zod
			const parsed: Posts = PostsSchema.parse(JSON.parse(result));

			console.log("🎯 Extracted Posts from Hacker News Show HN:\n");

			// Display each post with formatting
			for (const [index, post] of parsed.posts.entries()) {
				console.log(`\n${index + 1}. --------------------------------`);
				console.log(`Title:            ${post.post_title}`);
				console.log(`URL:              ${post.post_url}`);
				console.log(`Comments:         ${post.num_comments}`);
				console.log(`Hours since post: ${post.hours_since_post}`);
			}

			console.log("\n✅ Successfully extracted structured data!");
		} else {
			console.log("❌ No result returned from agent");
		}
	} catch (error) {
		console.error("💥 Error running agent:", error);

		// If it's a Zod validation error, provide more details
		if (error instanceof z.ZodError) {
			console.error("Validation errors:", error.errors);
		}
	}
}

// Run the main function
main().catch(console.error);