Metadata-Version: 2.4
Name: langgraph-init-cli
Version: 0.1.4
Summary: CLI scaffolder for LangGraph projects
Author: Varsha
License-Expression: MIT
Project-URL: Homepage, https://github.com/varshasathya/langgraph-init-project
Project-URL: Repository, https://github.com/varshasathya/langgraph-init-project
Keywords: langgraph,langchain,cli,scaffolding,agent,python
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Code Generators
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: langgraph>=0.2.0
Requires-Dist: langchain>=0.3.0
Requires-Dist: langsmith>=0.1.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: typer>=0.12.0
Requires-Dist: pytest>=9.0.3
Dynamic: license-file

# langgraph-init-cli

A production-oriented scaffolding CLI for [LangGraph](https://github.com/langchain-ai/langgraph) projects. Generate opinionated project layouts that start simple and scale into a full agentic architecture - with graph orchestration, LLM provider abstraction, prompt versioning, tool registries, evaluation, observability, and LangSmith-ready tracing.

```bash
pip install langgraph-init-cli
langgraph-init my-app --template advanced
```

---

## Why langgraph-init?

Starting a LangGraph project from scratch means a lot of boilerplate: wiring state graphs, organizing nodes, managing prompts, hooking up LangSmith. `langgraph-init` gives you a well-structured starting point so you can skip the scaffolding and focus on the agent logic that matters.

---

## Installation

```bash
pip install langgraph-init-cli
```

Or for a cleaner global CLI experience:

```bash
pipx install langgraph-init-cli
```

---

## Usage

```bash
langgraph-init <project-name> --template <template>
```

**Available templates:**

| Template | Best For |
|---|---|
| `base` | Quick experiments and prototypes |
| `advanced` | Modular team projects with clean graph structure |
| `production` | Full production systems with tooling, observability, and evaluation |

**Example:**

```bash
langgraph-init my-app --template production
cd my-app
cp .env.example .env
pip install -e .
python -m src.app.main
```

---

## Templates

### `base`

A minimal LangGraph starter to get something running fast. No LLM, no config — just the graph fundamentals. Runnable via `src.app.main:run`

```
src/app/
├── state.py    # AppState TypedDict
├── nodes.py    # intake_node, draft_node, output_node
└── main.py     # StateGraph wiring + run()
```

Three nodes (`intake -> draft -> output`), a typed state, and a working `app.invoke()` call. Replace the stub logic with real LLM calls when you're ready.

---

### `advanced`

A modular architecture for teams that want clean structure with a real LLM wired in — without full production overhead.

```
src/app/
├── llm/provider.py           # get_llm() — OpenAI / Anthropic / Google / WatsonX
├── graph/                    # builder, state, edges, constants, registry
├── memory/checkpointer.py    # MemorySaver for in-process conversation persistence
├── nodes/                    # intent_node, processing_node, output_node
├── prompts/versions/         # .txt prompt files loaded by task + version
├── services/prompt_service.py
├── tools/calculator.py       # Pydantic-validated arithmetic tool
└── utils/logger.py           # JSON structured logger
```

- `Names` / `Nodes` / `Tags` pattern for readable graph wiring
- `ChatPromptTemplate` + `get_llm()` in every node - real LLM calls from day one
- Conditional routing with retry logic (`route_after_process`)
- Calculator tool with Pydantic input/output validation
- `MemorySaver` checkpointer wired in - same `thread_id` resumes a conversation

---

### `production`

A complete scaffold intended for real systems. Everything is modular, runnable without external services, and ready to extend.

```
src/app/
├── config.py                 # Settings dataclass — all config from .env
├── llm/provider.py           # get_llm() — OpenAI / Anthropic / Google / WatsonX
├── graph/                    # builder, state, edges (retry + error routing), constants, registry
├── memory/checkpointer.py    # MemorySaver / SqliteSaver / PostgresSaver via MEMORY_BACKEND env var
├── nodes/                    # intent, processing, validation, output, error
├── services/                 # llm_service, prompt_service, tool_service, evaluation_service, versioning_service
├── prompts/versions/         # intent/v1+v2, extraction/v1, validation/v1
├── tools/                    # BaseTool + registry + calculator, retriever, db query, http tools
├── models/                   # ExtractionSchema + WorkflowResult (Pydantic)
├── storage/                  # workflow_store, prompt_store, cache (in-memory singletons)
├── observability/            # metrics counters, @traceable decorator, LangSmith config
├── evaluation/               # field coverage evaluator + confidence scoring formula
└── api/                      # FastAPI-ready /run + /health endpoints
```

- Graph orchestration with `StateGraph`, conditional routing (`complete / retry / error`), and retry cap from config
- `RunnableParallel` for concurrent extraction and analysis in `processing_node`
- Prompt versioning system (`prompts/versions/<task>/v1.txt`, `v2.txt`) with version config in `config.py`
- Full tool framework with `BaseTool`, registry, and four demo tools (calculator, retriever, DB query, HTTP)
- `ExtractionSchema` and `WorkflowResult` Pydantic models - type-safe extraction and serialization
- Evaluation: field coverage + confidence scoring → validation pass/fail → auto retry
- Structured JSON logging, metrics counters, `trace_block()` context manager
- LangSmith integration `@traceable` decorator for LangSmith (environment-driven, safe when disabled)
- In-memory storage singletons (`workflow_store`, `prompt_store`, `cache`) designed to swap for a real DB

**Generated layout:**

```
src/app/
├── main.py
├── config.py
├── graph/
├── nodes/
├── services/
├── tools/
├── prompts/
├── models/
├── storage/
├── utils/
├── observability/
├── evaluation/
└── api/
```

---

## Graph Wiring Pattern

The `advanced` and `production` templates  use a three-concept pattern to keep graph wiring readable and maintainable:

```python
class Names:
    INTENT = "intent"         # Stable node identifiers

class Nodes:
    INTENT = intent_node      # Callable implementations

class Tags:
    COMPLETE = "complete"     # Routing labels for conditional edges
    RETRY = "retry"
    ERROR = "error"
```

This separates string identifiers from executable functions, making edges easy to read and refactor. `constants.py` is always the first file to update when adding a new node.

---

## Understanding the Generated Files

Here's what each file and folder does, and where to make changes when building your own agent.

### `config.py` — App Settings

Centralizes all configuration in a `Settings` dataclass. Every module imports the shared `settings` instance — nothing reads `.env` directly.

```python
from src.app.config import settings

settings.log_level                 # "INFO"
settings.default_prompt_versions   # {"intent": "v2", "extraction": "v1", "validation": "v1"}
settings.max_validation_retries    # 2
settings.langsmith_tracing         # True/False
```
```python
# What's inside:
project_name       # Your app name
environment        # "development" | "production" (from APP_ENV)
log_level          # "INFO" by default (from LOG_LEVEL)
langsmith_tracing  # Toggle LangSmith tracing on/off (from LANGSMITH_TRACING)
langsmith_api_key  # Your LangSmith API key (from LANGSMITH_API_KEY)
default_prompt_versions  # e.g. {"intent": "v2", "extraction": "v1"}
max_validation_retries   # How many times to retry failed validation (default: 2)
```

**What to change here:** your project name,`default_prompt_versions` to activate a new prompt version, `max_validation_retries` for retry behavior. Add any new env-driven fields your agent needs.

---

### `main.py` — Entrypoint

Builds the graph and runs it with `app.invoke()` and a `thread_id` for conversation memory. This is what executes when you run `python -m src.app.main`

```python
sample_state = {
    "input_text": "Please calculate 12 + 7 and validate the answer.",
    "retry_count": 0,
    "messages": [],
    "prompt_versions": settings.default_prompt_versions.copy(),
    "tool_results": {},
}
result = app.invoke(sample_state, config={"configurable": {"thread_id": "session-1"}})
```

**What to change here:** replace `sample_state` with your real input schema.
Swap the `input_text` for whatever your agent actually receives (a user message, a document, an API payload, etc.).
---

### `graph/` — Graph Orchestration

| File | Purpose |
|---|---|
| `builder.py` | Wires nodes and edges into a `StateGraph` - start here to understand the flow |
| `state.py` | `WorkflowState` TypedDict - every field that flows between nodes |
| `edges.py` | Routing functions + `EDGE_MAP` for conditional edges |
| `constants.py` | `Names`, `Nodes`, `Tags` — update this first when adding a new node |
| `registry.py` | `NODE_REGISTRY` dict - loaded by `builder.py` |

**What to change here:** add new nodes in `registry.py`, define new routes in `edges.py`, and expand the state schema in `state.py`.
---

### `nodes/` — Node Implementations

| File | What it does |
|---|---|
| `intent.py` | Step 1: classifies input via `ChatPromptTemplate + LLM` |
| `processing.py` | Step 2: parallel enrichment + tool dispatch |
| `validation.py` | Step 3: scores quality, decides retry or continue |
| `output.py` | Step 4: builds `WorkflowResult`, saves to `workflow_store` |
| `error.py` | Fallback: structured error response |

**What to change here:** this is where most of your agent logic lives. Replace stub LLM calls with real provider clients. The function signature - `(state: WorkflowState) -> WorkflowState` - stays the same.

---

### `services/` — Reusable Logic

Holds logic that multiple nodes share:

| File | What it does |
|---|---|
| `llm_service.py` | `classify_intent` + `parallel_enrich` via `RunnableParallel` |
| `prompt_service.py` | `load_prompt(task, version)` with fallback + access logging |
| `evaluation_service.py` | Coordinates field coverage + confidence scoring |
| `versioning_service.py` | `switch_version()` for runtime prompt switching |
| `tool_service.py` | Dispatches tool calls from the registry |

**What to change here:** replace the keyword-matching stubs in `llm_service.py` with real `get_llm()` calls.

---

### `tools/` — Tool Framework

`BaseTool` contract + `ToolRegistry`. Comes with four demo tools you can run immediately and replace later.

| Tool | What it does |
|---|---|
| `calculator_tool.py` | Safe arithmetic with Pydantic input/output validation |
| `retriever_tool.py` | Stub retriever (returns fixed text) |
| `query_tool.py` | Stub DB query (returns fixed result) |
| `http_tool.py` | Stub HTTP tool (returns fixed response) |

**What to change here:** add your own tools by implementing `BaseTool`, register in `tools/registry.py`, call in `tool_service.py`.Delete the demo tools when you no longer need them.

---

### `prompts/` — Prompt Versioning

Prompts are plain `.txt` files. Edit them directly without touching Python code. Add a `v2.txt` alongside `v1.txt` to iterate safely — the registry falls back to `v1.txt` if a requested version doesn't exist.

```
prompts/versions/
├── intent/
│   ├── v1.txt
│   └── v2.txt
├── extraction/
│   └── v1.txt
└── validation/
    └── v1.txt
```
The prompt service loads the version specified in `config.py` and falls back to `v1` if a version doesn't exist. This lets you iterate on prompts without changing code - just add a new version file and update the config.

**What to change here:** edit the `.txt` files directly. Add new task folders as your agent gains new capabilities.
---

### `observability/` — Logging and Tracing

Structured JSON logging and metrics counters out of the box. Trace decorators make it easy to instrument any function for LangSmith.

- **`metrics.py`** — `metrics.increment("event")` / `metrics.snapshot()` — global counters
- **`langsmith.py`** — `@traceable(name="...")` decorator — sends traces to LangSmith when `LANGSMITH_TRACING=true`

**What to change here:** add custom metrics or extend the trace decorators for new nodes.

---

### `evaluation/` — Output Scoring

Field coverage evaluation and confidence scoring to measure output quality. Feeds the validation node's retry decision.

```
score = (field_coverage × 0.6) + (confidence × 0.4)
is_valid = field_coverage >= 0.5 AND score >= 0.5
```
**What to change here:** expand the scoring rubric to match your domain's definition of a good output.

---

### `storage/` — Persistence Layer

In-memory singletons designed to swap for a real database without changing node code:

| File | What it stores |
|---|---|
| `workflow_store.py` | `WorkflowResult.model_dump()` after each successful run |
| `prompt_store.py` | Which prompt version ran per task per call |
| `cache.py` | Simple key-value cache |

Designed to be swapped for a real database (Postgres, Redis, S3, etc.) without changing node code.

**What to change here:** implement the storage interface for your target database when you're ready to persist results.
---

### `api/` — Optional API Surface

A thin API layer (FastAPI-ready) you can enable if you want to expose the agent as an HTTP service.

FastAPI app with `/run` and `/health` already wired in `routes.py`. Serve it when ready:

```bash
pip install fastapi uvicorn
uvicorn src.app.api.routes:api --reload
```
**What to change here:** add your routes and request/response models here when you're ready to serve the agent over HTTP.

---

## After Generation

Recommended next steps once you have your scaffold:

- Set your `.env` — provider, model, log level, memory backend
- Uncomment the right provider in `pyproject.toml` and run `pip install -e .`
- Replace keyword-matching stubs in `llm_service.py` with `get_llm()` calls
- Update `state.py`, `schema.py`, and `workflow.py` for your domain's data shape
- Add domain-specific tools in `tools/` implementing `BaseTool`
- Add real persistence in `storage/` for your target database
- Set `LANGSMITH_TRACING=true` and add `LANGSMITH_API_KEY` to activate tracing
- Add tests around graph routing and node behavior

---

## Generated `langgraph.json`

All projects include:

```json
{
  "dependencies": ["."],
  "graphs": {
    "<project-name>": "src.app.main:run"
  }
}
```

This keeps the entrypoint consistent and compatible with LangGraph tooling.

---

## Links

- **PyPI:** https://pypi.org/project/langgraph-init-cli/
- **GitHub:** https://github.com/varshasathya/langgraph-init-project
- **LangGraph docs:** https://langchain-ai.github.io/langgraph/
- **LangSmith:** https://smith.langchain.com/

---

## License

MIT
