Skip to content

@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 as_agent is provided with mode="chat_v1", this must match ["message", "files", "context_refs", "session_id", "user_meta"].

()
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_agent dictionary should include at least an "id" key.
  • When registering as an app, the as_app dictionary should include at least an "id" key.
  • The decorated function is a sync function (generate the TaskGraph), despite the underlying @tool can be async.
  • Fields inputs and outputs are 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 as_agent is provided with mode="chat_v1", this must match ["message", "files", "context_refs", "session_id", "user_meta"].

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 GraphFunction and registers it

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_agent dictionary should include at least an "id" key.
  • When registering as an app, the as_app dictionary should include at least an "id" key.
  • The decorated function can be either synchronous or asynchronous.
  • Fields inputs and outputs are 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 as FileRef.
  • context_refs: Artifact links from the UI, typically a list of dicts with artifact_id.
  • session_id: Convenient access to the session ID (same as context.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.