Skip to content
Anlyon
Esc
↑↓navigate↵open⌘Jpreview
On this page

LangGraph: hosted tools and human approval

Call an Anlyon hosted action from a LangGraph node, keep provider credentials outside the graph, and recover by invocation ID.

LangGraph manages graph execution. Anlyon executes the named external action. As of 2026-09-30, a LangGraph interrupt() runs in your process and does not hold credentials. It does not approve a pending Anlyon invocation.

Prerequisites

Complete the quickstart in a test environment. Define the hosted template action refund-order with charge and amount inputs and require approval. Configure the provider secret using an operator credential outside the graph. The graph runtime needs an Anlyon agent credential with actions:invoke and actions:read. It does not need the provider key or approvals:decide.

The following is a node integration pattern, not a complete persisted graph application. Install anlyon in your application and supply the prepared action. The host application must persist the operation key with the business request before running this node.

import os
from typing import TypedDict
from anlyon import Client


class RefundState(TypedDict):
    charge: str
    amount: int
    operation_key: str
    invocation_id: str
    status: str


def submit_refund(state: RefundState) -> dict[str, str]:
    with Client(api_key=os.environ["ANLYON_AGENT_KEY"]) as agent:
        result = agent.actions.invoke(
            "refund-order",
            {"charge": state["charge"], "amount": state["amount"]},
            idempotency_key=state["operation_key"],
        )
        if result.data is None:
            raise RuntimeError("No invocation returned; recover with the same request identity")
        return {
            "invocation_id": result.data["id"],
            "status": result.data["status"],
        }


def read_refund(state: RefundState) -> dict[str, str]:
    with Client(api_key=os.environ["ANLYON_AGENT_KEY"]) as agent:
        result = agent.actions.invocation(state["invocation_id"])
        if result.data is None:
            raise RuntimeError("Invocation unavailable; do not submit a new refund")
        return {"status": result.data["status"]}

Register these functions as nodes in your StateGraph. Initialize the state from trusted application data, use a durable checkpointer for restart recovery, and persist the returned invocation ID. After submission, return pending work to your application or resume at the read node. Do not repeatedly submit new operations while waiting.

Approval is not completion

Status Application behavior
pending_approval Show the pending review. An authorized person decides in Anlyon
running Read the same invocation later
succeeded For this template action, report the recorded provider HTTP result
unknown Request reconciliation. Do not generate another refund
failed Inspect evidence and use the documented explicit retry path if appropriate
denied or expired Stop. Do not resubmit to bypass the decision

A resume payload such as approved: true is not an Anlyon decision. Authenticate reviewers in the application and keep decision credentials out of the graph. Never let model output supply reviewer authority.

Restarts and interrupts

Check LangGraph’s interrupt documentation for which code runs again when a graph resumes. Keep external writes out of code that runs before an interrupt. Once submitted, prefer reading the saved invocation. If submission was interrupted before its ID was persisted, the same template request and idempotency key recover its current state while the invocation exists.

For a new execution after a confirmed failure, follow explicit retry and resolution, including retryOf. Do not replace an unknown operation’s key to force a new call.

Governed actions

For an action with an adapter or a declaration, pass operation_key and retain effectId. An adapter action takes the adapter’s input schema. Follow governed-effect recovery, not the template invocation resolution path. Anlyon’s current beta is not for critical production workloads.

See framework and architecture choices, approval policies, and idempotency.

Was this page helpful?