@graphify and graph_fn — Convert Python Functions to Graphs¶
Introduction¶
This document explains how to use the @graphify decorator and the graph_fn function to convert Python functions into executable graphs within the Aethergraph framework. These tools enable you to define, orchestrate, and manage complex workflows as graphs, making it easier to build modular agents and applications. You will also learn how to provide metadata for agents and apps, and how these components interact with the Aethergraph UI.
1. Core APIs¶
The @graphify decorator defines a TaskGraph, where each node must be annotated with @tool. When a TaskGraph is triggered, all execution traces are preserved, and the graph can be resumed automatically if a run_id is provided. Note that direct invocation of subgraphs or nested graphs within a TaskGraph is not supported; instead, use context.spawn_run(...) or other context runner methods to launch nested graphs.
In contrast, @graph_fn offers a more intuitive way to define a graph from a standard Python function. It converts a Python function—typically one that accepts a context parameter—into an executable graph. You can run the resulting graph as you would any async Python function, and you can nest subgraphs using run, async_run, or context.spawn_run(...). However, be aware that concurrency limits may not be enforced if you invoke the graph directly using native Python calls (e.g., await my_fn(...)).
@graphify(name, inputs, outputs, version, ... )
Decorator to define a TaskGraph and optionally register it as an agent or app.
This decorator wraps a Python function as a TaskGraph, enabling it to be executed
as a node-based graph with runtime context, retry policy, and concurrency controls.
It also supports rich metadata registration for agent and app discovery.
Examples:
Basic usage:
@graphify(
name="add_numbers",
inputs=["a", "b"],
outputs=["sum"],
)
async def add_numbers(a: int, b: int):
return {"sum": a + b}
Registering as an agent with metadata:
@graphify(
name="chat_agent",
inputs=["message", "files", "context_refs", "session_id", "user_meta"],
outputs=["response"],
as_agent={
"id": "chatbot",
"title": "Chat Agent",
"description": "Conversational AI agent.",
"mode": "chat_v1",
"icon": "chat",
"tags": ["chat", "nlp"],
},
)
async def chat_agent(...):
...
Registering as an app:
@graphify(
name="summarizer",
inputs=[],
outputs=["summary"],
as_app={
"id": "summarizer-app",
"name": "Text Summarizer",
"description": "Summarizes input text.",
"category": "Productivity",
"tags": ["nlp", "summary"],
},
)
async def summarizer():
...
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
Unique name for the graph function. |
'default_graph'
|
|
inputs
|
List of input parameter names. If |
()
|
|
outputs
|
List of output keys returned by the function. |
None
|
|
version
|
Version string for the graph function (default: "0.1.0"). |
'0.1.0'
|
|
entrypoint
|
bool
|
If True, marks this graph as the main entrypoint for a flow. [Currently unused] |
False
|
flow_id
|
str | None
|
Optional flow identifier for grouping related graphs. |
None
|
tags
|
list[str] | None
|
List of string tags for discovery and categorization. |
None
|
as_agent
|
dict[str, Any] | None
|
Optional dictionary defining agent metadata. Used when running through Aethergraph UI. See additional information below. |
None
|
as_app
|
dict[str, Any] | None
|
Optional dictionary defining app metadata. Used when running through Aethergraph UI. See additional information below. |
None
|
description
|
str | None
|
Optional human-readable description of the graph function. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
TaskGraph |
A decorator that transforms a function into a TaskGraph with the specified configuration. |
Notes
- as_agent and as_app are not needed to define a graph; they are only for registration purposes for use in Aethergraph UI.
- When registering as an agent, the
as_agentdictionary should include at least an "id" key. - When registering as an app, the
as_appdictionary should include at least an "id" key. - The decorated function is a sync function (generate the TaskGraph), despite the underlying
@toolcan be async. - Fields
inputsandoutputsare can be inferred from the function signature if not explicitly provided, but it's recommended to declare them for clarity.
@graph_fn(name, inputs, outputs, version, *, ...)
Decorator to define a graph function and optionally register it as an agent or app.
This decorator wraps a Python function as a GraphFunction, enabling it to be executed
as a node-based graph with runtime context, retry policy, and concurrency controls.
It also supports rich metadata registration for agent and app discovery.
Examples:
Basic usage:
@graph_fn(
name="add_numbers",
inputs=["a", "b"],
outputs=["sum"],
)
async def add_numbers(a: int, b: int):
return {"sum": a + b}
Registering as an agent with metadata:
@graph_fn(
name="chat_agent",
inputs=["message", "files", "context_refs", "session_id", "user_meta"],
outputs=["response"],
as_agent={
"id": "chatbot",
"title": "Chat Agent",
"description": "Conversational AI agent.",
"mode": "chat_v1",
"icon": "chat",
"tags": ["chat", "nlp"],
},
)
async def chat_agent(...):
...
Registering as an app:
@graph_fn(
name="summarizer",
inputs=[],
outputs=["summary"],
as_app={
"id": "summarizer-app",
"name": "Text Summarizer",
"description": "Summarizes input text.",
"category": "Productivity",
"tags": ["nlp", "summary"],
},
)
async def summarizer():
...
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Unique name for the graph function. |
required |
inputs
|
list[str] | None
|
List of input parameter names. If |
None
|
outputs
|
list[str] | None
|
List of output keys returned by the function. |
None
|
version
|
str
|
Version string for the graph function (default: "0.1.0"). |
'0.1.0'
|
entrypoint
|
bool
|
If True, marks this graph as the main entrypoint for a flow. [Currently unused] |
False
|
flow_id
|
str | None
|
Optional flow identifier for grouping related graphs. |
None
|
tags
|
list[str] | None
|
List of string tags for discovery and categorization. |
None
|
as_agent
|
dict[str, Any] | None
|
Optional dictionary defining agent metadata. Used when running through Aethergraph UI. See additional information below. |
None
|
as_app
|
dict[str, Any] | None
|
Optional dictionary defining app metadata. Used when running through Aethergraph UI. See additional information below. |
None
|
description
|
str | None
|
Optional human-readable description of the graph function. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
Callable |
Callable[[Callable], GraphFunction]
|
A decorator that wraps the function as a |
Callable[[Callable], GraphFunction]
|
in the runtime registry, with agent/app metadata if provided. |
Notes
- as_agent and as_app are not needed to define a graph; they are only for registration purposes for use in Aethergraph UI.
- When registering as an agent, the
as_agentdictionary should include at least an "id" key. - When registering as an app, the
as_appdictionary should include at least an "id" key. - The decorated function can be either synchronous or asynchronous.
- Fields
inputsandoutputsare can be inferred from the function signature if not explicitly provided, but it's recommended to declare them for clarity.
2. Agent/App Metadata¶
When using agents with Aethergraph, you must declare the entry graph as either an agent or an app.
An agent is triggered by a Workspace message and requires the following input signature:
@graph_fn(
name="my_agent",
inputs=["message", "files", "context_refs", "session_id", "user_meta"],
# outputs can be arbitrary
as_agent={
id="...",
title="My Agent", # Displayed in the Avatar
mode="chat_v1", # Specifies as a session workspace agent
run_visibility="inline", # "inline" hides run status
memory_level="session", # "user" | "session" | "run", etc.
}
)
You do not need to start the agent manually using run or run_async; the UI will automatically trigger the agent with the following default attributes:
message: The message sent from the UI.files: Attached files from the UI, parsed asFileRef.context_refs: Artifact links from the UI, typically a list of dicts withartifact_id.session_id: Convenient access to the session ID (same ascontext.session_id).user_meta: Currently not in use.
It is recommended to use graph_fn for agents to enable dynamic routing and orchestration. For better UI responsiveness, use context.spawn_run(...) to launch other agents or graphs. You do not need to invoke app graphs from within agents.
An app is a reusable graph listed in the Aethergraph UI. Apps are typically single graphs without direct inputs. If you need to collect inputs, use context.ui_run_channel().ask_text(...) or other ask_* methods to prompt for arguments.
It is recommended to use graphify for apps. The graphify decorator allows all node execution statuses to be displayed in the UI, and the app can be terminated manually.
as_agent meta keys
Bases: TypedDict
Configuration metadata for an agent. Register an agent with as_agent
parameter in @graphify or @graph_fn.
All fields are optional except id in practice; anything omitted gets
reasonable defaults in build_agent_meta.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
Unique identifier for the agent. Defaults to graph name. |
title |
str
|
Display name of the agent. Optional, shown in the UI. |
description |
str
|
Brief description of the agent. Optional, shown in the UI. |
short_description |
str
|
Shorter summary (used in cards). Optional. |
icon_key |
str
|
Icon key used in the UI (e.g. "message-circle"). |
color |
str
|
Accent color token (e.g. "emerald"). |
badge |
str
|
Badge label, e.g. "Chat Agent". |
category |
str
|
Category, e.g. "Core", "R&D Lab", "Infra", "Productivity". |
status |
str
|
"available" | "coming-soon" | "hidden" | "error" | ... |
mode |
str
|
Operational mode. Defaults to "chat_v1" for chat agents. |
session_kind |
str
|
Session type, e.g. "chat". Defaults to "chat". |
flow_id |
str
|
Flow identifier for wiring. Defaults to graph name. |
tags |
list[str]
|
Tags used for search / grouping. |
tool_graphs |
list[str]
|
Related tool graph identifiers. |
features |
list[str]
|
Optional feature bullets for UI. |
run_visibility |
RunVisibility
|
"normal" | "inline" | ... |
run_importance |
RunImportance
|
"normal" | "high" | ... |
memory_level |
Literal['user', 'session', 'run']
|
Memory scope level. |
memory_scope |
str
|
Logical scope, e.g. "session.global", "user.all". |
github_url |
str
|
Optional GitHub link. |
as_app meta keys
Bases: TypedDict
Configuration metadata for an application. Register an app with as_app
parameter in @graphify or @graph_fn.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
Unique identifier for the app. Defaults to graph name. |
name |
str
|
Human-readable name of the app. Defaults to "App for |
badge |
str
|
Short badge or label for the app. Optional, shown in the UI. |
short_description |
str
|
Brief summary of the app's purpose. Optional. |
description |
str
|
Detailed description of the app. Optional. |
category |
str
|
Category, e.g. "Core", "R&D Lab", "Infra", "Productivity". |
status |
str
|
"available" | "coming-soon" | "hidden" | "error" | ... |
icon_key |
str
|
Icon key for the app. |
color |
str
|
Accent color token. |
mode |
str
|
App mode, e.g. "no_input_v1". Defaults to "no_input_v1". |
tags |
list[str]
|
Tags for search / grouping. |
features |
list[str]
|
Notable features for the app. |
run_visibility |
RunVisibility
|
"normal" | "inline" | ... |
run_importance |
RunImportance
|
"normal" | "high" | ... |
flow_id |
str
|
Flow identifier. Defaults to graph name. |
github_url |
str
|
Optional GitHub link. |