AOS CoreDocumentationGetting startedPublicationsDownloads & accessContact

LangGraph

Available in AOS Core 0.2.0-rc14 with the optional langgraph dependencies. LangGraph runs the workflow; AOS authenticates and governs the external action. Only public LangGraph documentation and existing AOS contracts are used.

Run the local checks

Download and verify the wheel using Getting started. From the directory containing that wheel, with Python 3.11–3.14:

python3 -m venv .aos-framework
.aos-framework/bin/python -m pip install --upgrade pip
.aos-framework/bin/python -m pip install './aos_core-0.2.0rc14-py3-none-any.whl[langgraph]'
.aos-framework/bin/aos-evaluate --cli --langgraph --output ./framework-run --port 0 --serve

Use a new output directory on each run. The command starts an isolated control plane, runtime worker and harmless HTTP service. It creates real LangGraph checkpoints, closes and reopens the SQLite checkpointer, and resumes the action. No cloud resources, model API or payment account is used. Local validation disables inherited LangSmith/LangChain tracing and restores the environment afterward. Normal application tracing remains the operator’s responsibility.

Expected results:

Check Expected behavior
Review pause No external action until the workflow is resumed
Resume after reopening checkpoints One successful action, with AOS receipt and runtime evidence
Replay with the same thread and identity Original receipt; no second external effect
Policy changed during review Denied before provider execution
Budget exhausted during review Rejected before provider execution
Provider response lost Unknown outcome; no blind retry
Capability revoked during review Rejected before provider execution

framework.json contains the framework checks and receipt references. evaluation.json also includes the ordinary CLI allowed/denied/unknown checks. There are four total reference effects: two in the ordinary checks and two in the framework checks. A reference effect only advances an in-memory counter. HTTP-request latency is measured; tokens and cost are null because this test does not measure model usage. These are local functional results, not production benchmarks.

Inspect through the console and CLI

  1. Open the console URL printed by the command. Choose Session, enter free-evaluation, and select framework-run/console-token.txt. The token stays in your local environment.
  2. Open Capabilities to inspect the contract. The reference capability is revoked at the end of validation. Connect and approve a separate staging capability to perform new actions.
  3. Open Audit to review decisions. Under Platform > Runtime & Fleets, inspect unknown workloads and use Reconcile evidence. Reconciliation does not repeat the action.
  4. In another terminal, use the AOS_URL, AOS_TENANT_ID and AOS_TOKEN_FILE values printed in WALKTHROUGH.txt, then run:
.aos-framework/bin/aos product capability list
.aos-framework/bin/aos product runtime workloads --status unknown
.aos-framework/bin/aos product execution pending
.aos-framework/bin/aos product audit

Both interfaces inspect the same records. LangGraph drives the workflow pause; Action Reviews records the separate AOS approval. The evaluator uses a distinct reviewer identity. Its private reviewer-token.txt is only for this isolated local validation. Stop the evaluator with Ctrl-C. Keep tokens, checkpoint files and evidence private; remove the output directory when no longer needed.

Add to your application

After registering and approving a capability, use a service identity limited to the required tenant and operations. Configure this existing token through a private file, not graph state.

import os
from pathlib import Path
from langgraph.checkpoint.sqlite import SqliteSaver
from langgraph.types import Command
from aos.integrations.langgraph import build_action_graph
from aos.product_client import ProductClient

client = ProductClient(os.environ['AOS_URL'], os.environ['AOS_TENANT_ID'],
                       Path(os.environ['AOS_TOKEN_FILE']).read_text().strip())
# Checkpoints contain action inputs. Use private local storage.
Path('./private-state').mkdir(mode=0o700, exist_ok=True)
Path('./private-state').chmod(0o700)
with SqliteSaver.from_conn_string('./private-state/workflow.sqlite') as saver:
    graph = build_action_graph(client, checkpointer=saver)
    config = {'configurable': {'thread_id': 'maintenance-request-001'}}
    paused = graph.invoke({'action': {
        'capability_id': os.environ['AOS_CAPABILITY_ID'],
        'operation': 'restart', 'input': {'service': 'staging-service'},
    }}, config)
    # AOS creates a pending exact-request review before the graph pauses.
    print('A different reviewer must approve:', paused['approval_id'])
    input('After that reviewer approves through AOS, press Enter to resume: ')
    # Application consent alone does not grant authority.
    result = graph.invoke(Command(resume={
        'approved': True,
        'action_digest': paused['binding']['action_digest'],
    }), config)
    print(result['result'])

Persist the logical thread ID before starting. On a process restart, reopen the same checkpoint database and use graph.get_state(config) to inspect pending state before sending Command. Use a separate node ID for each distinct action boundary in a larger application. Do not rotate the thread ID, node ID, AOS identity or idempotency key to retry an uncertain action. Scope and protect checkpoint access per tenant and user; the checkpointer is trusted application state. If the workflow is resumed before the AOS reviewer decides, it raises before sending an invocation. After approval, reopen the same checkpoint and call graph.invoke(None, config) to continue that pending node. Never replace an unknown action with a fresh thread just to retry it.

The review reply is consent, not an AOS authority token. AOS capability approvals, current policy, roles and usage budgets still apply. An AOS escalation remains blocked until resolved through AOS’s existing approval process. The adapter does not auto-resolve it or mint delegated authority. The evaluator validates separate requester and reviewer identities; cross-agent delegation remains a separate qualification step. See action approval for UI and CLI steps.

Only action.input, explicit action.context and action.constraints are forwarded. Other graph state, model transcripts, credentials and private context are not automatically forwarded. Explicit inputs are stored in the AOS review and checkpoints: callers must minimize them and control retention. Provider output is not copied to graph results; the result contains status and evidence references.

Recovery and retention

The gateway retains the response for 24 hours, then removes its body and retains a payload-free admission tombstone. A delayed replay gets IDEMPOTENCY_OUTCOME_REQUIRES_REVIEW (CLI exit 4). Server errors and interrupted processing also retain the guard. These cases require inspection of audit, runtime and provider records. The guard prevents re-admission with the same identity and key; it does not establish exactly-once execution in arbitrary external systems.

Back up the idempotency table with the control-plane database. Do not prune its effect tombstones while workflows can still resume. Restoring an older database, changing identity or deliberately choosing a new key can remove duplicate protection. Guarded states require this server version; rollback must retain them and disable new writes until the compatible server is restored. Existing rc11 records are not retroactively protected once already expired or deleted.

Public references: LangGraph interrupts explain why pre-interrupt code can run again; persistence explains checkpointer durability. The implementation uses optional LangGraph 1.2.x and SQLite checkpointer 3.1.x dependencies. External model/IdP qualification, sustained operation and independent security review remain in the release gate.