Metadata-Version: 2.4
Name: parseforge
Version: 0.3.1
Summary: LLM-driven pipeline that forges, validates, and promotes TextFSM templates from network CLI output
Author-email: Tuyen Mathew Duong <tuyen@geekstrident.com>
Maintainer-email: Tuyen Mathew Duong <tuyen@geekstrident.com>
License: MIT
Keywords: textfsm,network automation,cli parsing,template generator,ai,llm,netmiko,device output parsing
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Code Generators
Classifier: Topic :: Text Processing
Classifier: Topic :: Utilities
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.1
Requires-Dist: PyYAML>=6.0
Requires-Dist: textfsm>=1.1.0
Requires-Dist: textfsm-ai>=0.7.1
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.40.0; extra == "anthropic"
Requires-Dist: textfsm-ai[anthropic]>=0.7.1; extra == "anthropic"
Provides-Extra: deepseek
Requires-Dist: openai>=1.0.0; extra == "deepseek"
Requires-Dist: textfsm-ai[deepseek]>=0.7.1; extra == "deepseek"
Provides-Extra: openai
Requires-Dist: openai>=1.0.0; extra == "openai"
Requires-Dist: textfsm-ai[openai]>=0.7.1; extra == "openai"
Provides-Extra: groq
Requires-Dist: openai>=1.0.0; extra == "groq"
Requires-Dist: textfsm-ai[groq]>=0.7.1; extra == "groq"
Provides-Extra: xai
Requires-Dist: openai>=1.0.0; extra == "xai"
Requires-Dist: textfsm-ai[xai]>=0.7.1; extra == "xai"
Provides-Extra: together
Requires-Dist: openai>=1.0.0; extra == "together"
Requires-Dist: textfsm-ai[together]>=0.7.1; extra == "together"
Provides-Extra: fireworks
Requires-Dist: openai>=1.0.0; extra == "fireworks"
Requires-Dist: textfsm-ai[fireworks]>=0.7.1; extra == "fireworks"
Provides-Extra: perplexity
Requires-Dist: openai>=1.0.0; extra == "perplexity"
Requires-Dist: textfsm-ai[perplexity]>=0.7.1; extra == "perplexity"
Provides-Extra: openrouter
Requires-Dist: openai>=1.0.0; extra == "openrouter"
Requires-Dist: textfsm-ai[openrouter]>=0.7.1; extra == "openrouter"
Provides-Extra: moonshot
Requires-Dist: openai>=1.0.0; extra == "moonshot"
Requires-Dist: textfsm-ai[moonshot]>=0.7.1; extra == "moonshot"
Provides-Extra: cerebras
Requires-Dist: openai>=1.0.0; extra == "cerebras"
Requires-Dist: textfsm-ai[cerebras]>=0.7.1; extra == "cerebras"
Provides-Extra: mistral
Requires-Dist: mistralai==1.10.0; extra == "mistral"
Requires-Dist: textfsm-ai[mistral]>=0.7.1; extra == "mistral"
Provides-Extra: cohere
Requires-Dist: cohere==5.21.1; extra == "cohere"
Requires-Dist: textfsm-ai[cohere]>=0.7.1; extra == "cohere"
Provides-Extra: azure
Requires-Dist: azure-ai-inference>=1.0.0b9; extra == "azure"
Requires-Dist: textfsm-ai[azure]>=0.7.1; extra == "azure"
Provides-Extra: gemini
Requires-Dist: google-genai>=0.2.0; extra == "gemini"
Requires-Dist: textfsm-ai[gemini]>=0.7.1; extra == "gemini"
Provides-Extra: vertexai
Requires-Dist: google-genai>=0.2.0; extra == "vertexai"
Requires-Dist: textfsm-ai[vertexai]>=0.7.1; extra == "vertexai"
Provides-Extra: bedrock
Requires-Dist: boto3==1.42.97; extra == "bedrock"
Requires-Dist: textfsm-ai[bedrock]>=0.7.1; extra == "bedrock"
Provides-Extra: oci
Requires-Dist: oci==2.182.0; extra == "oci"
Requires-Dist: textfsm-ai[oci]>=0.7.1; extra == "oci"
Provides-Extra: sampling
Requires-Dist: netmiko>=4.0; extra == "sampling"
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
Requires-Dist: ruff>=0.4.0; extra == "dev"
Requires-Dist: black>=24.0.0; extra == "dev"
Requires-Dist: mypy>=1.10.0; extra == "dev"
Requires-Dist: anthropic>=0.40.0; extra == "dev"
Requires-Dist: openai>=1.0.0; extra == "dev"
Requires-Dist: mistralai==1.10.0; extra == "dev"
Requires-Dist: cohere==5.21.1; extra == "dev"
Requires-Dist: azure-ai-inference>=1.0.0b9; extra == "dev"
Requires-Dist: google-genai>=0.2.0; extra == "dev"
Requires-Dist: boto3==1.42.97; extra == "dev"
Requires-Dist: oci==2.182.0; extra == "dev"
Provides-Extra: release
Requires-Dist: bump2version; extra == "release"
Requires-Dist: build; extra == "release"
Dynamic: license-file

