Skip to content

Commit 4aa1490

Browse files
committed
feat: declare model_usage on DescribeImage, OpenAiPrompt, and AnthropicPrompt
1 parent 2378071 commit 4aa1490

2 files changed

Lines changed: 98 additions & 16 deletions

File tree

griptape_nodes_library.json

Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@
6363
"display_name": "Claude Opus 4.7",
6464
"family": "Claude 4",
6565
"provider_model_id": "claude-opus-4-7",
66-
"key_support": "REQUIRES_GRIPTAPE_KEY"
66+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
6767
},
6868
"gtc_claude_sonnet_4_6": {
6969
"display_name": "Claude Sonnet 4.6",
7070
"family": "Claude 4",
7171
"provider_model_id": "claude-sonnet-4-6",
72-
"key_support": "REQUIRES_GRIPTAPE_KEY"
72+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
7373
},
7474
"gtc_claude_sonnet_4_5": {
7575
"display_name": "Claude Sonnet 4.5",
@@ -81,7 +81,7 @@
8181
"display_name": "Claude Haiku 4.5",
8282
"family": "Claude 4",
8383
"provider_model_id": "claude-haiku-4-5",
84-
"key_support": "REQUIRES_GRIPTAPE_KEY"
84+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
8585
}
8686
}
8787
},
@@ -203,7 +203,7 @@
203203
"display_name": "GPT-5.2",
204204
"family": "GPT",
205205
"provider_model_id": "gpt-5.2",
206-
"key_support": "REQUIRES_GRIPTAPE_KEY"
206+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
207207
},
208208
"gtc_gpt_5_2_chat": {
209209
"display_name": "GPT-5.2 Chat",
@@ -215,73 +215,73 @@
215215
"display_name": "GPT-5.1",
216216
"family": "GPT",
217217
"provider_model_id": "gpt-5.1",
218-
"key_support": "REQUIRES_GRIPTAPE_KEY"
218+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
219219
},
220220
"gtc_gpt_5": {
221221
"display_name": "GPT-5",
222222
"family": "GPT",
223223
"provider_model_id": "gpt-5",
224-
"key_support": "REQUIRES_GRIPTAPE_KEY"
224+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
225225
},
226226
"gtc_gpt_5_mini": {
227227
"display_name": "GPT-5 mini",
228228
"family": "GPT",
229229
"provider_model_id": "gpt-5-mini",
230-
"key_support": "REQUIRES_GRIPTAPE_KEY"
230+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
231231
},
232232
"gtc_gpt_5_nano": {
233233
"display_name": "GPT-5 nano",
234234
"family": "GPT",
235235
"provider_model_id": "gpt-5-nano",
236-
"key_support": "REQUIRES_GRIPTAPE_KEY"
236+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
237237
},
238238
"gtc_gpt_4_1": {
239239
"display_name": "GPT-4.1",
240240
"family": "GPT",
241241
"provider_model_id": "gpt-4.1",
242-
"key_support": "REQUIRES_GRIPTAPE_KEY"
242+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
243243
},
244244
"gtc_gpt_4_1_mini": {
245245
"display_name": "GPT-4.1 mini",
246246
"family": "GPT",
247247
"provider_model_id": "gpt-4.1-mini",
248-
"key_support": "REQUIRES_GRIPTAPE_KEY"
248+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
249249
},
250250
"gtc_gpt_4_1_nano": {
251251
"display_name": "GPT-4.1 nano",
252252
"family": "GPT",
253253
"provider_model_id": "gpt-4.1-nano",
254-
"key_support": "REQUIRES_GRIPTAPE_KEY"
254+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
255255
},
256256
"gtc_gpt_4o": {
257257
"display_name": "GPT-4o",
258258
"family": "GPT",
259259
"provider_model_id": "gpt-4o",
260-
"key_support": "REQUIRES_GRIPTAPE_KEY"
260+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
261261
},
262262
"gtc_o4_mini": {
263263
"display_name": "o4 mini",
264264
"family": "o-series",
265265
"provider_model_id": "o4-mini",
266-
"key_support": "REQUIRES_GRIPTAPE_KEY"
266+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
267267
},
268268
"gtc_o3": {
269269
"display_name": "o3",
270270
"family": "o-series",
271271
"provider_model_id": "o3",
272-
"key_support": "REQUIRES_GRIPTAPE_KEY"
272+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
273273
},
274274
"gtc_o3_mini": {
275275
"display_name": "o3 mini",
276276
"family": "o-series",
277277
"provider_model_id": "o3-mini",
278-
"key_support": "REQUIRES_GRIPTAPE_KEY"
278+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
279279
},
280280
"gtc_o1": {
281281
"display_name": "o1",
282282
"family": "o-series",
283283
"provider_model_id": "o1",
284-
"key_support": "REQUIRES_GRIPTAPE_KEY"
284+
"key_support": "SUPPORTS_CUSTOMER_KEY_OR_GRIPTAPE_KEY"
285285
},
286286
"gtc_gpt_image_1": {
287287
"display_name": "GPT Image 1",
@@ -3740,6 +3740,16 @@
37403740
"config",
37413741
"anthropic",
37423742
"llm"
3743+
],
3744+
"declarations": [
3745+
{
3746+
"type": "model_usage",
3747+
"model_ids": [
3748+
"gtc_claude_opus_4_7",
3749+
"gtc_claude_sonnet_4_6",
3750+
"gtc_claude_haiku_4_5"
3751+
]
3752+
}
37433753
]
37443754
}
37453755
},
@@ -3917,6 +3927,26 @@
39173927
"config",
39183928
"openai",
39193929
"llm"
3930+
],
3931+
"declarations": [
3932+
{
3933+
"type": "model_usage",
3934+
"model_ids": [
3935+
"gtc_gpt_5_2",
3936+
"gtc_gpt_5_1",
3937+
"gtc_gpt_5",
3938+
"gtc_gpt_5_mini",
3939+
"gtc_gpt_5_nano",
3940+
"gtc_gpt_4_1",
3941+
"gtc_gpt_4_1_mini",
3942+
"gtc_gpt_4_1_nano",
3943+
"gtc_gpt_4o",
3944+
"gtc_o4_mini",
3945+
"gtc_o3",
3946+
"gtc_o3_mini",
3947+
"gtc_o1"
3948+
]
3949+
}
39203950
]
39213951
}
39223952
},
@@ -3962,6 +3992,28 @@
39623992
"text",
39633993
"ai",
39643994
"vision"
3995+
],
3996+
"declarations": [
3997+
{
3998+
"type": "model_usage",
3999+
"model_ids": [
4000+
"gtc_gpt_5_2",
4001+
"gtc_gpt_5_1",
4002+
"gtc_gpt_5",
4003+
"gtc_gpt_5_mini",
4004+
"gtc_gpt_4_1",
4005+
"gtc_gpt_4_1_mini",
4006+
"gtc_gpt_4_1_nano",
4007+
"gtc_gpt_4o",
4008+
"gtc_o4_mini",
4009+
"gtc_o3",
4010+
"gtc_claude_opus_4_7",
4011+
"gtc_claude_sonnet_4_6",
4012+
"gtc_claude_sonnet_4_5",
4013+
"gtc_gemini_3_1_pro",
4014+
"gtc_gemini_2_5_pro"
4015+
]
4016+
}
39654017
]
39664018
}
39674019
},

