parseforge 0.3.0__tar.gz → 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- parseforge-0.3.1/PKG-INFO +199 -0
- parseforge-0.3.1/README.md +95 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/__init__.py +1 -1
- parseforge-0.3.1/parseforge.egg-info/PKG-INFO +199 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/pyproject.toml +1 -1
- parseforge-0.3.0/PKG-INFO +0 -384
- parseforge-0.3.0/README.md +0 -280
- parseforge-0.3.0/parseforge.egg-info/PKG-INFO +0 -384
- {parseforge-0.3.0 → parseforge-0.3.1}/LICENSE +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/MANIFEST.in +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/SPEC.md +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/api.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/cli/__init__.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/cli/config.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/cli/main.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/drift.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/generation.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/integration.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/__init__.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/assemble.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/cache.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/llm.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/prompts.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/prompts.yaml +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/__init__.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/anthropic.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/azure.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/bedrock.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/cerebras.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/cohere.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/deepseek.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/errors.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/fireworks.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/gemini.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/groq.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/mistral.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/models.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/models.yaml +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/moonshot.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/oci.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/openai.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/openrouter.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/perplexity.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/text.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/together.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/vertexai.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/providers/xai.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/naming/resolver.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/paths.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/pipeline.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/promotion.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/sampling/__init__.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/sampling/backends/__init__.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/sampling/backends/netmiko.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/sampling/core.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge/validation.py +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge.egg-info/SOURCES.txt +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge.egg-info/dependency_links.txt +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge.egg-info/entry_points.txt +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge.egg-info/requires.txt +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/parseforge.egg-info/top_level.txt +0 -0
- {parseforge-0.3.0 → parseforge-0.3.1}/setup.cfg +0 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: parseforge
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: LLM-driven pipeline that forges, validates, and promotes TextFSM templates from network CLI output
|
|
5
|
+
Author-email: Tuyen Mathew Duong <tuyen@geekstrident.com>
|
|
6
|
+
Maintainer-email: Tuyen Mathew Duong <tuyen@geekstrident.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Keywords: textfsm,network automation,cli parsing,template generator,ai,llm,netmiko,device output parsing
|
|
9
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Intended Audience :: Information Technology
|
|
12
|
+
Classifier: Intended Audience :: System Administrators
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
19
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
20
|
+
Classifier: Topic :: Text Processing
|
|
21
|
+
Classifier: Topic :: Utilities
|
|
22
|
+
Classifier: Operating System :: OS Independent
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: click>=8.1
|
|
27
|
+
Requires-Dist: PyYAML>=6.0
|
|
28
|
+
Requires-Dist: textfsm>=1.1.0
|
|
29
|
+
Requires-Dist: textfsm-ai>=0.7.1
|
|
30
|
+
Provides-Extra: anthropic
|
|
31
|
+
Requires-Dist: anthropic>=0.40.0; extra == "anthropic"
|
|
32
|
+
Requires-Dist: textfsm-ai[anthropic]>=0.7.1; extra == "anthropic"
|
|
33
|
+
Provides-Extra: deepseek
|
|
34
|
+
Requires-Dist: openai>=1.0.0; extra == "deepseek"
|
|
35
|
+
Requires-Dist: textfsm-ai[deepseek]>=0.7.1; extra == "deepseek"
|
|
36
|
+
Provides-Extra: openai
|
|
37
|
+
Requires-Dist: openai>=1.0.0; extra == "openai"
|
|
38
|
+
Requires-Dist: textfsm-ai[openai]>=0.7.1; extra == "openai"
|
|
39
|
+
Provides-Extra: groq
|
|
40
|
+
Requires-Dist: openai>=1.0.0; extra == "groq"
|
|
41
|
+
Requires-Dist: textfsm-ai[groq]>=0.7.1; extra == "groq"
|
|
42
|
+
Provides-Extra: xai
|
|
43
|
+
Requires-Dist: openai>=1.0.0; extra == "xai"
|
|
44
|
+
Requires-Dist: textfsm-ai[xai]>=0.7.1; extra == "xai"
|
|
45
|
+
Provides-Extra: together
|
|
46
|
+
Requires-Dist: openai>=1.0.0; extra == "together"
|
|
47
|
+
Requires-Dist: textfsm-ai[together]>=0.7.1; extra == "together"
|
|
48
|
+
Provides-Extra: fireworks
|
|
49
|
+
Requires-Dist: openai>=1.0.0; extra == "fireworks"
|
|
50
|
+
Requires-Dist: textfsm-ai[fireworks]>=0.7.1; extra == "fireworks"
|
|
51
|
+
Provides-Extra: perplexity
|
|
52
|
+
Requires-Dist: openai>=1.0.0; extra == "perplexity"
|
|
53
|
+
Requires-Dist: textfsm-ai[perplexity]>=0.7.1; extra == "perplexity"
|
|
54
|
+
Provides-Extra: openrouter
|
|
55
|
+
Requires-Dist: openai>=1.0.0; extra == "openrouter"
|
|
56
|
+
Requires-Dist: textfsm-ai[openrouter]>=0.7.1; extra == "openrouter"
|
|
57
|
+
Provides-Extra: moonshot
|
|
58
|
+
Requires-Dist: openai>=1.0.0; extra == "moonshot"
|
|
59
|
+
Requires-Dist: textfsm-ai[moonshot]>=0.7.1; extra == "moonshot"
|
|
60
|
+
Provides-Extra: cerebras
|
|
61
|
+
Requires-Dist: openai>=1.0.0; extra == "cerebras"
|
|
62
|
+
Requires-Dist: textfsm-ai[cerebras]>=0.7.1; extra == "cerebras"
|
|
63
|
+
Provides-Extra: mistral
|
|
64
|
+
Requires-Dist: mistralai==1.10.0; extra == "mistral"
|
|
65
|
+
Requires-Dist: textfsm-ai[mistral]>=0.7.1; extra == "mistral"
|
|
66
|
+
Provides-Extra: cohere
|
|
67
|
+
Requires-Dist: cohere==5.21.1; extra == "cohere"
|
|
68
|
+
Requires-Dist: textfsm-ai[cohere]>=0.7.1; extra == "cohere"
|
|
69
|
+
Provides-Extra: azure
|
|
70
|
+
Requires-Dist: azure-ai-inference>=1.0.0b9; extra == "azure"
|
|
71
|
+
Requires-Dist: textfsm-ai[azure]>=0.7.1; extra == "azure"
|
|
72
|
+
Provides-Extra: gemini
|
|
73
|
+
Requires-Dist: google-genai>=0.2.0; extra == "gemini"
|
|
74
|
+
Requires-Dist: textfsm-ai[gemini]>=0.7.1; extra == "gemini"
|
|
75
|
+
Provides-Extra: vertexai
|
|
76
|
+
Requires-Dist: google-genai>=0.2.0; extra == "vertexai"
|
|
77
|
+
Requires-Dist: textfsm-ai[vertexai]>=0.7.1; extra == "vertexai"
|
|
78
|
+
Provides-Extra: bedrock
|
|
79
|
+
Requires-Dist: boto3==1.42.97; extra == "bedrock"
|
|
80
|
+
Requires-Dist: textfsm-ai[bedrock]>=0.7.1; extra == "bedrock"
|
|
81
|
+
Provides-Extra: oci
|
|
82
|
+
Requires-Dist: oci==2.182.0; extra == "oci"
|
|
83
|
+
Requires-Dist: textfsm-ai[oci]>=0.7.1; extra == "oci"
|
|
84
|
+
Provides-Extra: sampling
|
|
85
|
+
Requires-Dist: netmiko>=4.0; extra == "sampling"
|
|
86
|
+
Provides-Extra: dev
|
|
87
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
88
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
|
|
89
|
+
Requires-Dist: ruff>=0.4.0; extra == "dev"
|
|
90
|
+
Requires-Dist: black>=24.0.0; extra == "dev"
|
|
91
|
+
Requires-Dist: mypy>=1.10.0; extra == "dev"
|
|
92
|
+
Requires-Dist: anthropic>=0.40.0; extra == "dev"
|
|
93
|
+
Requires-Dist: openai>=1.0.0; extra == "dev"
|
|
94
|
+
Requires-Dist: mistralai==1.10.0; extra == "dev"
|
|
95
|
+
Requires-Dist: cohere==5.21.1; extra == "dev"
|
|
96
|
+
Requires-Dist: azure-ai-inference>=1.0.0b9; extra == "dev"
|
|
97
|
+
Requires-Dist: google-genai>=0.2.0; extra == "dev"
|
|
98
|
+
Requires-Dist: boto3==1.42.97; extra == "dev"
|
|
99
|
+
Requires-Dist: oci==2.182.0; extra == "dev"
|
|
100
|
+
Provides-Extra: release
|
|
101
|
+
Requires-Dist: bump2version; extra == "release"
|
|
102
|
+
Requires-Dist: build; extra == "release"
|
|
103
|
+
Dynamic: license-file
|
|
104
|
+
|
|
105
|
+
# ParseForge
|
|
106
|
+
|
|
107
|
+
LLM-driven pipeline that forges, cross-validates, and promotes [TextFSM](https://github.com/google/textfsm)
|
|
108
|
+
templates from network device CLI output.
|
|
109
|
+
|
|
110
|
+
Full design plan: [SPEC.md](SPEC.md).
|
|
111
|
+
|
|
112
|
+
## Features
|
|
113
|
+
|
|
114
|
+
- **Trial → integration → promotion: a Human-in-the-Loop review workflow,
|
|
115
|
+
not a one-shot generator.** Every LLM-generated template starts as
|
|
116
|
+
unreviewed evidence in `trials/`. `integration` clusters every trial for
|
|
117
|
+
a command by the *output schema* its parsed records actually have, not
|
|
118
|
+
exact template text — a command's output can legitimately vary by
|
|
119
|
+
hardware/firmware, so distinct schemas become separate, independently
|
|
120
|
+
tracked groups instead of one hand-picked "winner." `promotion` then
|
|
121
|
+
auto-promotes any group whose match rate against every known sample
|
|
122
|
+
clears a configurable gate straight into `authoritative/`; anything
|
|
123
|
+
short of that gate is queued for human review instead of silently
|
|
124
|
+
shipped. A human-reviewed promotion is recorded as a named snapshot
|
|
125
|
+
alongside whatever's currently live, never silently overwriting it —
|
|
126
|
+
so review effort goes only where the evidence is actually ambiguous.
|
|
127
|
+
- **Eighteen LLM providers, one interface.** Anthropic, OpenAI, DeepSeek,
|
|
128
|
+
Groq, xAI, Together, Fireworks, Perplexity, OpenRouter, Moonshot,
|
|
129
|
+
Cerebras, Mistral, Cohere, Azure OpenAI, Gemini, Vertex AI, Amazon
|
|
130
|
+
Bedrock, and Oracle Cloud (OCI) — including four with non-standard auth
|
|
131
|
+
(deployment names, GCP Application Default Credentials, AWS's
|
|
132
|
+
credential chain, OCI request-signing) handled transparently. Naming
|
|
133
|
+
and generation can use two different providers in the same trial. See
|
|
134
|
+
[Providers](https://geeks-trident-llc.github.io/parseforge/guides/providers/).
|
|
135
|
+
- **Self-caching cli-name resolution.** A raw CLI command
|
|
136
|
+
(`show interface GE1.1 status`) only ever costs LLM tokens once — it's
|
|
137
|
+
resolved to a canonical, indexed name
|
|
138
|
+
(`show-interface-var1-status`) and cached locally; every later trial for
|
|
139
|
+
that command is a free lookup.
|
|
140
|
+
- **Self-validation, not just "the LLM said so."** Every generated
|
|
141
|
+
template is immediately run against its own sample before being
|
|
142
|
+
recorded as passed — a template that doesn't actually parse the output
|
|
143
|
+
it was generated from never gets a chance to look good on paper.
|
|
144
|
+
- **Drift monitoring.** An authoritative template is periodically checked
|
|
145
|
+
against new production samples; a failing sample feeds back into the
|
|
146
|
+
pipeline as a new trial automatically, closing the loop instead of just
|
|
147
|
+
logging an alert.
|
|
148
|
+
- **CLI and Python API, same underlying calls.** Everything the CLI does
|
|
149
|
+
— `run`, `trial`, `integration`, `promotion` — is one function call in
|
|
150
|
+
Python too. See the
|
|
151
|
+
[Python API guide](https://geeks-trident-llc.github.io/parseforge/guides/python-api/).
|
|
152
|
+
|
|
153
|
+
## Status
|
|
154
|
+
|
|
155
|
+
Early beta. The full pipeline is implemented and tested end to end — naming,
|
|
156
|
+
sampling, generation, self-validation, integration (output-schema group/variant
|
|
157
|
+
clustering), promotion (auto and human-reviewed), and drift monitoring — and
|
|
158
|
+
wired into the CLI. A few things are intentionally not there yet:
|
|
159
|
+
|
|
160
|
+
- **`USER_REVIEWED` promotion has a library entry point but no CLI command**
|
|
161
|
+
(`promotion.promote_user_reviewed()` works today; there's no
|
|
162
|
+
`parseforge promotion --mode user-reviewed` yet). Deferred until real
|
|
163
|
+
human-reviewed cases exist to show what a CLI/config shape for a list of
|
|
164
|
+
case/suffix/gate requests should actually look like, rather than guessing
|
|
165
|
+
ahead of need.
|
|
166
|
+
- **Batch sampling mode** (collect several samples per command before
|
|
167
|
+
generating, SPEC.md §4) is designed but not built — the simpler
|
|
168
|
+
per-command loop mode is the only one implemented.
|
|
169
|
+
- **One sampling connector** (Netmiko/SSH). The CLI's `--connector` registry
|
|
170
|
+
is built to hold more without a redesign, but nothing else is wired in yet.
|
|
171
|
+
|
|
172
|
+
## Installation
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# minimal install, no AI-provider SDK
|
|
176
|
+
pip install parseforge
|
|
177
|
+
|
|
178
|
+
# with a provider extra, e.g. anthropic
|
|
179
|
+
pip install parseforge[anthropic]
|
|
180
|
+
|
|
181
|
+
# local development
|
|
182
|
+
pip install -e ".[dev,sampling]"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
For the full extras list (all eighteen providers, `sampling`, combining
|
|
186
|
+
extras, per-provider `requirements/` files, and the dev/test/release
|
|
187
|
+
setup), see
|
|
188
|
+
[Installation](https://geeks-trident-llc.github.io/parseforge/getting-started/installation/).
|
|
189
|
+
|
|
190
|
+
## Reference
|
|
191
|
+
|
|
192
|
+
- [Documentation site](https://geeks-trident-llc.github.io/parseforge/) ([source](./docs/index.md))
|
|
193
|
+
- [Quickstart](https://geeks-trident-llc.github.io/parseforge/getting-started/quickstart/) — a full walkthrough, from a single lookup to the end-to-end workflow
|
|
194
|
+
- [Providers](https://geeks-trident-llc.github.io/parseforge/guides/providers/) — every provider's extra, auth requirements, and default model
|
|
195
|
+
- [CLI Guide](https://geeks-trident-llc.github.io/parseforge/guides/cli/) — every command, in full
|
|
196
|
+
- [Python API guide](https://geeks-trident-llc.github.io/parseforge/guides/python-api/) — calling parseforge from Python instead of the CLI
|
|
197
|
+
- [API Reference](https://geeks-trident-llc.github.io/parseforge/reference/api/) — every public function/class, by pipeline stage
|
|
198
|
+
- [Changelog](https://geeks-trident-llc.github.io/parseforge/changelog/) — what shipped in each release
|
|
199
|
+
- [SPEC.md](SPEC.md) — full design plan and open questions
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# ParseForge
|
|
2
|
+
|
|
3
|
+
LLM-driven pipeline that forges, cross-validates, and promotes [TextFSM](https://github.com/google/textfsm)
|
|
4
|
+
templates from network device CLI output.
|
|
5
|
+
|
|
6
|
+
Full design plan: [SPEC.md](SPEC.md).
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Trial → integration → promotion: a Human-in-the-Loop review workflow,
|
|
11
|
+
not a one-shot generator.** Every LLM-generated template starts as
|
|
12
|
+
unreviewed evidence in `trials/`. `integration` clusters every trial for
|
|
13
|
+
a command by the *output schema* its parsed records actually have, not
|
|
14
|
+
exact template text — a command's output can legitimately vary by
|
|
15
|
+
hardware/firmware, so distinct schemas become separate, independently
|
|
16
|
+
tracked groups instead of one hand-picked "winner." `promotion` then
|
|
17
|
+
auto-promotes any group whose match rate against every known sample
|
|
18
|
+
clears a configurable gate straight into `authoritative/`; anything
|
|
19
|
+
short of that gate is queued for human review instead of silently
|
|
20
|
+
shipped. A human-reviewed promotion is recorded as a named snapshot
|
|
21
|
+
alongside whatever's currently live, never silently overwriting it —
|
|
22
|
+
so review effort goes only where the evidence is actually ambiguous.
|
|
23
|
+
- **Eighteen LLM providers, one interface.** Anthropic, OpenAI, DeepSeek,
|
|
24
|
+
Groq, xAI, Together, Fireworks, Perplexity, OpenRouter, Moonshot,
|
|
25
|
+
Cerebras, Mistral, Cohere, Azure OpenAI, Gemini, Vertex AI, Amazon
|
|
26
|
+
Bedrock, and Oracle Cloud (OCI) — including four with non-standard auth
|
|
27
|
+
(deployment names, GCP Application Default Credentials, AWS's
|
|
28
|
+
credential chain, OCI request-signing) handled transparently. Naming
|
|
29
|
+
and generation can use two different providers in the same trial. See
|
|
30
|
+
[Providers](https://geeks-trident-llc.github.io/parseforge/guides/providers/).
|
|
31
|
+
- **Self-caching cli-name resolution.** A raw CLI command
|
|
32
|
+
(`show interface GE1.1 status`) only ever costs LLM tokens once — it's
|
|
33
|
+
resolved to a canonical, indexed name
|
|
34
|
+
(`show-interface-var1-status`) and cached locally; every later trial for
|
|
35
|
+
that command is a free lookup.
|
|
36
|
+
- **Self-validation, not just "the LLM said so."** Every generated
|
|
37
|
+
template is immediately run against its own sample before being
|
|
38
|
+
recorded as passed — a template that doesn't actually parse the output
|
|
39
|
+
it was generated from never gets a chance to look good on paper.
|
|
40
|
+
- **Drift monitoring.** An authoritative template is periodically checked
|
|
41
|
+
against new production samples; a failing sample feeds back into the
|
|
42
|
+
pipeline as a new trial automatically, closing the loop instead of just
|
|
43
|
+
logging an alert.
|
|
44
|
+
- **CLI and Python API, same underlying calls.** Everything the CLI does
|
|
45
|
+
— `run`, `trial`, `integration`, `promotion` — is one function call in
|
|
46
|
+
Python too. See the
|
|
47
|
+
[Python API guide](https://geeks-trident-llc.github.io/parseforge/guides/python-api/).
|
|
48
|
+
|
|
49
|
+
## Status
|
|
50
|
+
|
|
51
|
+
Early beta. The full pipeline is implemented and tested end to end — naming,
|
|
52
|
+
sampling, generation, self-validation, integration (output-schema group/variant
|
|
53
|
+
clustering), promotion (auto and human-reviewed), and drift monitoring — and
|
|
54
|
+
wired into the CLI. A few things are intentionally not there yet:
|
|
55
|
+
|
|
56
|
+
- **`USER_REVIEWED` promotion has a library entry point but no CLI command**
|
|
57
|
+
(`promotion.promote_user_reviewed()` works today; there's no
|
|
58
|
+
`parseforge promotion --mode user-reviewed` yet). Deferred until real
|
|
59
|
+
human-reviewed cases exist to show what a CLI/config shape for a list of
|
|
60
|
+
case/suffix/gate requests should actually look like, rather than guessing
|
|
61
|
+
ahead of need.
|
|
62
|
+
- **Batch sampling mode** (collect several samples per command before
|
|
63
|
+
generating, SPEC.md §4) is designed but not built — the simpler
|
|
64
|
+
per-command loop mode is the only one implemented.
|
|
65
|
+
- **One sampling connector** (Netmiko/SSH). The CLI's `--connector` registry
|
|
66
|
+
is built to hold more without a redesign, but nothing else is wired in yet.
|
|
67
|
+
|
|
68
|
+
## Installation
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# minimal install, no AI-provider SDK
|
|
72
|
+
pip install parseforge
|
|
73
|
+
|
|
74
|
+
# with a provider extra, e.g. anthropic
|
|
75
|
+
pip install parseforge[anthropic]
|
|
76
|
+
|
|
77
|
+
# local development
|
|
78
|
+
pip install -e ".[dev,sampling]"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
For the full extras list (all eighteen providers, `sampling`, combining
|
|
82
|
+
extras, per-provider `requirements/` files, and the dev/test/release
|
|
83
|
+
setup), see
|
|
84
|
+
[Installation](https://geeks-trident-llc.github.io/parseforge/getting-started/installation/).
|
|
85
|
+
|
|
86
|
+
## Reference
|
|
87
|
+
|
|
88
|
+
- [Documentation site](https://geeks-trident-llc.github.io/parseforge/) ([source](./docs/index.md))
|
|
89
|
+
- [Quickstart](https://geeks-trident-llc.github.io/parseforge/getting-started/quickstart/) — a full walkthrough, from a single lookup to the end-to-end workflow
|
|
90
|
+
- [Providers](https://geeks-trident-llc.github.io/parseforge/guides/providers/) — every provider's extra, auth requirements, and default model
|
|
91
|
+
- [CLI Guide](https://geeks-trident-llc.github.io/parseforge/guides/cli/) — every command, in full
|
|
92
|
+
- [Python API guide](https://geeks-trident-llc.github.io/parseforge/guides/python-api/) — calling parseforge from Python instead of the CLI
|
|
93
|
+
- [API Reference](https://geeks-trident-llc.github.io/parseforge/reference/api/) — every public function/class, by pipeline stage
|
|
94
|
+
- [Changelog](https://geeks-trident-llc.github.io/parseforge/changelog/) — what shipped in each release
|
|
95
|
+
- [SPEC.md](SPEC.md) — full design plan and open questions
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: parseforge
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: LLM-driven pipeline that forges, validates, and promotes TextFSM templates from network CLI output
|
|
5
|
+
Author-email: Tuyen Mathew Duong <tuyen@geekstrident.com>
|
|
6
|
+
Maintainer-email: Tuyen Mathew Duong <tuyen@geekstrident.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Keywords: textfsm,network automation,cli parsing,template generator,ai,llm,netmiko,device output parsing
|
|
9
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Intended Audience :: Information Technology
|
|
12
|
+
Classifier: Intended Audience :: System Administrators
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
19
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
20
|
+
Classifier: Topic :: Text Processing
|
|
21
|
+
Classifier: Topic :: Utilities
|
|
22
|
+
Classifier: Operating System :: OS Independent
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: click>=8.1
|
|
27
|
+
Requires-Dist: PyYAML>=6.0
|
|
28
|
+
Requires-Dist: textfsm>=1.1.0
|
|
29
|
+
Requires-Dist: textfsm-ai>=0.7.1
|
|
30
|
+
Provides-Extra: anthropic
|
|
31
|
+
Requires-Dist: anthropic>=0.40.0; extra == "anthropic"
|
|
32
|
+
Requires-Dist: textfsm-ai[anthropic]>=0.7.1; extra == "anthropic"
|
|
33
|
+
Provides-Extra: deepseek
|
|
34
|
+
Requires-Dist: openai>=1.0.0; extra == "deepseek"
|
|
35
|
+
Requires-Dist: textfsm-ai[deepseek]>=0.7.1; extra == "deepseek"
|
|
36
|
+
Provides-Extra: openai
|
|
37
|
+
Requires-Dist: openai>=1.0.0; extra == "openai"
|
|
38
|
+
Requires-Dist: textfsm-ai[openai]>=0.7.1; extra == "openai"
|
|
39
|
+
Provides-Extra: groq
|
|
40
|
+
Requires-Dist: openai>=1.0.0; extra == "groq"
|
|
41
|
+
Requires-Dist: textfsm-ai[groq]>=0.7.1; extra == "groq"
|
|
42
|
+
Provides-Extra: xai
|
|
43
|
+
Requires-Dist: openai>=1.0.0; extra == "xai"
|
|
44
|
+
Requires-Dist: textfsm-ai[xai]>=0.7.1; extra == "xai"
|
|
45
|
+
Provides-Extra: together
|
|
46
|
+
Requires-Dist: openai>=1.0.0; extra == "together"
|
|
47
|
+
Requires-Dist: textfsm-ai[together]>=0.7.1; extra == "together"
|
|
48
|
+
Provides-Extra: fireworks
|
|
49
|
+
Requires-Dist: openai>=1.0.0; extra == "fireworks"
|
|
50
|
+
Requires-Dist: textfsm-ai[fireworks]>=0.7.1; extra == "fireworks"
|
|
51
|
+
Provides-Extra: perplexity
|
|
52
|
+
Requires-Dist: openai>=1.0.0; extra == "perplexity"
|
|
53
|
+
Requires-Dist: textfsm-ai[perplexity]>=0.7.1; extra == "perplexity"
|
|
54
|
+
Provides-Extra: openrouter
|
|
55
|
+
Requires-Dist: openai>=1.0.0; extra == "openrouter"
|
|
56
|
+
Requires-Dist: textfsm-ai[openrouter]>=0.7.1; extra == "openrouter"
|
|
57
|
+
Provides-Extra: moonshot
|
|
58
|
+
Requires-Dist: openai>=1.0.0; extra == "moonshot"
|
|
59
|
+
Requires-Dist: textfsm-ai[moonshot]>=0.7.1; extra == "moonshot"
|
|
60
|
+
Provides-Extra: cerebras
|
|
61
|
+
Requires-Dist: openai>=1.0.0; extra == "cerebras"
|
|
62
|
+
Requires-Dist: textfsm-ai[cerebras]>=0.7.1; extra == "cerebras"
|
|
63
|
+
Provides-Extra: mistral
|
|
64
|
+
Requires-Dist: mistralai==1.10.0; extra == "mistral"
|
|
65
|
+
Requires-Dist: textfsm-ai[mistral]>=0.7.1; extra == "mistral"
|
|
66
|
+
Provides-Extra: cohere
|
|
67
|
+
Requires-Dist: cohere==5.21.1; extra == "cohere"
|
|
68
|
+
Requires-Dist: textfsm-ai[cohere]>=0.7.1; extra == "cohere"
|
|
69
|
+
Provides-Extra: azure
|
|
70
|
+
Requires-Dist: azure-ai-inference>=1.0.0b9; extra == "azure"
|
|
71
|
+
Requires-Dist: textfsm-ai[azure]>=0.7.1; extra == "azure"
|
|
72
|
+
Provides-Extra: gemini
|
|
73
|
+
Requires-Dist: google-genai>=0.2.0; extra == "gemini"
|
|
74
|
+
Requires-Dist: textfsm-ai[gemini]>=0.7.1; extra == "gemini"
|
|
75
|
+
Provides-Extra: vertexai
|
|
76
|
+
Requires-Dist: google-genai>=0.2.0; extra == "vertexai"
|
|
77
|
+
Requires-Dist: textfsm-ai[vertexai]>=0.7.1; extra == "vertexai"
|
|
78
|
+
Provides-Extra: bedrock
|
|
79
|
+
Requires-Dist: boto3==1.42.97; extra == "bedrock"
|
|
80
|
+
Requires-Dist: textfsm-ai[bedrock]>=0.7.1; extra == "bedrock"
|
|
81
|
+
Provides-Extra: oci
|
|
82
|
+
Requires-Dist: oci==2.182.0; extra == "oci"
|
|
83
|
+
Requires-Dist: textfsm-ai[oci]>=0.7.1; extra == "oci"
|
|
84
|
+
Provides-Extra: sampling
|
|
85
|
+
Requires-Dist: netmiko>=4.0; extra == "sampling"
|
|
86
|
+
Provides-Extra: dev
|
|
87
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
88
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
|
|
89
|
+
Requires-Dist: ruff>=0.4.0; extra == "dev"
|
|
90
|
+
Requires-Dist: black>=24.0.0; extra == "dev"
|
|
91
|
+
Requires-Dist: mypy>=1.10.0; extra == "dev"
|
|
92
|
+
Requires-Dist: anthropic>=0.40.0; extra == "dev"
|
|
93
|
+
Requires-Dist: openai>=1.0.0; extra == "dev"
|
|
94
|
+
Requires-Dist: mistralai==1.10.0; extra == "dev"
|
|
95
|
+
Requires-Dist: cohere==5.21.1; extra == "dev"
|
|
96
|
+
Requires-Dist: azure-ai-inference>=1.0.0b9; extra == "dev"
|
|
97
|
+
Requires-Dist: google-genai>=0.2.0; extra == "dev"
|
|
98
|
+
Requires-Dist: boto3==1.42.97; extra == "dev"
|
|
99
|
+
Requires-Dist: oci==2.182.0; extra == "dev"
|
|
100
|
+
Provides-Extra: release
|
|
101
|
+
Requires-Dist: bump2version; extra == "release"
|
|
102
|
+
Requires-Dist: build; extra == "release"
|
|
103
|
+
Dynamic: license-file
|
|
104
|
+
|
|
105
|
+
# ParseForge
|
|
106
|
+
|
|
107
|
+
LLM-driven pipeline that forges, cross-validates, and promotes [TextFSM](https://github.com/google/textfsm)
|
|
108
|
+
templates from network device CLI output.
|
|
109
|
+
|
|
110
|
+
Full design plan: [SPEC.md](SPEC.md).
|
|
111
|
+
|
|
112
|
+
## Features
|
|
113
|
+
|
|
114
|
+
- **Trial → integration → promotion: a Human-in-the-Loop review workflow,
|
|
115
|
+
not a one-shot generator.** Every LLM-generated template starts as
|
|
116
|
+
unreviewed evidence in `trials/`. `integration` clusters every trial for
|
|
117
|
+
a command by the *output schema* its parsed records actually have, not
|
|
118
|
+
exact template text — a command's output can legitimately vary by
|
|
119
|
+
hardware/firmware, so distinct schemas become separate, independently
|
|
120
|
+
tracked groups instead of one hand-picked "winner." `promotion` then
|
|
121
|
+
auto-promotes any group whose match rate against every known sample
|
|
122
|
+
clears a configurable gate straight into `authoritative/`; anything
|
|
123
|
+
short of that gate is queued for human review instead of silently
|
|
124
|
+
shipped. A human-reviewed promotion is recorded as a named snapshot
|
|
125
|
+
alongside whatever's currently live, never silently overwriting it —
|
|
126
|
+
so review effort goes only where the evidence is actually ambiguous.
|
|
127
|
+
- **Eighteen LLM providers, one interface.** Anthropic, OpenAI, DeepSeek,
|
|
128
|
+
Groq, xAI, Together, Fireworks, Perplexity, OpenRouter, Moonshot,
|
|
129
|
+
Cerebras, Mistral, Cohere, Azure OpenAI, Gemini, Vertex AI, Amazon
|
|
130
|
+
Bedrock, and Oracle Cloud (OCI) — including four with non-standard auth
|
|
131
|
+
(deployment names, GCP Application Default Credentials, AWS's
|
|
132
|
+
credential chain, OCI request-signing) handled transparently. Naming
|
|
133
|
+
and generation can use two different providers in the same trial. See
|
|
134
|
+
[Providers](https://geeks-trident-llc.github.io/parseforge/guides/providers/).
|
|
135
|
+
- **Self-caching cli-name resolution.** A raw CLI command
|
|
136
|
+
(`show interface GE1.1 status`) only ever costs LLM tokens once — it's
|
|
137
|
+
resolved to a canonical, indexed name
|
|
138
|
+
(`show-interface-var1-status`) and cached locally; every later trial for
|
|
139
|
+
that command is a free lookup.
|
|
140
|
+
- **Self-validation, not just "the LLM said so."** Every generated
|
|
141
|
+
template is immediately run against its own sample before being
|
|
142
|
+
recorded as passed — a template that doesn't actually parse the output
|
|
143
|
+
it was generated from never gets a chance to look good on paper.
|
|
144
|
+
- **Drift monitoring.** An authoritative template is periodically checked
|
|
145
|
+
against new production samples; a failing sample feeds back into the
|
|
146
|
+
pipeline as a new trial automatically, closing the loop instead of just
|
|
147
|
+
logging an alert.
|
|
148
|
+
- **CLI and Python API, same underlying calls.** Everything the CLI does
|
|
149
|
+
— `run`, `trial`, `integration`, `promotion` — is one function call in
|
|
150
|
+
Python too. See the
|
|
151
|
+
[Python API guide](https://geeks-trident-llc.github.io/parseforge/guides/python-api/).
|
|
152
|
+
|
|
153
|
+
## Status
|
|
154
|
+
|
|
155
|
+
Early beta. The full pipeline is implemented and tested end to end — naming,
|
|
156
|
+
sampling, generation, self-validation, integration (output-schema group/variant
|
|
157
|
+
clustering), promotion (auto and human-reviewed), and drift monitoring — and
|
|
158
|
+
wired into the CLI. A few things are intentionally not there yet:
|
|
159
|
+
|
|
160
|
+
- **`USER_REVIEWED` promotion has a library entry point but no CLI command**
|
|
161
|
+
(`promotion.promote_user_reviewed()` works today; there's no
|
|
162
|
+
`parseforge promotion --mode user-reviewed` yet). Deferred until real
|
|
163
|
+
human-reviewed cases exist to show what a CLI/config shape for a list of
|
|
164
|
+
case/suffix/gate requests should actually look like, rather than guessing
|
|
165
|
+
ahead of need.
|
|
166
|
+
- **Batch sampling mode** (collect several samples per command before
|
|
167
|
+
generating, SPEC.md §4) is designed but not built — the simpler
|
|
168
|
+
per-command loop mode is the only one implemented.
|
|
169
|
+
- **One sampling connector** (Netmiko/SSH). The CLI's `--connector` registry
|
|
170
|
+
is built to hold more without a redesign, but nothing else is wired in yet.
|
|
171
|
+
|
|
172
|
+
## Installation
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# minimal install, no AI-provider SDK
|
|
176
|
+
pip install parseforge
|
|
177
|
+
|
|
178
|
+
# with a provider extra, e.g. anthropic
|
|
179
|
+
pip install parseforge[anthropic]
|
|
180
|
+
|
|
181
|
+
# local development
|
|
182
|
+
pip install -e ".[dev,sampling]"
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
For the full extras list (all eighteen providers, `sampling`, combining
|
|
186
|
+
extras, per-provider `requirements/` files, and the dev/test/release
|
|
187
|
+
setup), see
|
|
188
|
+
[Installation](https://geeks-trident-llc.github.io/parseforge/getting-started/installation/).
|
|
189
|
+
|
|
190
|
+
## Reference
|
|
191
|
+
|
|
192
|
+
- [Documentation site](https://geeks-trident-llc.github.io/parseforge/) ([source](./docs/index.md))
|
|
193
|
+
- [Quickstart](https://geeks-trident-llc.github.io/parseforge/getting-started/quickstart/) — a full walkthrough, from a single lookup to the end-to-end workflow
|
|
194
|
+
- [Providers](https://geeks-trident-llc.github.io/parseforge/guides/providers/) — every provider's extra, auth requirements, and default model
|
|
195
|
+
- [CLI Guide](https://geeks-trident-llc.github.io/parseforge/guides/cli/) — every command, in full
|
|
196
|
+
- [Python API guide](https://geeks-trident-llc.github.io/parseforge/guides/python-api/) — calling parseforge from Python instead of the CLI
|
|
197
|
+
- [API Reference](https://geeks-trident-llc.github.io/parseforge/reference/api/) — every public function/class, by pipeline stage
|
|
198
|
+
- [Changelog](https://geeks-trident-llc.github.io/parseforge/changelog/) — what shipped in each release
|
|
199
|
+
- [SPEC.md](SPEC.md) — full design plan and open questions
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "parseforge"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.1"
|
|
8
8
|
description = "LLM-driven pipeline that forges, validates, and promotes TextFSM templates from network CLI output"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|