Write your first AgentApp¶
Welcome back!
In the previous tutorial, you ran Flower’s built-in AgentApp on SuperGrid. Now it’s time to build one of your own. You’ll create a small AgentApp, package it as a Flower App, and run it with a prompt you choose.
If you haven’t already, complete Get started with Flower
Agent first. It will help you install uv
and authenticate your CLI with SuperGrid.
Create the project¶
Start by creating a directory for your new app:
$ mkdir hello-agent
$ cd hello-agent
You’ll create these files:
hello-agent/
├── .gitignore
├── hello_agent/
│ ├── __init__.py
│ └── agent_app.py
└── pyproject.toml
First, add the virtual environment to .gitignore so it isn’t scanned when you
build the Flower App Bundle:
.venv/
Define the AgentApp¶
Create an empty hello_agent/__init__.py, then add the agent logic Flower will
run to hello_agent/agent_app.py:
from flwr.agentapp import AgentApp, AgentSession
from flwr.app import Context
MODEL = "openai/gpt-5.5"
app = AgentApp()
@app.main()
def main(agent: AgentSession, context: Context) -> None:
"""Run the agent once for the configured prompt."""
prompt = context.run_config.get("agent.input")
if not isinstance(prompt, str) or not prompt.strip():
raise ValueError("agent.input must be a non-empty string")
agent.responses.create(
{
"model": MODEL,
"input": prompt,
"stream": True,
}
)
AgentApp.main registers the function Flower calls when the task starts. The
runtime passes two arguments:
agentprovides access to models and connectors;contextprovides the run configuration and persistent run state.
The call to agent.responses.create uses an Open Responses-compatible request
and returns the corresponding response object.
Configure the Flower App¶
Next, create pyproject.toml to tell Flower how to package, configure, and load
your AgentApp:
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "hello-agent"
version = "0.1.0"
description = "My first Flower AgentApp"
license = "Apache-2.0"
requires-python = ">=3.11"
dependencies = ["flwr>=1.33.0,<2.0"]
[tool.hatch.build.targets.wheel]
packages = ["."]
[tool.flwr.app]
publisher = "local"
fab-include = ["hello_agent/**/*.py"]
[tool.flwr.app.config.agent]
input = "Explain why flowers turn toward light."
[tool.flwr.app.components]
agentapp = "hello_agent.agent_app:app"
The agentapp component is an object reference in the form
<module>:<attribute>. Here, Flower imports the app object from
hello_agent/agent_app.py. The nested config.agent.input value becomes the
flattened context.run_config["agent.input"] entry used by the app.
Create the environment¶
Use uv to resolve the dependencies declared in pyproject.toml:
$ uv sync
uv creates a virtual environment in .venv and writes a uv.lock file. You
don’t need to activate the environment: uv run executes commands inside it.
Check the bundle¶
Before sending anything to SuperGrid, build the Flower App Bundle (FAB):
$ uv run flwr build
This validates the configuration and component reference before writing a
.fab file. The FAB contains the app code and metadata that SuperGrid needs to
start the run.
Run the AgentApp¶
Submit the project directory through the supergrid connection:
$ uv run flwr run . supergrid
The default prompt comes from pyproject.toml. Override it for one run with
--run-config:
$ uv run flwr run . supergrid \
--run-config 'agent.input="Describe photosynthesis for a five-year-old."'
Open the printed run ID in the SuperGrid dashboard to inspect the response and run activity.
Make it your own¶
The app currently makes one model request and then exits. Try changing:
MODELto another model available to your SuperGrid account;instructions,reasoning, ormax_output_tokensin the response request; orthe app flow to make several model requests or use the connector loop described in Use connectors.
Each invocation of uv run flwr run . supergrid builds and submits the current
local project, so saved changes are included in the next run.
Final remarks¶
Congratulations, you’ve written and run your first custom AgentApp! 🎉
You now have all the pieces of a Flower Agent project:
an
AgentAppwith a registered main function;an
AgentSessionfor calling runtime-provided capabilities;a
Contextfor reading run configuration; anda
pyproject.tomlthat makes the app discoverable and configurable.
This example deliberately keeps the agent logic small. From here, you can add instructions, make multiple model calls, or give the model a connector that lets it search the web.
Continue with Use connectors to build your first tool-calling loop. To learn how to configure, observe, and stop a run, see Run an AgentApp on SuperGrid. For local development, see Run an AgentApp with a local SuperLink.