tests/unit/test_model_catalog_consistency.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717

1818
import pytest
1919

20+
from griptape_nodes_library.config.prompt.anthropic_prompt import MODEL_CHOICES as ANTHROPIC_MODEL_CHOICES
2021
from griptape_nodes_library.config.prompt.cloud_models import MODEL_CHOICES_ARGS
22+
from griptape_nodes_library.config.prompt.openai_prompt import MODEL_CHOICES as OPENAI_MODEL_CHOICES
23+
from griptape_nodes_library.image.describe_image import MODEL_CHOICES as DESCRIBE_IMAGE_MODEL_CHOICES
2124

2225
LIBRARY_JSON = Path(__file__).parents[2] / "griptape_nodes_library.json"
2326

@@ -68,6 +71,33 @@ def test_chat_node_model_usage_matches_static_choices(class_name: str) -> None:
6871
assert declared == served
6972

7073

74+
@pytest.mark.parametrize(
75+
("class_name", "model_choices"),
76+
[
77+
("DescribeImage", DESCRIBE_IMAGE_MODEL_CHOICES),
78+
("OpenAiPrompt", OPENAI_MODEL_CHOICES),
79+
("AnthropicPrompt", ANTHROPIC_MODEL_CHOICES),
80+
],
81+
)
82+
def test_static_model_choice_node_model_usage_matches_static_choices(
83+
class_name: str, model_choices: list[str]
84+
) -> None:
85+
"""The static `MODEL_CHOICES` list in Python and the models the node declares must agree.
86+
87+
Unlike the chat nodes above, these nodes carry their model list as a plain
88+
list of provider model id strings rather than `MODEL_CHOICES_ARGS` dicts.
89+
Each node's `model_usage` ids resolve (through the catalog) to the same
90+
ordered provider model ids the node serves from `MODEL_CHOICES`. A
91+
mismatch means the manifest and the code drifted and one side needs updating.
92+
"""
93+
library = _load_library()
94+
provider_model_id_by_catalog_id = _provider_model_id_by_catalog_id(library)
95+
96+
declared = [provider_model_id_by_catalog_id[model_id] for model_id in _model_usage_ids(library, class_name)]
97+
98+
assert declared == model_choices
99+
100+
71101
def test_declared_models_resolve_uniquely_per_node() -> None:
72102
"""Each node's declared models map one-to-one to provider model ids.
73103

0 commit comments

Comments
 (0)