LangGraph Workflow Starter
Run a stateful approval workflow with the MIT-licensed LangGraph 1.2.18 OSS library and SQLite checkpoints on Ubuntu 24.04 x86_64. Software Sushi supplies an authenticated local JSON API, client, service configuration and a synthetic CSV workflow. There is no browser UI. LangSmith Server, Studio and commercial control-plane features are not included. The upstream projects do not endorse this image.
Start with a t3.small instance (2 GiB RAM) and a 16 GiB root volume. Larger workflows may need more memory, storage and application changes. No GPU or model weights are included. Your OpenAI-compatible provider, model access and usage charges are separate. Use synthetic data for the included demonstration.
Connect and check the application
Connect using AWS Systems Manager Session Manager, then become the customer user:
sudo -iu ubuntu
sushi-langgraph health
The API listens on 127.0.0.1:8123. Keep inbound application ports closed. A browser opening this address will not display a UI. The client reads the per-instance bearer token from /home/ubuntu/.config/sushi/langgraph/access.json (mode 0600); it never prints the token. Anyone with access to the ubuntu account can control its workflows. This starter is a single-user service, without tenant isolation.
Configure a model after launch
As an administrator, edit /etc/langgraph/provider.json using sudoedit in a terminal that is not being recorded. Set the three JSON fields base_url, model and api_key to your provider's API base URL (including /v1 when the provider requires it), exact available model ID and API key. Use HTTPS for a remote provider. An OpenAI-compatible local model may use loopback HTTP; the provider demonstration requires a remote HTTPS endpoint. Obtain model access and review the provider's terms before sending data. This starter sends the calculated sum, row count, run ID and input digest to your configured provider; it does not send the original CSV rows.
Keep the file owned by root:ubuntu with mode 0640, and the directory /etc/langgraph with mode 0750. No provider credential is baked into the image. The service reads the file for each proposal, so a provider change needs no restart. Do not place API keys in shell arguments, environment commands, logs or workflow input. LangSmith tracing is disabled by the supplied service.
The provider and selected model must support OpenAI-compatible JSON-object response mode (response_format: {"type": "json_object"}). The model must return exactly the requested two-field object: action set to publish_report and run_id matching the workflow ID. Markdown fences, explanations, extra keys, duplicate keys and nonfinite JSON numbers are refused. General compatibility with an OpenAI-style endpoint alone does not establish this response contract. A provider error or invalid proposal produces a recoverable failed node (HTTP 503); inspect the configuration and workflow before retrying its failed node.
Run, review, restart and approve a workflow
As ubuntu, choose a new result directory for each run:
bash /opt/sushi/docs/demo.sh start /home/ubuntu/langgraph-results/my-first-run
The tool reads a generated three-row CSV and calculates its sum in code. The model proposes publishing that result. LangGraph pauses before publication. Inspect paused.json in your result directory and the input.csv and tool-result.json under the corresponding run directory printed in the JSON: /home/ubuntu/langgraph-data/runs/RUN_ID/.
After reviewing the proposal, restart the service and explicitly approve:
sudo systemctl restart sushi-langgraph.service
bash /opt/sushi/docs/demo.sh resume /home/ubuntu/langgraph-results/my-first-run
sudo systemctl restart sushi-langgraph.service
bash /opt/sushi/docs/demo.sh read /home/ubuntu/langgraph-results/my-first-run
The final step independently rereads the CSV, calculator receipt and report in a separate Python process. It checks the persisted checkpoint, one calculator call and one publication. Only a successful final read prints SUSHI_CUSTOMER_DEMO_PASSED. Both restart boundaries are checked using the API's startup identity. These are graceful service-restart checks, not a claim of general exactly-once execution for arbitrary external tools or power loss.
For your own bounded integer task:
sushi-langgraph start invoice-review-001 5 17 20
sushi-langgraph read invoice-review-001
sushi-langgraph approve invoice-review-001
Use sushi-langgraph reject invoice-review-001 instead of approve to finish without publishing. Integers are limited to absolute value 1,000,000 and 100 rows per workflow. IDs contain 8–64 ASCII letters, digits or hyphens. Reusing an ID with different input fails; repeated matching approvals return the completed state. The supplied tool can only read its run's CSV and publish its report; it cannot execute arbitrary shell commands or access customer-selected paths. Adapt and review /opt/langgraph/workflow.py to develop other tools.
API and storage
All routes require bearer authentication. GET /health returns service readiness; POST /runs takes run_id and values; GET /runs/ID reads a checkpoint; POST /runs/ID/approve takes the boolean approved; and POST /runs/ID/retry takes an empty JSON object. Use Content-Type: application/json. The supplied client handles authentication without exposing the token. The API serializes requests and supports one local application process.
Checkpoints, input CSVs, tool receipts, action records and results live under /home/ubuntu/langgraph-data. Demo readbacks live under /home/ubuntu/langgraph-results. Both are mode 0700. The service runs as ubuntu with writes restricted to its data directory. The unique local SQLite action record prevents a replayed publication from appending a second action; this protection applies only to the supplied report publisher.
Before backup, stop sushi-langgraph.service, copy the entire data directory (including SQLite WAL/SHM files if present), provider configuration and access file to encrypted storage, then start the service again. Restore a consistent complete backup with the original ownership and permissions. EBS data remains subject to your volume retention and backup policy; terminating an instance may delete its root volume.
Troubleshooting and recovery
sudo systemctl status sushi-langgraph-firstboot.service sushi-langgraph.service
sudo journalctl -u sushi-langgraph.service --since '-10 minutes' --no-pager
HTTP 401 means the client lacks the instance token. HTTP 409 means the saved workflow conflicts with the request. HTTP 503 means the provider is unconfigured, unreachable or returned an invalid proposal. Check provider access and JSON settings, read the workflow, then run sushi-langgraph retry RUN_ID to retry a failed node. Successful earlier nodes remain checkpointed; retries of the proposal node do not rerun the calculator. Do not delete databases to repair a provider error. A rejected workflow needs a new run ID to begin again.
After correcting ownership or configuration, restart the application service. The firstboot unit preserves existing credentials and data on later boots; it refuses unsafe linked paths or changed ownership. For token rotation, stop the service, replace only the token value in the access file with 64 random hex characters using a secure editor, retain mode 0600 and ubuntu:ubuntu ownership, then start the service. Existing workflows remain in the databases.
Original dependency sources and wheels are retained under /opt/langgraph/sources and /opt/langgraph/wheels. Original notices are under /usr/share/doc/langgraph. The installed third-party libraries retain their own licenses. Software Sushi's paid repackaging covers the AMI integration; it does not sell upstream software licenses or include provider subscriptions.