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