parseforge 0.2.6__tar.gz → 0.2.9__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.2.6/parseforge.egg-info → parseforge-0.2.9}/PKG-INFO +40 -15
- {parseforge-0.2.6 → parseforge-0.2.9}/README.md +27 -14
- parseforge-0.2.9/parseforge/__init__.py +1 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/cli/config.py +18 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/cli/main.py +222 -19
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/__init__.py +6 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/__init__.py +6 -0
- parseforge-0.2.9/parseforge/naming/providers/azure.py +197 -0
- parseforge-0.2.9/parseforge/naming/providers/cohere.py +173 -0
- parseforge-0.2.9/parseforge/naming/providers/mistral.py +163 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/models.yaml +19 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/pipeline.py +17 -0
- {parseforge-0.2.6 → parseforge-0.2.9/parseforge.egg-info}/PKG-INFO +40 -15
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge.egg-info/SOURCES.txt +3 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge.egg-info/requires.txt +15 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/pyproject.toml +17 -4
- parseforge-0.2.6/parseforge/__init__.py +0 -1
- {parseforge-0.2.6 → parseforge-0.2.9}/LICENSE +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/MANIFEST.in +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/SPEC.md +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/cli/__init__.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/drift.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/generation.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/integration.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/assemble.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/cache.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/llm.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/prompts.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/prompts.yaml +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/anthropic.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/cerebras.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/cost.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/deepseek.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/errors.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/fireworks.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/groq.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/models.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/moonshot.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/openai.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/openrouter.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/perplexity.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/text.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/together.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/providers/xai.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/naming/resolver.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/paths.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/promotion.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/sampling/__init__.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/sampling/backends/__init__.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/sampling/backends/netmiko.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/sampling/core.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge/validation.py +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge.egg-info/dependency_links.txt +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge.egg-info/entry_points.txt +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/parseforge.egg-info/top_level.txt +0 -0
- {parseforge-0.2.6 → parseforge-0.2.9}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: parseforge
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.9
|
|
4
4
|
Summary: LLM-driven pipeline that forges, validates, and promotes TextFSM templates from network CLI output
|
|
5
5
|
Author-email: Tuyen Mathew Duong <tuyen@geekstrident.com>
|
|
6
6
|
Maintainer-email: Tuyen Mathew Duong <tuyen@geekstrident.com>
|
|
@@ -60,6 +60,15 @@ Requires-Dist: textfsm-ai[moonshot]>=0.6.1; extra == "moonshot"
|
|
|
60
60
|
Provides-Extra: cerebras
|
|
61
61
|
Requires-Dist: openai>=1.0.0; extra == "cerebras"
|
|
62
62
|
Requires-Dist: textfsm-ai[cerebras]>=0.6.1; extra == "cerebras"
|
|
63
|
+
Provides-Extra: mistral
|
|
64
|
+
Requires-Dist: mistralai==1.10.0; extra == "mistral"
|
|
65
|
+
Requires-Dist: textfsm-ai[mistral]>=0.6.1; extra == "mistral"
|
|
66
|
+
Provides-Extra: cohere
|
|
67
|
+
Requires-Dist: cohere==5.21.1; extra == "cohere"
|
|
68
|
+
Requires-Dist: textfsm-ai[cohere]>=0.6.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.6.1; extra == "azure"
|
|
63
72
|
Provides-Extra: sampling
|
|
64
73
|
Requires-Dist: netmiko>=4.0; extra == "sampling"
|
|
65
74
|
Provides-Extra: dev
|
|
@@ -70,6 +79,9 @@ Requires-Dist: black>=24.0.0; extra == "dev"
|
|
|
70
79
|
Requires-Dist: mypy>=1.10.0; extra == "dev"
|
|
71
80
|
Requires-Dist: anthropic>=0.40.0; extra == "dev"
|
|
72
81
|
Requires-Dist: openai>=1.0.0; extra == "dev"
|
|
82
|
+
Requires-Dist: mistralai==1.10.0; extra == "dev"
|
|
83
|
+
Requires-Dist: cohere==5.21.1; extra == "dev"
|
|
84
|
+
Requires-Dist: azure-ai-inference>=1.0.0b9; extra == "dev"
|
|
73
85
|
Provides-Extra: release
|
|
74
86
|
Requires-Dist: bump2version; extra == "release"
|
|
75
87
|
Requires-Dist: build; extra == "release"
|
|
@@ -112,11 +124,11 @@ command that's pure local processing (`canonical`/`readable`/`recognizers`,
|
|
|
112
124
|
LLM (`name`, `check --provider`, `run`, `generate-template`, `trial`) needs the
|
|
113
125
|
extra for whichever provider it uses: `anthropic`, `openai`, `deepseek`,
|
|
114
126
|
`groq`, `xai`, `together`, `fireworks`, `perplexity`, `openrouter`,
|
|
115
|
-
`moonshot`, or `
|
|
116
|
-
isn't required, so that's the one most setups
|
|
117
|
-
parseforge[sampling]` adds Netmiko for live device
|
|
118
|
-
as needed, e.g.
|
|
119
|
-
`pip install parseforge[anthropic,openai,deepseek,groq,xai,together,fireworks,perplexity,openrouter,moonshot,cerebras,sampling]`.
|
|
127
|
+
`moonshot`, `cerebras`, `mistral`, `cohere`, or `azure`. `--provider` defaults
|
|
128
|
+
to `anthropic` wherever it isn't required, so that's the one most setups
|
|
129
|
+
need. `pip install parseforge[sampling]` adds Netmiko for live device
|
|
130
|
+
sampling; combine extras as needed, e.g.
|
|
131
|
+
`pip install parseforge[anthropic,openai,deepseek,groq,xai,together,fireworks,perplexity,openrouter,moonshot,cerebras,mistral,cohere,azure,sampling]`.
|
|
120
132
|
|
|
121
133
|
## Development
|
|
122
134
|
|
|
@@ -124,11 +136,13 @@ as needed, e.g.
|
|
|
124
136
|
pip install -e ".[dev,sampling]"
|
|
125
137
|
pytest
|
|
126
138
|
```
|
|
127
|
-
`dev` already includes
|
|
128
|
-
|
|
129
|
-
`
|
|
130
|
-
|
|
131
|
-
|
|
139
|
+
`dev` already includes the `anthropic`, `openai`, `mistralai`, `cohere`, and
|
|
140
|
+
`azure-ai-inference` SDKs (tests exercise all fourteen providers —
|
|
141
|
+
`anthropic`, `openai`, `deepseek`, `groq`, `xai`, `together`, `fireworks`,
|
|
142
|
+
`perplexity`, `openrouter`, `moonshot`, `cerebras` share just the first two
|
|
143
|
+
packages, and `mistral`/`cohere`/`azure` each need their own SDK — and never
|
|
144
|
+
silently skip) — add the specific `,<provider>` extra explicitly only if
|
|
145
|
+
installing outside of `dev`.
|
|
132
146
|
|
|
133
147
|
Linting/formatting/type-checking/docs run through tox instead of extras — see
|
|
134
148
|
`tox.ini` (`tox -e lint`/`format`/`typecheck`/`docs`), each installing its own
|
|
@@ -150,8 +164,14 @@ parseforge name --vendor cisco --family catalyst9200 --os ios-xe --version 17.9.
|
|
|
150
164
|
```
|
|
151
165
|
Still needs an LLM provider on a cache miss — `--provider` defaults to `anthropic`,
|
|
152
166
|
and `--api-key` falls back to that provider's own env var (`ANTHROPIC_API_KEY`/
|
|
153
|
-
`OPENAI_API_KEY`/`DEEPSEEK_API_KEY
|
|
154
|
-
never touches the LLM, so no key is needed at all in that case.
|
|
167
|
+
`OPENAI_API_KEY`/`DEEPSEEK_API_KEY`/etc.). A cache hit (a command already seen
|
|
168
|
+
before) never touches the LLM, so no key is needed at all in that case.
|
|
169
|
+
|
|
170
|
+
`--provider azure` is the one exception to the usual `--api-key`/`--model` shape —
|
|
171
|
+
Azure has no fixed base_url or model catalog, so it also needs `--endpoint`
|
|
172
|
+
(`AZURE_ENDPOINT`), `--api-version` (`AZURE_API_VERSION`), and `--deployment`
|
|
173
|
+
(`AZURE_DEPLOYMENT`, replacing `--model`). Same three options exist on
|
|
174
|
+
`check --provider`, `run`, and `generate-template` below.
|
|
155
175
|
|
|
156
176
|
**`check`** — validate a connector or provider before spending time/tokens on a real
|
|
157
177
|
run. With neither `--env` nor explicit connection flags, prints what a connector needs
|
|
@@ -196,7 +216,10 @@ parseforge run --vendor cisco --family catalyst9200 --os ios-xe --version 17.9.1
|
|
|
196
216
|
`--naming-provider`/`--naming-api-key`/`--naming-model`, defaulting independently
|
|
197
217
|
(`--naming-provider` defaults to `anthropic`; the other two fall back to that
|
|
198
218
|
provider's own env var/default model) — set them explicitly if naming needs a
|
|
199
|
-
different provider than generation.
|
|
219
|
+
different provider than generation. `--provider azure`/`--naming-provider azure`
|
|
220
|
+
each get their own `--endpoint`/`--api-version`/`--deployment` (generation) and
|
|
221
|
+
`--naming-endpoint`/`--naming-api-version`/`--naming-deployment` (naming) — see
|
|
222
|
+
the `name` section above for what they're for.
|
|
200
223
|
|
|
201
224
|
**`init-trial-config`** — write a placeholder `trial.yaml` to fill in, instead of
|
|
202
225
|
writing one by hand:
|
|
@@ -229,7 +252,9 @@ workers: 1
|
|
|
229
252
|
```
|
|
230
253
|
`provider`/`api_key`/`model` are one shared LLM source used for both naming and
|
|
231
254
|
generation. Use the `run` command's separate `--naming-*`/`--generation-*` flags
|
|
232
|
-
instead if a trial actually needs two different providers.
|
|
255
|
+
instead if a trial actually needs two different providers. For `provider: azure`,
|
|
256
|
+
also set `endpoint`/`api_version`/`deployment` (`deployment` replaces `model`) —
|
|
257
|
+
see `parseforge init-trial-config`'s generated placeholder for the exact keys.
|
|
233
258
|
|
|
234
259
|
**`integration`** — rebuild `integration/` for every case under `trials/` (SPEC §5
|
|
235
260
|
step 8):
|
|
@@ -35,11 +35,11 @@ command that's pure local processing (`canonical`/`readable`/`recognizers`,
|
|
|
35
35
|
LLM (`name`, `check --provider`, `run`, `generate-template`, `trial`) needs the
|
|
36
36
|
extra for whichever provider it uses: `anthropic`, `openai`, `deepseek`,
|
|
37
37
|
`groq`, `xai`, `together`, `fireworks`, `perplexity`, `openrouter`,
|
|
38
|
-
`moonshot`, or `
|
|
39
|
-
isn't required, so that's the one most setups
|
|
40
|
-
parseforge[sampling]` adds Netmiko for live device
|
|
41
|
-
as needed, e.g.
|
|
42
|
-
`pip install parseforge[anthropic,openai,deepseek,groq,xai,together,fireworks,perplexity,openrouter,moonshot,cerebras,sampling]`.
|
|
38
|
+
`moonshot`, `cerebras`, `mistral`, `cohere`, or `azure`. `--provider` defaults
|
|
39
|
+
to `anthropic` wherever it isn't required, so that's the one most setups
|
|
40
|
+
need. `pip install parseforge[sampling]` adds Netmiko for live device
|
|
41
|
+
sampling; combine extras as needed, e.g.
|
|
42
|
+
`pip install parseforge[anthropic,openai,deepseek,groq,xai,together,fireworks,perplexity,openrouter,moonshot,cerebras,mistral,cohere,azure,sampling]`.
|
|
43
43
|
|
|
44
44
|
## Development
|
|
45
45
|
|
|
@@ -47,11 +47,13 @@ as needed, e.g.
|
|
|
47
47
|
pip install -e ".[dev,sampling]"
|
|
48
48
|
pytest
|
|
49
49
|
```
|
|
50
|
-
`dev` already includes
|
|
51
|
-
|
|
52
|
-
`
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
`dev` already includes the `anthropic`, `openai`, `mistralai`, `cohere`, and
|
|
51
|
+
`azure-ai-inference` SDKs (tests exercise all fourteen providers —
|
|
52
|
+
`anthropic`, `openai`, `deepseek`, `groq`, `xai`, `together`, `fireworks`,
|
|
53
|
+
`perplexity`, `openrouter`, `moonshot`, `cerebras` share just the first two
|
|
54
|
+
packages, and `mistral`/`cohere`/`azure` each need their own SDK — and never
|
|
55
|
+
silently skip) — add the specific `,<provider>` extra explicitly only if
|
|
56
|
+
installing outside of `dev`.
|
|
55
57
|
|
|
56
58
|
Linting/formatting/type-checking/docs run through tox instead of extras — see
|
|
57
59
|
`tox.ini` (`tox -e lint`/`format`/`typecheck`/`docs`), each installing its own
|
|
@@ -73,8 +75,14 @@ parseforge name --vendor cisco --family catalyst9200 --os ios-xe --version 17.9.
|
|
|
73
75
|
```
|
|
74
76
|
Still needs an LLM provider on a cache miss — `--provider` defaults to `anthropic`,
|
|
75
77
|
and `--api-key` falls back to that provider's own env var (`ANTHROPIC_API_KEY`/
|
|
76
|
-
`OPENAI_API_KEY`/`DEEPSEEK_API_KEY
|
|
77
|
-
never touches the LLM, so no key is needed at all in that case.
|
|
78
|
+
`OPENAI_API_KEY`/`DEEPSEEK_API_KEY`/etc.). A cache hit (a command already seen
|
|
79
|
+
before) never touches the LLM, so no key is needed at all in that case.
|
|
80
|
+
|
|
81
|
+
`--provider azure` is the one exception to the usual `--api-key`/`--model` shape —
|
|
82
|
+
Azure has no fixed base_url or model catalog, so it also needs `--endpoint`
|
|
83
|
+
(`AZURE_ENDPOINT`), `--api-version` (`AZURE_API_VERSION`), and `--deployment`
|
|
84
|
+
(`AZURE_DEPLOYMENT`, replacing `--model`). Same three options exist on
|
|
85
|
+
`check --provider`, `run`, and `generate-template` below.
|
|
78
86
|
|
|
79
87
|
**`check`** — validate a connector or provider before spending time/tokens on a real
|
|
80
88
|
run. With neither `--env` nor explicit connection flags, prints what a connector needs
|
|
@@ -119,7 +127,10 @@ parseforge run --vendor cisco --family catalyst9200 --os ios-xe --version 17.9.1
|
|
|
119
127
|
`--naming-provider`/`--naming-api-key`/`--naming-model`, defaulting independently
|
|
120
128
|
(`--naming-provider` defaults to `anthropic`; the other two fall back to that
|
|
121
129
|
provider's own env var/default model) — set them explicitly if naming needs a
|
|
122
|
-
different provider than generation.
|
|
130
|
+
different provider than generation. `--provider azure`/`--naming-provider azure`
|
|
131
|
+
each get their own `--endpoint`/`--api-version`/`--deployment` (generation) and
|
|
132
|
+
`--naming-endpoint`/`--naming-api-version`/`--naming-deployment` (naming) — see
|
|
133
|
+
the `name` section above for what they're for.
|
|
123
134
|
|
|
124
135
|
**`init-trial-config`** — write a placeholder `trial.yaml` to fill in, instead of
|
|
125
136
|
writing one by hand:
|
|
@@ -152,7 +163,9 @@ workers: 1
|
|
|
152
163
|
```
|
|
153
164
|
`provider`/`api_key`/`model` are one shared LLM source used for both naming and
|
|
154
165
|
generation. Use the `run` command's separate `--naming-*`/`--generation-*` flags
|
|
155
|
-
instead if a trial actually needs two different providers.
|
|
166
|
+
instead if a trial actually needs two different providers. For `provider: azure`,
|
|
167
|
+
also set `endpoint`/`api_version`/`deployment` (`deployment` replaces `model`) —
|
|
168
|
+
see `parseforge init-trial-config`'s generated placeholder for the exact keys.
|
|
156
169
|
|
|
157
170
|
**`integration`** — rebuild `integration/` for every case under `trials/` (SPEC §5
|
|
158
171
|
step 8):
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.9"
|
|
@@ -42,6 +42,14 @@ class TrialConfig:
|
|
|
42
42
|
note: str | None = None
|
|
43
43
|
workers: int = 1
|
|
44
44
|
path: str | None = None
|
|
45
|
+
# Only meaningful for provider: azure — no fixed base_url or model
|
|
46
|
+
# catalog there (see naming/providers/azure.py). endpoint/api_version
|
|
47
|
+
# are ignored by every other provider; deployment replaces the usual
|
|
48
|
+
# "model" concept and is what actually gets sent as the generation
|
|
49
|
+
# model argument (see cli/main.py's trial_cmd).
|
|
50
|
+
endpoint: str | None = None
|
|
51
|
+
api_version: str | None = None
|
|
52
|
+
deployment: str | None = None
|
|
45
53
|
|
|
46
54
|
|
|
47
55
|
@dataclass(frozen=True)
|
|
@@ -57,6 +65,10 @@ class GenerationRequestConfig:
|
|
|
57
65
|
env: str | None = None
|
|
58
66
|
cmdline: str | None = None
|
|
59
67
|
sample_file: str | None = None
|
|
68
|
+
# Only meaningful for provider: azure — see TrialConfig above.
|
|
69
|
+
endpoint: str | None = None
|
|
70
|
+
api_version: str | None = None
|
|
71
|
+
deployment: str | None = None
|
|
60
72
|
|
|
61
73
|
|
|
62
74
|
_TRIAL_REQUIRED = (
|
|
@@ -124,6 +136,9 @@ def load_trial_config(path: Path) -> TrialConfig:
|
|
|
124
136
|
note=raw.get("notes"),
|
|
125
137
|
workers=int(raw.get("workers", 1)),
|
|
126
138
|
path=raw.get("path"),
|
|
139
|
+
endpoint=raw.get("endpoint"),
|
|
140
|
+
api_version=raw.get("api_version"),
|
|
141
|
+
deployment=raw.get("deployment"),
|
|
127
142
|
)
|
|
128
143
|
|
|
129
144
|
|
|
@@ -143,4 +158,7 @@ def load_generation_config(path: Path) -> GenerationRequestConfig:
|
|
|
143
158
|
env=raw.get("env"),
|
|
144
159
|
cmdline=raw.get("cmdline"),
|
|
145
160
|
sample_file=raw.get("sample_file"),
|
|
161
|
+
endpoint=raw.get("endpoint"),
|
|
162
|
+
api_version=raw.get("api_version"),
|
|
163
|
+
deployment=raw.get("deployment"),
|
|
146
164
|
)
|
|
@@ -20,13 +20,17 @@ from parseforge import (
|
|
|
20
20
|
validation,
|
|
21
21
|
)
|
|
22
22
|
from parseforge.cli import config as cli_config
|
|
23
|
+
from parseforge.naming.providers.azure import DEFAULT_API_VERSION
|
|
23
24
|
|
|
24
25
|
_BUILDERS: dict[str, type[naming.RegexBuilder]] = {
|
|
25
26
|
"anthropic": naming.AnthropicRegexBuilder,
|
|
27
|
+
"azure": naming.AzureRegexBuilder,
|
|
26
28
|
"cerebras": naming.CerebrasRegexBuilder,
|
|
29
|
+
"cohere": naming.CohereRegexBuilder,
|
|
27
30
|
"deepseek": naming.DeepSeekRegexBuilder,
|
|
28
31
|
"fireworks": naming.FireworksRegexBuilder,
|
|
29
32
|
"groq": naming.GroqRegexBuilder,
|
|
33
|
+
"mistral": naming.MistralRegexBuilder,
|
|
30
34
|
"moonshot": naming.MoonshotRegexBuilder,
|
|
31
35
|
"openai": naming.OpenAIRegexBuilder,
|
|
32
36
|
"openrouter": naming.OpenRouterRegexBuilder,
|
|
@@ -59,6 +63,13 @@ device_type: <netmiko-device-type>
|
|
|
59
63
|
provider: anthropic
|
|
60
64
|
api_key: <api-key>
|
|
61
65
|
model: <model>
|
|
66
|
+
# For provider: azure only -- no fixed base_url or model catalog there.
|
|
67
|
+
# deployment replaces model above (still keep a model: placeholder value,
|
|
68
|
+
# it's simply ignored); endpoint/api_version default to AZURE_ENDPOINT/
|
|
69
|
+
# AZURE_API_VERSION if omitted.
|
|
70
|
+
# endpoint: <azure-resource-endpoint>
|
|
71
|
+
# api_version: <azure-api-version>
|
|
72
|
+
# deployment: <azure-deployment-name>
|
|
62
73
|
|
|
63
74
|
# --- commands to run (required, at least one) ---
|
|
64
75
|
commands:
|
|
@@ -84,6 +95,10 @@ _GENERATE_TEMPLATE_CONFIG_PLACEHOLDER = """\
|
|
|
84
95
|
provider: anthropic
|
|
85
96
|
api_key: <api-key>
|
|
86
97
|
model: <model>
|
|
98
|
+
# For provider: azure only -- see trial.yaml's placeholder for details.
|
|
99
|
+
# endpoint: <azure-resource-endpoint>
|
|
100
|
+
# api_version: <azure-api-version>
|
|
101
|
+
# deployment: <azure-deployment-name>
|
|
87
102
|
|
|
88
103
|
# --- input: choose exactly one ---
|
|
89
104
|
|
|
@@ -112,13 +127,34 @@ def _write_placeholder_config(out_path: str, force: bool, content: str) -> None:
|
|
|
112
127
|
|
|
113
128
|
|
|
114
129
|
def _build_regex_builder(
|
|
115
|
-
provider: str,
|
|
130
|
+
provider: str,
|
|
131
|
+
api_key: str | None,
|
|
132
|
+
model: str | None,
|
|
133
|
+
endpoint: str | None = None,
|
|
134
|
+
api_version: str | None = None,
|
|
135
|
+
deployment: str | None = None,
|
|
116
136
|
) -> naming.RegexBuilder:
|
|
137
|
+
"""endpoint/api_version/deployment are only meaningful for
|
|
138
|
+
provider="azure" (no fixed base_url or model catalog there — see
|
|
139
|
+
naming/providers/azure.py) — forwarded only when given, so every
|
|
140
|
+
other provider's constructor never sees an unexpected kwarg.
|
|
141
|
+
|
|
142
|
+
When deployment is given, model is *not* forwarded — AzureRegexBuilder
|
|
143
|
+
has no model parameter at all (deployment replaces it), so passing
|
|
144
|
+
both would raise a plain TypeError. This matters in practice: every
|
|
145
|
+
TrialConfig always has a (placeholder) model value, since it's a
|
|
146
|
+
required config key shared by every provider."""
|
|
117
147
|
kwargs: dict[str, str] = {}
|
|
118
148
|
if api_key is not None:
|
|
119
149
|
kwargs["api_key"] = api_key
|
|
120
|
-
if
|
|
150
|
+
if deployment is not None:
|
|
151
|
+
kwargs["deployment"] = deployment
|
|
152
|
+
elif model is not None:
|
|
121
153
|
kwargs["model"] = model
|
|
154
|
+
if endpoint is not None:
|
|
155
|
+
kwargs["endpoint"] = endpoint
|
|
156
|
+
if api_version is not None:
|
|
157
|
+
kwargs["api_version"] = api_version
|
|
122
158
|
return _BUILDERS[provider](**kwargs)
|
|
123
159
|
|
|
124
160
|
|
|
@@ -209,13 +245,32 @@ def main() -> None:
|
|
|
209
245
|
help="Provider API key. Defaults to that provider's own API key environment "
|
|
210
246
|
"variable (ANTHROPIC_API_KEY, OPENAI_API_KEY, DEEPSEEK_API_KEY, GROQ_API_KEY, "
|
|
211
247
|
"XAI_API_KEY, TOGETHER_API_KEY, FIREWORKS_API_KEY, PERPLEXITY_API_KEY, "
|
|
212
|
-
"OPENROUTER_API_KEY, MOONSHOT_API_KEY, CEREBRAS_API_KEY
|
|
213
|
-
"cache miss.",
|
|
248
|
+
"OPENROUTER_API_KEY, MOONSHOT_API_KEY, CEREBRAS_API_KEY, MISTRAL_API_KEY, "
|
|
249
|
+
"COHERE_API_KEY, AZURE_API_KEY); only needed on a cache miss.",
|
|
214
250
|
)
|
|
215
251
|
@click.option(
|
|
216
252
|
"--model",
|
|
217
253
|
default=None,
|
|
218
|
-
help="Defaults to the selected provider's own default model."
|
|
254
|
+
help="Defaults to the selected provider's own default model. Ignored for "
|
|
255
|
+
"--provider azure — use --deployment instead.",
|
|
256
|
+
)
|
|
257
|
+
@click.option(
|
|
258
|
+
"--endpoint",
|
|
259
|
+
default=None,
|
|
260
|
+
help="Azure resource endpoint. Only used by --provider azure; defaults to "
|
|
261
|
+
"AZURE_ENDPOINT.",
|
|
262
|
+
)
|
|
263
|
+
@click.option(
|
|
264
|
+
"--api-version",
|
|
265
|
+
default=None,
|
|
266
|
+
help="Azure API version. Only used by --provider azure; defaults to "
|
|
267
|
+
"AZURE_API_VERSION, then a built-in default.",
|
|
268
|
+
)
|
|
269
|
+
@click.option(
|
|
270
|
+
"--deployment",
|
|
271
|
+
default=None,
|
|
272
|
+
help="Azure deployment name — replaces --model for --provider azure; "
|
|
273
|
+
"defaults to AZURE_DEPLOYMENT.",
|
|
219
274
|
)
|
|
220
275
|
@click.argument("command", nargs=-1, required=True)
|
|
221
276
|
def name_cmd(
|
|
@@ -226,6 +281,9 @@ def name_cmd(
|
|
|
226
281
|
provider: str,
|
|
227
282
|
api_key: str | None,
|
|
228
283
|
model: str | None,
|
|
284
|
+
endpoint: str | None,
|
|
285
|
+
api_version: str | None,
|
|
286
|
+
deployment: str | None,
|
|
229
287
|
command: tuple[str, ...],
|
|
230
288
|
) -> None:
|
|
231
289
|
"""Print the canonical cli-name for a raw CLI COMMAND.
|
|
@@ -234,7 +292,9 @@ def name_cmd(
|
|
|
234
292
|
on a cache miss.
|
|
235
293
|
"""
|
|
236
294
|
context = naming.CliContext(vendor=vendor, family=family, os=os_, version=version)
|
|
237
|
-
builder = _build_regex_builder(
|
|
295
|
+
builder = _build_regex_builder(
|
|
296
|
+
provider, api_key, model, endpoint, api_version, deployment
|
|
297
|
+
)
|
|
238
298
|
click.echo(naming.cli_name(" ".join(command), context, builder=builder))
|
|
239
299
|
|
|
240
300
|
|
|
@@ -272,18 +332,66 @@ def name_cmd(
|
|
|
272
332
|
@click.option(
|
|
273
333
|
"--naming-model",
|
|
274
334
|
default=None,
|
|
275
|
-
help="Defaults to the naming provider's own default model."
|
|
335
|
+
help="Defaults to the naming provider's own default model. Ignored for "
|
|
336
|
+
"--naming-provider azure — use --naming-deployment instead.",
|
|
337
|
+
)
|
|
338
|
+
@click.option(
|
|
339
|
+
"--naming-endpoint",
|
|
340
|
+
default=None,
|
|
341
|
+
help="Azure resource endpoint for naming. Only used by --naming-provider "
|
|
342
|
+
"azure; defaults to AZURE_ENDPOINT.",
|
|
343
|
+
)
|
|
344
|
+
@click.option(
|
|
345
|
+
"--naming-api-version",
|
|
346
|
+
default=None,
|
|
347
|
+
help="Azure API version for naming. Only used by --naming-provider azure; "
|
|
348
|
+
"defaults to AZURE_API_VERSION, then a built-in default.",
|
|
349
|
+
)
|
|
350
|
+
@click.option(
|
|
351
|
+
"--naming-deployment",
|
|
352
|
+
default=None,
|
|
353
|
+
help="Azure deployment name for naming — replaces --naming-model for "
|
|
354
|
+
"--naming-provider azure; defaults to AZURE_DEPLOYMENT.",
|
|
276
355
|
)
|
|
277
356
|
@click.option(
|
|
278
357
|
"--provider",
|
|
279
358
|
required=True,
|
|
280
359
|
help="LLM provider for template generation (textfsm-ai's own registry, "
|
|
281
360
|
'e.g. "anthropic", "openai", "deepseek", "groq", "xai", "together", '
|
|
282
|
-
'"fireworks", "perplexity", "openrouter", "moonshot", "cerebras"
|
|
283
|
-
"uses its own separate
|
|
361
|
+
'"fireworks", "perplexity", "openrouter", "moonshot", "cerebras", '
|
|
362
|
+
'"mistral", "cohere", "azure"). Naming uses its own separate '
|
|
363
|
+
"--naming-provider, not this one.",
|
|
284
364
|
)
|
|
285
365
|
@click.option("--api-key", required=True, help="API key for the generation LLM call.")
|
|
286
|
-
@click.option(
|
|
366
|
+
@click.option(
|
|
367
|
+
"--model",
|
|
368
|
+
required=True,
|
|
369
|
+
help="Model for the generation LLM call. For --provider azure, pass the "
|
|
370
|
+
"deployment name here via --deployment instead — this becomes the "
|
|
371
|
+
"deployment name that's actually sent.",
|
|
372
|
+
)
|
|
373
|
+
@click.option(
|
|
374
|
+
"--endpoint",
|
|
375
|
+
default=None,
|
|
376
|
+
envvar="AZURE_ENDPOINT",
|
|
377
|
+
help="Azure resource endpoint for generation. Only used by --provider "
|
|
378
|
+
"azure; defaults to the AZURE_ENDPOINT environment variable.",
|
|
379
|
+
)
|
|
380
|
+
@click.option(
|
|
381
|
+
"--api-version",
|
|
382
|
+
default=None,
|
|
383
|
+
envvar="AZURE_API_VERSION",
|
|
384
|
+
help="Azure API version for generation. Only used by --provider azure; "
|
|
385
|
+
"defaults to the AZURE_API_VERSION environment variable.",
|
|
386
|
+
)
|
|
387
|
+
@click.option(
|
|
388
|
+
"--deployment",
|
|
389
|
+
default=None,
|
|
390
|
+
envvar="AZURE_DEPLOYMENT",
|
|
391
|
+
help="Azure deployment name for generation — overrides --model for "
|
|
392
|
+
"--provider azure; defaults to the AZURE_DEPLOYMENT environment "
|
|
393
|
+
"variable.",
|
|
394
|
+
)
|
|
287
395
|
@click.option(
|
|
288
396
|
"--store-root",
|
|
289
397
|
default=None,
|
|
@@ -305,9 +413,15 @@ def run_cmd(
|
|
|
305
413
|
naming_provider: str,
|
|
306
414
|
naming_api_key: str | None,
|
|
307
415
|
naming_model: str | None,
|
|
416
|
+
naming_endpoint: str | None,
|
|
417
|
+
naming_api_version: str | None,
|
|
418
|
+
naming_deployment: str | None,
|
|
308
419
|
provider: str,
|
|
309
420
|
api_key: str,
|
|
310
421
|
model: str,
|
|
422
|
+
endpoint: str | None,
|
|
423
|
+
api_version: str | None,
|
|
424
|
+
deployment: str | None,
|
|
311
425
|
store_root: str | None,
|
|
312
426
|
project: str | None,
|
|
313
427
|
email: str | None,
|
|
@@ -332,9 +446,20 @@ def run_cmd(
|
|
|
332
446
|
connection = DeviceConnection(
|
|
333
447
|
host=host, username=username, password=password, device_type=device_type
|
|
334
448
|
)
|
|
335
|
-
naming_builder = _build_regex_builder(
|
|
449
|
+
naming_builder = _build_regex_builder(
|
|
450
|
+
naming_provider,
|
|
451
|
+
naming_api_key,
|
|
452
|
+
naming_model,
|
|
453
|
+
naming_endpoint,
|
|
454
|
+
naming_api_version,
|
|
455
|
+
naming_deployment,
|
|
456
|
+
)
|
|
336
457
|
generation_config = LLMProviderConfig(
|
|
337
|
-
provider=provider,
|
|
458
|
+
provider=provider,
|
|
459
|
+
api_key=api_key,
|
|
460
|
+
model=deployment or model,
|
|
461
|
+
endpoint=endpoint,
|
|
462
|
+
api_version=api_version,
|
|
338
463
|
)
|
|
339
464
|
metadata = TrialMetadata(
|
|
340
465
|
project=project,
|
|
@@ -388,8 +513,17 @@ def _check_connector(
|
|
|
388
513
|
click.echo("OK")
|
|
389
514
|
|
|
390
515
|
|
|
391
|
-
def _check_provider(
|
|
392
|
-
|
|
516
|
+
def _check_provider(
|
|
517
|
+
provider: str,
|
|
518
|
+
api_key: str | None,
|
|
519
|
+
model: str | None,
|
|
520
|
+
endpoint: str | None = None,
|
|
521
|
+
api_version: str | None = None,
|
|
522
|
+
deployment: str | None = None,
|
|
523
|
+
) -> None:
|
|
524
|
+
builder = _build_regex_builder(
|
|
525
|
+
provider, api_key, model, endpoint, api_version, deployment
|
|
526
|
+
)
|
|
393
527
|
context = naming.CliContext(vendor="check", family="check", os="check", version="0")
|
|
394
528
|
try:
|
|
395
529
|
response = builder.build_pattern("show clock", context)
|
|
@@ -422,6 +556,21 @@ def _check_provider(provider: str, api_key: str | None, model: str | None) -> No
|
|
|
422
556
|
)
|
|
423
557
|
@click.option("--api-key", default=None, help="Used for a --provider check.")
|
|
424
558
|
@click.option("--model", default=None, help="Used for a --provider check.")
|
|
559
|
+
@click.option(
|
|
560
|
+
"--endpoint",
|
|
561
|
+
default=None,
|
|
562
|
+
help="Used for a --provider azure check; defaults to AZURE_ENDPOINT.",
|
|
563
|
+
)
|
|
564
|
+
@click.option(
|
|
565
|
+
"--api-version",
|
|
566
|
+
default=None,
|
|
567
|
+
help="Used for a --provider azure check; defaults to AZURE_API_VERSION.",
|
|
568
|
+
)
|
|
569
|
+
@click.option(
|
|
570
|
+
"--deployment",
|
|
571
|
+
default=None,
|
|
572
|
+
help="Used for a --provider azure check; defaults to AZURE_DEPLOYMENT.",
|
|
573
|
+
)
|
|
425
574
|
def check_cmd(
|
|
426
575
|
connector: str | None,
|
|
427
576
|
provider: str | None,
|
|
@@ -433,6 +582,9 @@ def check_cmd(
|
|
|
433
582
|
probe_command: str,
|
|
434
583
|
api_key: str | None,
|
|
435
584
|
model: str | None,
|
|
585
|
+
endpoint: str | None,
|
|
586
|
+
api_version: str | None,
|
|
587
|
+
deployment: str | None,
|
|
436
588
|
) -> None:
|
|
437
589
|
"""Validate a --connector or --provider is reachable, or report what it
|
|
438
590
|
needs. Exactly one of --connector/--provider is required."""
|
|
@@ -444,7 +596,7 @@ def check_cmd(
|
|
|
444
596
|
)
|
|
445
597
|
else:
|
|
446
598
|
assert provider is not None
|
|
447
|
-
_check_provider(provider, api_key, model)
|
|
599
|
+
_check_provider(provider, api_key, model, endpoint, api_version, deployment)
|
|
448
600
|
|
|
449
601
|
|
|
450
602
|
@main.command("init-generate-template-config")
|
|
@@ -489,7 +641,34 @@ def init_generate_template_config_cmd(out_path: str, force: bool) -> None:
|
|
|
489
641
|
help='Generation LLM provider (textfsm-ai\'s own registry), e.g. "anthropic".',
|
|
490
642
|
)
|
|
491
643
|
@click.option("--api-key", default=None)
|
|
492
|
-
@click.option(
|
|
644
|
+
@click.option(
|
|
645
|
+
"--model",
|
|
646
|
+
default=None,
|
|
647
|
+
help="Model for the generation LLM call. For --provider azure, pass the "
|
|
648
|
+
"deployment name via --deployment instead — this becomes the "
|
|
649
|
+
"deployment name that's actually sent.",
|
|
650
|
+
)
|
|
651
|
+
@click.option(
|
|
652
|
+
"--endpoint",
|
|
653
|
+
default=None,
|
|
654
|
+
envvar="AZURE_ENDPOINT",
|
|
655
|
+
help="Azure resource endpoint. Only used by --provider azure; defaults to "
|
|
656
|
+
"the AZURE_ENDPOINT environment variable.",
|
|
657
|
+
)
|
|
658
|
+
@click.option(
|
|
659
|
+
"--api-version",
|
|
660
|
+
default=None,
|
|
661
|
+
envvar="AZURE_API_VERSION",
|
|
662
|
+
help="Azure API version. Only used by --provider azure; defaults to the "
|
|
663
|
+
"AZURE_API_VERSION environment variable.",
|
|
664
|
+
)
|
|
665
|
+
@click.option(
|
|
666
|
+
"--deployment",
|
|
667
|
+
default=None,
|
|
668
|
+
envvar="AZURE_DEPLOYMENT",
|
|
669
|
+
help="Azure deployment name — overrides --model for --provider azure; "
|
|
670
|
+
"defaults to the AZURE_DEPLOYMENT environment variable.",
|
|
671
|
+
)
|
|
493
672
|
@click.option(
|
|
494
673
|
"--out",
|
|
495
674
|
"out_dir",
|
|
@@ -510,6 +689,9 @@ def generate_template_cmd(
|
|
|
510
689
|
provider: str | None,
|
|
511
690
|
api_key: str | None,
|
|
512
691
|
model: str | None,
|
|
692
|
+
endpoint: str | None,
|
|
693
|
+
api_version: str | None,
|
|
694
|
+
deployment: str | None,
|
|
513
695
|
out_dir: str | None,
|
|
514
696
|
) -> None:
|
|
515
697
|
"""One-shot template generation — no trial persisted under trials/.
|
|
@@ -530,6 +712,9 @@ def generate_template_cmd(
|
|
|
530
712
|
provider = provider or cfg.provider
|
|
531
713
|
api_key = api_key or cfg.api_key
|
|
532
714
|
model = model or cfg.model
|
|
715
|
+
endpoint = endpoint or cfg.endpoint
|
|
716
|
+
api_version = api_version or cfg.api_version
|
|
717
|
+
deployment = deployment or cfg.deployment
|
|
533
718
|
|
|
534
719
|
if not provider or not model or not api_key:
|
|
535
720
|
raise click.UsageError(
|
|
@@ -549,7 +734,14 @@ def generate_template_cmd(
|
|
|
549
734
|
"or --host/--username/--password/--device-type), or --config"
|
|
550
735
|
)
|
|
551
736
|
|
|
552
|
-
result = generation.generate(
|
|
737
|
+
result = generation.generate(
|
|
738
|
+
sample_text,
|
|
739
|
+
provider,
|
|
740
|
+
api_key,
|
|
741
|
+
deployment or model,
|
|
742
|
+
endpoint=endpoint or "",
|
|
743
|
+
api_version=api_version or DEFAULT_API_VERSION,
|
|
744
|
+
)
|
|
553
745
|
if not result.ready:
|
|
554
746
|
raise click.ClickException(f"generation not ready: {result.reason}")
|
|
555
747
|
|
|
@@ -682,9 +874,20 @@ def trial_cmd(config_path: str, store_root_opt: str | None) -> None:
|
|
|
682
874
|
password=cfg.password,
|
|
683
875
|
device_type=cfg.device_type,
|
|
684
876
|
)
|
|
685
|
-
naming_builder = _build_regex_builder(
|
|
877
|
+
naming_builder = _build_regex_builder(
|
|
878
|
+
cfg.provider,
|
|
879
|
+
cfg.api_key,
|
|
880
|
+
cfg.model,
|
|
881
|
+
cfg.endpoint,
|
|
882
|
+
cfg.api_version,
|
|
883
|
+
cfg.deployment,
|
|
884
|
+
)
|
|
686
885
|
generation_config = pipeline.LLMProviderConfig(
|
|
687
|
-
provider=cfg.provider,
|
|
886
|
+
provider=cfg.provider,
|
|
887
|
+
api_key=cfg.api_key,
|
|
888
|
+
model=cfg.deployment or cfg.model,
|
|
889
|
+
endpoint=cfg.endpoint,
|
|
890
|
+
api_version=cfg.api_version,
|
|
688
891
|
)
|
|
689
892
|
metadata = pipeline.TrialMetadata(
|
|
690
893
|
username=cfg.user, email=cfg.email, description=cfg.description, note=cfg.note
|
|
@@ -10,10 +10,13 @@ from .llm import (
|
|
|
10
10
|
)
|
|
11
11
|
from .providers import (
|
|
12
12
|
AnthropicRegexBuilder,
|
|
13
|
+
AzureRegexBuilder,
|
|
13
14
|
CerebrasRegexBuilder,
|
|
15
|
+
CohereRegexBuilder,
|
|
14
16
|
DeepSeekRegexBuilder,
|
|
15
17
|
FireworksRegexBuilder,
|
|
16
18
|
GroqRegexBuilder,
|
|
19
|
+
MistralRegexBuilder,
|
|
17
20
|
MoonshotRegexBuilder,
|
|
18
21
|
OpenAIRegexBuilder,
|
|
19
22
|
OpenRouterRegexBuilder,
|
|
@@ -31,10 +34,13 @@ __all__ = [
|
|
|
31
34
|
"RegexBuilder",
|
|
32
35
|
"UnimplementedRegexBuilder",
|
|
33
36
|
"AnthropicRegexBuilder",
|
|
37
|
+
"AzureRegexBuilder",
|
|
34
38
|
"CerebrasRegexBuilder",
|
|
39
|
+
"CohereRegexBuilder",
|
|
35
40
|
"DeepSeekRegexBuilder",
|
|
36
41
|
"FireworksRegexBuilder",
|
|
37
42
|
"GroqRegexBuilder",
|
|
43
|
+
"MistralRegexBuilder",
|
|
38
44
|
"MoonshotRegexBuilder",
|
|
39
45
|
"OpenAIRegexBuilder",
|
|
40
46
|
"OpenRouterRegexBuilder",
|