Scaling up

The local dendrite browser is great for development, but if you want to start scaling up you’ll need to use the RemoteDendriteBrowser.

With this class you script is ran remotely in the cloud.

Right now we only support Browserbase for hosting browsers, so you’ll need to create an account at Browserbase.

Get recipe

In the example below we’ll use DendriteRemoteBrowser to find suitable recipes on a Swedish cooking website.

The goal is to be create a function like this, that can be called by a cooking AI agent:

recipe = find_recipe(
    "tacos", 
    "Get a vegetarian recipe and that takes less than 30 mins to make"
)
print(recipe)

Which prints:

Tacos with Beans and Crispy Grilled Cheese

Ingredients:
- 1 can of corn (340 g)
- 1 can of mixed cooked beans (380 g)
...

Here is the entire script:

remote_browser.py
import asyncio
import os
import time
from dendrite_python_sdk.dendrite_browser.DendriteRemoteBrowser import (
    DendriteRemoteBrowser,
)
from openai import OpenAI
from openai.types.chat import ChatCompletionUserMessageParam


def ai_request(prompt: str):
    openai = OpenAI()
    messages = [ChatCompletionUserMessageParam(role="user", content=prompt)]
    oai_res = openai.chat.completions.create(messages=messages, model="gpt-4o-mini")
    if oai_res.choices[0].message.content:
        return oai_res.choices[0].message.content
    raise Exception("Failed to get successful response from Open AI.")


async def find_recipe(recipe: str, preferences: str):
    openai_api_key = os.environ.get("OPENAI_API_KEY", "")
    anthropic_api_key = os.environ.get("ANTHROPIC_API_KEY", "")
    dendrite_api_key = os.environ.get("DENDRITE_API_KEY", "")
    browserbase_api_key = os.environ.get("BROWSERBASE_API_KEY", "")

    start_time = time.time()
    dendrite = DendriteRemoteBrowser(
        openai_api_key=openai_api_key,
        anthropic_api_key=anthropic_api_key,
        dendrite_api_key=dendrite_api_key,
        browserbase_api_key=browserbase_api_key,
    )
    page = await dendrite.goto("https://www.ica.se/recept/")

    close_cookies_button = await page.get_element(
        "The reject cookies button", use_cache=False
    )
    if close_cookies_button:
        print("close_cookies_button: ", close_cookies_button.locator)
        await close_cookies_button.click()

    search_bar = await page.get_element(
        "The search bar for searching recipes with placeholder sök ingrediens etc",
        use_cache=False,
    )
    await search_bar.fill(recipe)
    await page.keyboard.press("Enter")

    await page.wait_for("Wait for the recipies to be loaded")
    await page.scroll_to_bottom()
    recipes_res = await page.extract(
        "Get all the recipes on the page and return and array of dicts like this {{name: str, time_to_make: str, url_to_recipe: str}}"
    )

    print("recipes_res.return_data: ", recipes_res.return_data)

    find_recipe_prompt = f"""Here are some recipes:
    
    {recipes_res.return_data}
    
    Please output the url of the recipe that best suits these food preferences: {preferences}. 
    
    Important: You output should consist of only one valid URL, nothing else, pick the one that best suits my preferences."""

    url = ai_request(find_recipe_prompt)
    page = await dendrite.goto(url)
    res = await page.ask(
        "Please output a nice, readable string containing the page's recipe that contains a header for ingredients and one for the steps in English.",
        str,
    )

    generated_recipe = res.return_data
    print(
        f"Find recipe took: {time.time() - start_time}. Here is the recipe:\n\n{generated_recipe}"
    )
    return generated_recipe


asyncio.run(
    find_recipe(
        "tacos", "I am vegetarian and I want to cook something in less than 30 mins"
    )
)