ibm-watsonx-orchestrate 1.4.2__py3-none-any.whl → 1.5.0b1__py3-none-any.whl
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.
- ibm_watsonx_orchestrate/__init__.py +1 -1
- ibm_watsonx_orchestrate/agent_builder/agents/types.py +10 -1
- ibm_watsonx_orchestrate/agent_builder/knowledge_bases/types.py +14 -0
- ibm_watsonx_orchestrate/agent_builder/model_policies/__init__.py +1 -0
- ibm_watsonx_orchestrate/{client → agent_builder}/model_policies/types.py +7 -8
- ibm_watsonx_orchestrate/agent_builder/models/__init__.py +1 -0
- ibm_watsonx_orchestrate/{client → agent_builder}/models/types.py +57 -9
- ibm_watsonx_orchestrate/agent_builder/tools/python_tool.py +46 -3
- ibm_watsonx_orchestrate/agent_builder/tools/types.py +47 -1
- ibm_watsonx_orchestrate/cli/commands/agents/agents_command.py +17 -0
- ibm_watsonx_orchestrate/cli/commands/agents/agents_controller.py +86 -39
- ibm_watsonx_orchestrate/cli/commands/models/model_provider_mapper.py +191 -0
- ibm_watsonx_orchestrate/cli/commands/models/models_command.py +140 -258
- ibm_watsonx_orchestrate/cli/commands/models/models_controller.py +437 -0
- ibm_watsonx_orchestrate/cli/commands/server/server_command.py +2 -1
- ibm_watsonx_orchestrate/cli/commands/tools/tools_controller.py +1 -1
- ibm_watsonx_orchestrate/client/connections/__init__.py +2 -1
- ibm_watsonx_orchestrate/client/connections/utils.py +30 -0
- ibm_watsonx_orchestrate/client/model_policies/model_policies_client.py +23 -4
- ibm_watsonx_orchestrate/client/models/models_client.py +23 -3
- ibm_watsonx_orchestrate/client/toolkit/toolkit_client.py +13 -8
- ibm_watsonx_orchestrate/client/tools/tool_client.py +2 -1
- ibm_watsonx_orchestrate/docker/compose-lite.yml +2 -0
- ibm_watsonx_orchestrate/docker/default.env +10 -11
- ibm_watsonx_orchestrate/experimental/flow_builder/data_map.py +19 -0
- ibm_watsonx_orchestrate/experimental/flow_builder/flows/__init__.py +4 -3
- ibm_watsonx_orchestrate/experimental/flow_builder/flows/constants.py +3 -1
- ibm_watsonx_orchestrate/experimental/flow_builder/flows/decorators.py +3 -2
- ibm_watsonx_orchestrate/experimental/flow_builder/flows/flow.py +245 -223
- ibm_watsonx_orchestrate/experimental/flow_builder/node.py +34 -15
- ibm_watsonx_orchestrate/experimental/flow_builder/resources/flow_status.openapi.yml +7 -39
- ibm_watsonx_orchestrate/experimental/flow_builder/types.py +285 -12
- ibm_watsonx_orchestrate/experimental/flow_builder/utils.py +3 -1
- {ibm_watsonx_orchestrate-1.4.2.dist-info → ibm_watsonx_orchestrate-1.5.0b1.dist-info}/METADATA +1 -1
- {ibm_watsonx_orchestrate-1.4.2.dist-info → ibm_watsonx_orchestrate-1.5.0b1.dist-info}/RECORD +38 -35
- ibm_watsonx_orchestrate/cli/commands/models/env_file_model_provider_mapper.py +0 -180
- ibm_watsonx_orchestrate/experimental/flow_builder/flows/data_map.py +0 -91
- {ibm_watsonx_orchestrate-1.4.2.dist-info → ibm_watsonx_orchestrate-1.5.0b1.dist-info}/WHEEL +0 -0
- {ibm_watsonx_orchestrate-1.4.2.dist-info → ibm_watsonx_orchestrate-1.5.0b1.dist-info}/entry_points.txt +0 -0
- {ibm_watsonx_orchestrate-1.4.2.dist-info → ibm_watsonx_orchestrate-1.5.0b1.dist-info}/licenses/LICENSE +0 -0
@@ -1,32 +1,20 @@
|
|
1
1
|
import logging
|
2
|
-
import os
|
3
|
-
import sys
|
4
2
|
from typing import List
|
3
|
+
import json
|
4
|
+
import sys
|
5
5
|
|
6
|
-
import requests
|
7
|
-
import rich
|
8
|
-
import rich.highlighter
|
9
6
|
import typer
|
10
7
|
from typing_extensions import Annotated
|
11
8
|
|
12
|
-
from ibm_watsonx_orchestrate.
|
13
|
-
from ibm_watsonx_orchestrate.
|
14
|
-
from ibm_watsonx_orchestrate.
|
15
|
-
|
16
|
-
from ibm_watsonx_orchestrate.client.models.models_client import ModelsClient
|
17
|
-
from ibm_watsonx_orchestrate.client.models.types import CreateVirtualModel, ANTHROPIC_DEFAULT_MAX_TOKENS
|
18
|
-
from ibm_watsonx_orchestrate.client.utils import instantiate_client
|
9
|
+
from ibm_watsonx_orchestrate.agent_builder.models.types import ModelType
|
10
|
+
from ibm_watsonx_orchestrate.agent_builder.model_policies.types import ModelPolicyStrategyMode
|
11
|
+
from ibm_watsonx_orchestrate.cli.commands.models.models_controller import ModelsController
|
12
|
+
|
19
13
|
|
20
14
|
logger = logging.getLogger(__name__)
|
21
15
|
models_app = typer.Typer(no_args_is_help=True)
|
22
16
|
models_policy_app = typer.Typer(no_args_is_help=True)
|
23
|
-
|
24
|
-
|
25
|
-
WATSONX_URL = os.getenv("WATSONX_URL")
|
26
|
-
|
27
|
-
class ModelHighlighter(rich.highlighter.RegexHighlighter):
|
28
|
-
base_style = "model."
|
29
|
-
highlights = [r"(?P<name>(watsonx|virtual[-]model|virtual[-]policy)\/.+\/.+):"]
|
17
|
+
models_app.add_typer(models_policy_app, name='policy', help='Add or remove pseudo models which route traffic between multiple downstream models')
|
30
18
|
|
31
19
|
@models_app.command(name="list", help="List available models")
|
32
20
|
def model_list(
|
@@ -35,108 +23,33 @@ def model_list(
|
|
35
23
|
typer.Option("--raw", "-r", help="Display the list of models in a non-tabular format"),
|
36
24
|
] = False,
|
37
25
|
):
|
38
|
-
|
39
|
-
|
40
|
-
global WATSONX_URL
|
41
|
-
default_env_path = get_default_env_file()
|
42
|
-
merged_env_dict = merge_env(
|
43
|
-
default_env_path,
|
44
|
-
None
|
45
|
-
)
|
46
|
-
|
47
|
-
if 'WATSONX_URL' in merged_env_dict and merged_env_dict['WATSONX_URL']:
|
48
|
-
WATSONX_URL = merged_env_dict['WATSONX_URL']
|
49
|
-
|
50
|
-
watsonx_url = merged_env_dict.get("WATSONX_URL")
|
51
|
-
if not watsonx_url:
|
52
|
-
logger.error("Error: WATSONX_URL is required in the environment.")
|
53
|
-
sys.exit(1)
|
54
|
-
|
55
|
-
logger.info("Retrieving virtual-model models list...")
|
56
|
-
virtual_models = models_client.list()
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
logger.info("Retrieving virtual-policies models list...")
|
61
|
-
virtual_model_policies = model_policies_client.list()
|
62
|
-
|
63
|
-
logger.info("Retrieving watsonx.ai models list...")
|
64
|
-
found_models = _get_wxai_foundational_models()
|
65
|
-
|
66
|
-
|
67
|
-
preferred_str = merged_env_dict.get('PREFERRED_MODELS', '')
|
68
|
-
incompatible_str = merged_env_dict.get('INCOMPATIBLE_MODELS', '')
|
69
|
-
|
70
|
-
preferred_list = _string_to_list(preferred_str)
|
71
|
-
incompatible_list = _string_to_list(incompatible_str)
|
72
|
-
|
73
|
-
models = found_models.get("resources", [])
|
74
|
-
if not models:
|
75
|
-
logger.error("No models found.")
|
76
|
-
else:
|
77
|
-
# Remove incompatible models
|
78
|
-
filtered_models = []
|
79
|
-
for model in models:
|
80
|
-
model_id = model.get("model_id", "")
|
81
|
-
short_desc = model.get("short_description", "")
|
82
|
-
if any(incomp in model_id.lower() for incomp in incompatible_list):
|
83
|
-
continue
|
84
|
-
if any(incomp in short_desc.lower() for incomp in incompatible_list):
|
85
|
-
continue
|
86
|
-
filtered_models.append(model)
|
87
|
-
|
88
|
-
# Sort to put the preferred first
|
89
|
-
def sort_key(model):
|
90
|
-
model_id = model.get("model_id", "").lower()
|
91
|
-
is_preferred = any(pref in model_id for pref in preferred_list)
|
92
|
-
return (0 if is_preferred else 1, model_id)
|
93
|
-
|
94
|
-
sorted_models = sorted(filtered_models, key=sort_key)
|
95
|
-
|
96
|
-
if print_raw:
|
97
|
-
theme = rich.theme.Theme({"model.name": "bold cyan"})
|
98
|
-
console = rich.console.Console(highlighter=ModelHighlighter(), theme=theme)
|
99
|
-
console.print("[bold]Available Models:[/bold]")
|
100
|
-
|
101
|
-
for model in virtual_models:
|
102
|
-
console.print(f"- ✨️ {model.name}:", model.description or 'No description provided.')
|
103
|
-
|
104
|
-
for model in virtual_model_policies:
|
105
|
-
console.print(f"- ✨️ {model.name}:", 'No description provided.')
|
106
|
-
|
107
|
-
for model in sorted_models:
|
108
|
-
model_id = model.get("model_id", "N/A")
|
109
|
-
short_desc = model.get("short_description", "No description provided.")
|
110
|
-
full_model_name = f"watsonx/{model_id}: {short_desc}"
|
111
|
-
marker = "★ " if any(pref in model_id.lower() for pref in preferred_list) else ""
|
112
|
-
console.print(f"- [yellow]{marker}[/yellow]{full_model_name}")
|
113
|
-
|
114
|
-
console.print("[yellow]★[/yellow] [italic dim]indicates a supported and preferred model[/italic dim]\n[blue dim]✨️[/blue dim] [italic dim]indicates a model from a custom provider[/italic dim]" )
|
115
|
-
else:
|
116
|
-
table = rich.table.Table(
|
117
|
-
show_header=True,
|
118
|
-
title="[bold]Available Models[/bold]",
|
119
|
-
caption="[yellow]★ [/yellow] indicates a supported and preferred model from watsonx\n[blue]✨️[/blue] indicates a model from a custom provider",
|
120
|
-
show_lines=True)
|
121
|
-
columns = ["Model", "Description"]
|
122
|
-
for col in columns:
|
123
|
-
table.add_column(col)
|
124
|
-
|
125
|
-
for model in virtual_models:
|
126
|
-
table.add_row(f"✨️ {model.name}", model.description or 'No description provided.')
|
127
|
-
|
128
|
-
for model in virtual_model_policies:
|
129
|
-
table.add_row(f"✨️ {model.name}", 'No description provided.')
|
130
|
-
|
131
|
-
for model in sorted_models:
|
132
|
-
model_id = model.get("model_id", "N/A")
|
133
|
-
short_desc = model.get("short_description", "No description provided.")
|
134
|
-
marker = "★ " if any(pref in model_id.lower() for pref in preferred_list) else ""
|
135
|
-
table.add_row(f"[yellow]{marker}[/yellow]watsonx/{model_id}", short_desc)
|
136
|
-
|
137
|
-
rich.print(table)
|
138
|
-
|
26
|
+
models_controller = ModelsController()
|
27
|
+
models_controller.list_models(print_raw=print_raw)
|
139
28
|
|
29
|
+
@models_app.command(name="import", help="Import models from spec file")
|
30
|
+
def models_import(
|
31
|
+
file: Annotated[
|
32
|
+
str,
|
33
|
+
typer.Option(
|
34
|
+
"--file",
|
35
|
+
"-f",
|
36
|
+
help="Path to spec file containing model details.",
|
37
|
+
),
|
38
|
+
],
|
39
|
+
app_id: Annotated[
|
40
|
+
str, typer.Option(
|
41
|
+
'--app-id', '-a',
|
42
|
+
help='The app id of a key_value connection containing authentications details for the model provider.'
|
43
|
+
)
|
44
|
+
] = None,
|
45
|
+
):
|
46
|
+
models_controller = ModelsController()
|
47
|
+
models = models_controller.import_model(
|
48
|
+
file=file,
|
49
|
+
app_id=app_id
|
50
|
+
)
|
51
|
+
for model in models:
|
52
|
+
models_controller.publish_or_update_models(model=model)
|
140
53
|
|
141
54
|
@models_app.command(name="add", help="Add an llm from a custom provider")
|
142
55
|
def models_add(
|
@@ -144,10 +57,6 @@ def models_add(
|
|
144
57
|
str,
|
145
58
|
typer.Option("--name", "-n", help="The name of the model to add"),
|
146
59
|
],
|
147
|
-
env_file: Annotated[
|
148
|
-
str,
|
149
|
-
typer.Option('--env-file', '-e', help='The path to an .env file containing the credentials for your llm provider'),
|
150
|
-
],
|
151
60
|
description: Annotated[
|
152
61
|
str,
|
153
62
|
typer.Option('--description', '-d', help='The description of the model to add'),
|
@@ -156,33 +65,42 @@ def models_add(
|
|
156
65
|
str,
|
157
66
|
typer.Option('--display-name', help='What name should this llm appear as within the ui'),
|
158
67
|
] = None,
|
159
|
-
|
68
|
+
provider_config: Annotated[
|
69
|
+
str,
|
70
|
+
typer.Option(
|
71
|
+
"--provider-config",
|
72
|
+
help="LLM provider configuration in JSON format (e.g., '{\"customHost\": \"xyz\"}')",
|
73
|
+
),
|
74
|
+
] = None,
|
75
|
+
app_id: Annotated[
|
76
|
+
str, typer.Option(
|
77
|
+
'--app-id', '-a',
|
78
|
+
help='The app id of a key_value connection containing authentications details for the model provider.'
|
79
|
+
)
|
80
|
+
] = None,
|
81
|
+
type: Annotated[
|
82
|
+
ModelType,
|
83
|
+
typer.Option('--type', help='What type of model is it'),
|
84
|
+
] = ModelType.CHAT,
|
160
85
|
):
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
config = {
|
172
|
-
"max_tokens": ANTHROPIC_DEFAULT_MAX_TOKENS
|
173
|
-
}
|
174
|
-
|
175
|
-
model = CreateVirtualModel(
|
86
|
+
provider_config_dict = {}
|
87
|
+
if provider_config:
|
88
|
+
try:
|
89
|
+
provider_config_dict = json.loads(provider_config)
|
90
|
+
except:
|
91
|
+
logger.error(f"Failed to parse provider config. '{provider_config}' is not valid json")
|
92
|
+
sys.exit(1)
|
93
|
+
|
94
|
+
models_controller = ModelsController()
|
95
|
+
model = models_controller.create_model(
|
176
96
|
name=name,
|
177
|
-
display_name=display_name or name,
|
178
97
|
description=description,
|
179
|
-
|
180
|
-
|
181
|
-
|
98
|
+
display_name=display_name,
|
99
|
+
provider_config_dict = provider_config_dict,
|
100
|
+
model_type=type,
|
101
|
+
app_id=app_id,
|
182
102
|
)
|
183
|
-
|
184
|
-
models_client.create(model)
|
185
|
-
logger.info(f"Successfully added the model '{name}'")
|
103
|
+
models_controller.publish_or_update_models(model=model)
|
186
104
|
|
187
105
|
|
188
106
|
|
@@ -193,122 +111,86 @@ def models_remove(
|
|
193
111
|
typer.Option("--name", "-n", help="The name of the model to remove"),
|
194
112
|
]
|
195
113
|
):
|
196
|
-
|
197
|
-
|
198
|
-
model = next(filter(lambda x: x.name == name or x.name == f"virtual-model/{name}", models), None)
|
199
|
-
if not model:
|
200
|
-
logger.error(f"No model found with the name '{name}'")
|
201
|
-
sys.exit(1)
|
202
|
-
|
203
|
-
models_client.delete(model_id=model.id)
|
204
|
-
logger.info(f"Successfully removed the model '{name}'")
|
205
|
-
|
206
|
-
|
207
|
-
# @models_policy_app.command(name='add', help='Add a model policy')
|
208
|
-
# def models_policy_add(
|
209
|
-
# name: Annotated[
|
210
|
-
# str,
|
211
|
-
# typer.Option("--name", "-n", help="The name of the model to remove"),
|
212
|
-
# ],
|
213
|
-
# models: Annotated[
|
214
|
-
# List[str],
|
215
|
-
# typer.Option('--model', '-m', help='The name of the model to add'),
|
216
|
-
# ],
|
217
|
-
# strategy: Annotated[
|
218
|
-
# ModelPolicyStrategyMode,
|
219
|
-
# typer.Option('--strategy', '-s', help='How to spread traffic across models'),
|
220
|
-
# ],
|
221
|
-
# strategy_on_code: Annotated[
|
222
|
-
# List[int],
|
223
|
-
# typer.Option('--strategy-on-code', help='The http status to consider invoking the strategy'),
|
224
|
-
# ],
|
225
|
-
# retry_on_code: Annotated[
|
226
|
-
# List[int],
|
227
|
-
# typer.Option('--retry-on-code', help='The http status to consider retrying the llm call'),
|
228
|
-
# ],
|
229
|
-
# retry_attempts: Annotated[
|
230
|
-
# int,
|
231
|
-
# typer.Option('--retry-attempts', help='The number of attempts to retry'),
|
232
|
-
# ],
|
233
|
-
# display_name: Annotated[
|
234
|
-
# str,
|
235
|
-
# typer.Option('--display-name', help='What name should this llm appear as within the ui'),
|
236
|
-
# ] = None
|
237
|
-
# ):
|
238
|
-
# model_policies_client: ModelPoliciesClient = instantiate_client(ModelPoliciesClient)
|
239
|
-
# model_client: ModelsClient = instantiate_client(ModelsClient)
|
240
|
-
# model_lut = {m.name: m.id for m in model_client.list()}
|
241
|
-
# for m in models:
|
242
|
-
# if m not in model_lut:
|
243
|
-
# logger.error(f"No model found with the name '{m}'")
|
244
|
-
# exit(1)
|
245
|
-
|
246
|
-
# inner = ModelPolicyInner()
|
247
|
-
# inner.strategy = ModelPolicyStrategy(
|
248
|
-
# mode=strategy,
|
249
|
-
# on_status_codes=strategy_on_code
|
250
|
-
# )
|
251
|
-
# inner.targets = [ModelPolicyTarget(model_id=model_lut[m], weight=1) for m in models]
|
252
|
-
# if retry_on_code:
|
253
|
-
# inner.retry = ModelPolicyRetry(
|
254
|
-
# on_status_codes=retry_on_code,
|
255
|
-
# attempts=retry_attempts
|
256
|
-
# )
|
257
|
-
|
258
|
-
# if not display_name:
|
259
|
-
# display_name = name
|
260
|
-
|
261
|
-
|
262
|
-
# policy = ModelPolicy(
|
263
|
-
# name=name,
|
264
|
-
# display_name=display_name,
|
265
|
-
# policy=inner
|
266
|
-
# )
|
267
|
-
# model_policies_client.create(policy)
|
268
|
-
# logger.info(f"Successfully added the model policy '{name}'")
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
# @models_policy_app.command(name='remove', help='Remove a model policy')
|
273
|
-
# def models_policy_remove(
|
274
|
-
# name: Annotated[
|
275
|
-
# str,
|
276
|
-
# typer.Option("--name", "-n", help="The name of the model policy to remove"),
|
277
|
-
# ]
|
278
|
-
# ):
|
279
|
-
# model_policies_client: ModelPoliciesClient = instantiate_client(ModelPoliciesClient)
|
280
|
-
# model_policies = model_policies_client.list()
|
281
|
-
|
282
|
-
# policy = next(filter(lambda x: x.name == name or x.name == f"virtual-policy/{name}", model_policies), None)
|
283
|
-
# if not policy:
|
284
|
-
# logger.error(f"No model found with the name '{name}'")
|
285
|
-
# exit(1)
|
286
|
-
|
287
|
-
# model_policies_client.delete(model_policy_id=policy.id)
|
288
|
-
# logger.info(f"Successfully removed the model '{name}'")
|
114
|
+
models_controller = ModelsController()
|
115
|
+
models_controller.remove_model(name=name)
|
289
116
|
|
117
|
+
@models_policy_app.command(name='import', help='Add a model policy')
|
118
|
+
def models_policy_import(
|
119
|
+
file: Annotated[
|
120
|
+
str,
|
121
|
+
typer.Option(
|
122
|
+
"--file",
|
123
|
+
"-f",
|
124
|
+
help="Path to spec file containing model details.",
|
125
|
+
),
|
126
|
+
],
|
127
|
+
):
|
128
|
+
models_controller = ModelsController()
|
129
|
+
policies = models_controller.import_model_policy(
|
130
|
+
file=file
|
131
|
+
)
|
132
|
+
for policy in policies:
|
133
|
+
models_controller.publish_or_update_model_policies(policy=policy)
|
290
134
|
|
291
|
-
|
292
|
-
|
135
|
+
@models_policy_app.command(name='add', help='Add a model policy')
|
136
|
+
def models_policy_add(
|
137
|
+
name: Annotated[
|
138
|
+
str,
|
139
|
+
typer.Option("--name", "-n", help="The name of the model to remove"),
|
140
|
+
],
|
141
|
+
models: Annotated[
|
142
|
+
List[str],
|
143
|
+
typer.Option('--model', '-m', help='The name of the model to add'),
|
144
|
+
],
|
145
|
+
strategy: Annotated[
|
146
|
+
ModelPolicyStrategyMode,
|
147
|
+
typer.Option('--strategy', '-s', help='How to spread traffic across models'),
|
148
|
+
],
|
149
|
+
strategy_on_code: Annotated[
|
150
|
+
List[int],
|
151
|
+
typer.Option('--strategy-on-code', help='The http status to consider invoking the strategy'),
|
152
|
+
],
|
153
|
+
retry_on_code: Annotated[
|
154
|
+
List[int],
|
155
|
+
typer.Option('--retry-on-code', help='The http status to consider retrying the llm call'),
|
156
|
+
],
|
157
|
+
retry_attempts: Annotated[
|
158
|
+
int,
|
159
|
+
typer.Option('--retry-attempts', help='The number of attempts to retry'),
|
160
|
+
],
|
161
|
+
display_name: Annotated[
|
162
|
+
str,
|
163
|
+
typer.Option('--display-name', help='What name should this llm appear as within the ui'),
|
164
|
+
] = None,
|
165
|
+
description: Annotated[
|
166
|
+
str,
|
167
|
+
typer.Option('--description', help='Description of the policy for display in the ui'),
|
168
|
+
] = None
|
169
|
+
):
|
170
|
+
models_controller = ModelsController()
|
171
|
+
policy = models_controller.create_model_policy(
|
172
|
+
name=name,
|
173
|
+
models=models,
|
174
|
+
strategy=strategy,
|
175
|
+
strategy_on_code=strategy_on_code,
|
176
|
+
retry_on_code=retry_on_code,
|
177
|
+
retry_attempts=retry_attempts,
|
178
|
+
display_name=display_name,
|
179
|
+
description=description
|
180
|
+
)
|
181
|
+
models_controller.publish_or_update_model_policies(policy=policy)
|
293
182
|
|
294
|
-
try:
|
295
|
-
response = requests.get(foundation_models_url)
|
296
|
-
except requests.exceptions.RequestException as e:
|
297
|
-
logger.exception(f"Exception when connecting to Watsonx URL: {foundation_models_url}")
|
298
|
-
raise
|
299
183
|
|
300
|
-
if response.status_code != 200:
|
301
|
-
error_message = (
|
302
|
-
f"Failed to retrieve foundational models from {foundation_models_url}. "
|
303
|
-
f"Status code: {response.status_code}. Response: {response.content}"
|
304
|
-
)
|
305
|
-
raise Exception(error_message)
|
306
|
-
|
307
|
-
json_response = response.json()
|
308
|
-
return json_response
|
309
184
|
|
310
|
-
|
311
|
-
|
185
|
+
@models_policy_app.command(name='remove', help='Remove a model policy')
|
186
|
+
def models_policy_remove(
|
187
|
+
name: Annotated[
|
188
|
+
str,
|
189
|
+
typer.Option("--name", "-n", help="The name of the model policy to remove"),
|
190
|
+
]
|
191
|
+
):
|
192
|
+
models_controller = ModelsController()
|
193
|
+
models_controller.remove_policy(name=name)
|
312
194
|
|
313
195
|
if __name__ == "__main__":
|
314
196
|
models_app()
|