Skip to content

AI agent examples

These examples show how agents use Belgie to run JavaScript, TypeScript, and TSX. Pydantic AI uses run_typescript; LangChain uses run_code. Both examples ask the agent to fetch and summarize Hacker News data with TypeScript.

Network access is denied by default. These examples explicitly allow only the hacker-news.firebaseio.com host.

Demonstrates

  • BelgieSandbox with Pydantic AI.
  • BelgieMiddleware with LangChain.
  • Agent-authored complete TypeScript modules with an exported run function.
  • Framework-specific installation and result handling.

Pydantic AI

Install and run the example:

cd examples/ai/pydantic-ai
uv sync
export OPENAI_API_KEY=...
uv run main

The agent is configured with BelgieSandbox(allow_network=True). The complete entrypoint is included from the shipped example:

from pydantic_ai import Agent

from belgie.pydantic_ai import BelgieSandbox

agent = Agent(
    "openai:gpt-5",
    instructions=(
        "You can execute JavaScript, TypeScript, or TSX in a Deno sandbox with the run_typescript tool. "
        "Use it when fetching data or transforming values is easier in JS/TS than in Python."
    ),
    capabilities=[BelgieSandbox(allow_network=True)],
)


def main() -> None:
    result = agent.run_sync(
        "Use run_typescript with a TypeScript belgie.Script module that exports an async run function "
        "to fetch the Hacker News top stories API and summarize the top headline.",
    )
    print(result.output)  # noqa: T201


if __name__ == "__main__":
    main()

The prompt asks the model to export an async run function from a TypeScript module. See examples/ai/pydantic-ai.

LangChain

Install and run the LangChain example:

cd examples/ai/langchain
uv sync
export OPENAI_API_KEY=...
uv run main

The agent uses BelgieMiddleware. The complete entrypoint is included from the shipped example:

from langchain.agents import create_agent

from belgie import RuntimeOptions, RuntimePermissions
from belgie.langchain import BelgieMiddleware

runtime_options = RuntimeOptions(
    permissions=RuntimePermissions(allow_net=["hacker-news.firebaseio.com"]),
)

agent = create_agent(
    model="openai:gpt-5",
    tools=[],
    middleware=[BelgieMiddleware(runtime_options=runtime_options)],
    system_prompt=(
        "You can execute JavaScript, TypeScript, or TSX in a Deno sandbox with the run_code tool. "
        "Use it when fetching data or transforming values is easier in JS/TS than in Python."
    ),
)


def main() -> None:
    result = agent.invoke(
        {
            "messages": [
                (
                    "user",
                    (
                        "Use run_code with a TypeScript belgie.Script module that exports an async run function "
                        "to fetch the Hacker News top stories API and summarize the top headline."
                    ),
                ),
            ],
        },
    )
    print(result["messages"][-1].content)  # noqa: T201


if __name__ == "__main__":
    main()

See examples/ai/langchain.

Render an inline widget

To try inline rendering, ask the agent to call render_widget with a default-export TSX module:

export default function Widget() {
  return <main>Rendered by Belgie</main>;
}

The result is self-contained HTML. It uses the @belgie/vite CLI described in @belgie/vite, not the path-based MCP widget build.

FastAPI generative UI

examples/ui/pydantic-ai puts the same inline rendering flow behind a FastAPI endpoint and a small React SPA. The page accepts a prompt in a textbox, passes it to Pydantic AI, and displays the returned HTML in an isolated iframe.

See also