# ParseForge

LLM-driven pipeline that forges, cross-validates, and promotes [TextFSM](https://github.com/google/textfsm)
templates from network device CLI output.

Full design plan: [SPEC.md](SPEC.md).

## Features

- **Trial → integration → promotion: a Human-in-the-Loop review workflow,
  not a one-shot generator.** Every LLM-generated template starts as
  unreviewed evidence in `trials/`. `integration` clusters every trial for
  a command by the *output schema* its parsed records actually have, not
  exact template text — a command's output can legitimately vary by
  hardware/firmware, so distinct schemas become separate, independently
  tracked groups instead of one hand-picked "winner." `promotion` then
  auto-promotes any group whose match rate against every known sample
  clears a configurable gate straight into `authoritative/`; anything
  short of that gate is queued for human review instead of silently
  shipped. A human-reviewed promotion is recorded as a named snapshot
  alongside whatever's currently live, never silently overwriting it —
  so review effort goes only where the evidence is actually ambiguous.
- **Eighteen LLM providers, one interface.** Anthropic, OpenAI, DeepSeek,
  Groq, xAI, Together, Fireworks, Perplexity, OpenRouter, Moonshot,
  Cerebras, Mistral, Cohere, Azure OpenAI, Gemini, Vertex AI, Amazon
  Bedrock, and Oracle Cloud (OCI) — including four with non-standard auth
  (deployment names, GCP Application Default Credentials, AWS's
  credential chain, OCI request-signing) handled transparently. Naming
  and generation can use two different providers in the same trial. See
  [Providers](https://geeks-trident-llc.github.io/parseforge/guides/providers/).
- **Self-caching cli-name resolution.** A raw CLI command
  (`show interface GE1.1 status`) only ever costs LLM tokens once — it's
  resolved to a canonical, indexed name
  (`show-interface-var1-status`) and cached locally; every later trial for
  that command is a free lookup.
- **Self-validation, not just "the LLM said so."** Every generated
  template is immediately run against its own sample before being
  recorded as passed — a template that doesn't actually parse the output
  it was generated from never gets a chance to look good on paper.
- **Drift monitoring.** An authoritative template is periodically checked
  against new production samples; a failing sample feeds back into the
  pipeline as a new trial automatically, closing the loop instead of just
  logging an alert.
- **CLI and Python API, same underlying calls.** Everything the CLI does
  — `run`, `trial`, `integration`, `promotion` — is one function call in
  Python too. See the
  [Python API guide](https://geeks-trident-llc.github.io/parseforge/guides/python-api/).

## Status

Early beta. The full pipeline is implemented and tested end to end — naming,
sampling, generation, self-validation, integration (output-schema group/variant
clustering), promotion (auto and human-reviewed), and drift monitoring — and
wired into the CLI. A few things are intentionally not there yet:

- **`USER_REVIEWED` promotion has a library entry point but no CLI command**
  (`promotion.promote_user_reviewed()` works today; there's no
  `parseforge promotion --mode user-reviewed` yet). Deferred until real
  human-reviewed cases exist to show what a CLI/config shape for a list of
  case/suffix/gate requests should actually look like, rather than guessing
  ahead of need.
- **Batch sampling mode** (collect several samples per command before
  generating, SPEC.md §4) is designed but not built — the simpler
  per-command loop mode is the only one implemented.
- **One sampling connector** (Netmiko/SSH). The CLI's `--connector` registry
  is built to hold more without a redesign, but nothing else is wired in yet.

## Installation

```bash
# minimal install, no AI-provider SDK
pip install parseforge

# with a provider extra, e.g. anthropic
pip install parseforge[anthropic]

# local development
pip install -e ".[dev,sampling]"
```

For the full extras list (all eighteen providers, `sampling`, combining
extras, per-provider `requirements/` files, and the dev/test/release
setup), see
[Installation](https://geeks-trident-llc.github.io/parseforge/getting-started/installation/).

## Reference

- [Documentation site](https://geeks-trident-llc.github.io/parseforge/) ([source](./docs/index.md))
- [Quickstart](https://geeks-trident-llc.github.io/parseforge/getting-started/quickstart/) — a full walkthrough, from a single lookup to the end-to-end workflow
- [Providers](https://geeks-trident-llc.github.io/parseforge/guides/providers/) — every provider's extra, auth requirements, and default model
- [CLI Guide](https://geeks-trident-llc.github.io/parseforge/guides/cli/) — every command, in full
- [Python API guide](https://geeks-trident-llc.github.io/parseforge/guides/python-api/) — calling parseforge from Python instead of the CLI
- [API Reference](https://geeks-trident-llc.github.io/parseforge/reference/api/) — every public function/class, by pipeline stage
- [Changelog](https://geeks-trident-llc.github.io/parseforge/changelog/) — what shipped in each release
- [SPEC.md](SPEC.md) — full design plan and open questions
