Skip to content

Latest commit

 

History

History

README.md

Examples

End-to-end demo projects for openarmature. Each is a standalone main.py you can run against any OpenAI-compatible LLM endpoint (OpenAI's public API, vLLM, LM Studio, llama.cpp server, etc.).

Demos

Classify a query with an LLM and route to one of two follow-up nodes. Demonstrates: typed State with three reducer policies, the OpenAIProvider from openarmature.llm, structured output via a Pydantic class (response_schema=ClassificationResponse.parsed as a Classification instance), conditional routing on a parsed field, and a compile-time observer.

Question-answering assistant — classify, then short-answer or research-subgraph, then copy-edit. Demonstrates: conditional edges, SubgraphNode, custom ProjectionStrategy, the merge reducer.

Compare two topics by running the same analysis subgraph on each. Demonstrates: ExplicitMapping for reusing one compiled subgraph at multiple parent sites with disjoint parent fields.

Add observability to a draft → review → finalize pipeline without changing any node code. Demonstrates: attach_observer, NodeEvent, namespace chaining across subgraph boundaries, function-shaped and class-shaped observers, plus the OTelObserver running alongside the plain observer (same hook, different backend).

Question answering against a tiny baked-in document corpus, with two levels of subgraph nesting: outer coordinator → doc-QA subgraph → section-extract subgraph. A depth-aware observer prints the descent and return.

Summarize a batch of news headlines in parallel. Each per-headline run goes through a summarize → classify subgraph wrapped in retry middleware (transient failures don't tank the batch) and timing middleware (per-instance duration captured). Demonstrates: add_fan_out_node with items_field mode, extra_outputs collecting a parallel list, instance_middleware, concurrency cap.

Enrich an article with three independent analyses (summary, sentiment, topic tags) running concurrently. Each analysis is a separate subgraph with its own state schema. The sentiment branch wraps its subgraph in retry middleware; the other two run bare. Demonstrates: add_parallel_branches_node, BranchSpec per branch with input/output projection, heterogeneous branch state schemas, per-branch middleware.

Two independent analyses of a lunar-mission photograph — describe the surface, describe the equipment — using versioned prompt templates and a multimodal user message. Templates load from FilesystemPromptBackend with a primary + fallback chain; both renders are grouped under one observability PromptGroup so a trace UI can render them as one logical unit. Image source switches between ImageSourceURL and ImageSourceInline(base64_data=...) via env var. Demonstrates: PromptManager with composite backends, prompt fetch + render with template variables, PromptGroup + with_active_prompt_group, with_active_prompt nesting, multimodal UserMessage carrying both text and image content blocks.

A lunar-mission planning pipeline that checkpoints after every step, then resumes the saved record under an upgraded state schema. Phase one invokes a v1 graph against MissionPlanStateV1; the SQLiteCheckpointer (JSON mode) writes records to a temp DB. Phase two registers a v1→v2 migration backfilling a new risk_assessment field, builds a v2 graph with one new node, and resumes from the v1 invocation. Demonstrates: SQLiteCheckpointer(serialization="json"), with_checkpointer, save-on-completed-event, State.schema_version, with_state_migration, invoke(resume_invocation=...).

A lunar-mission assistant that calls local Python tools to answer questions mixing fact recall and physics arithmetic. Defines two tools (lookup_mission reading a baked-in record store, compute_delta_v doing a Hohmann transfer), passes them to the model via complete(tools=...), dispatches assistant.tool_calls to the local functions, and feeds the results back as ToolMessage entries. The agent loop is a graph cycle: call_llm → dispatch_tools → call_llm via a conditional edge, with a hard turn cap to prevent runaway loops. Demonstrates: Tool definitions with JSON Schema parameters, complete(tools=...), parsing ToolCall records, ToolMessage(tool_call_id=...) round- trip, multi-turn tool-calling loop as a graph cycle.

Configuration

All demos configure their LLM client via env vars; OpenAI public-API defaults shown:

Env var Default Notes
LLM_BASE_URL https://api.openai.com Host root only — the provider adds the path.
LLM_MODEL gpt-4o-mini Any model the bound endpoint exposes.
LLM_API_KEY (none) Required; pass empty for local servers that don't authenticate.

Running

# From the repo root, install the examples dep group:
uv sync --group examples

# Demo 03 also wants the OTel SDK for its OTelObserver:
uv sync --group examples --all-extras

# Run any demo:
LLM_API_KEY=sk-... uv run python examples/00-hello-world/main.py
LLM_API_KEY=sk-... uv run python examples/01-routing-and-subgraphs/main.py "what year did the moon landing happen"

For a local OpenAI-compatible server (vLLM, LM Studio, llama.cpp, etc.), point LLM_BASE_URL at the host root (e.g. http://localhost:8000) and set LLM_API_KEY to whatever value the server expects (often empty or a placeholder).