This commit is contained in:
Nick Silva 2026-09-30 20:49:47 -04:00 • committed by GitHub
commit db9da2cf41
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 34 additions and 0 deletions

View file

@ -61,6 +61,7 @@ longer signal it.
- **key**: A config-supplied `key` value (write-only) is now forwarded to `/key/generate`; previously it was silently dropped and the proxy generated a random key instead
- **security**: The `litellm_key` data source and `litellm_key_block` resource normalize raw `sk-` keys to their SHA-256 token hash before building request URLs and resource IDs, so plaintext keys no longer land in reverse-proxy access logs, Terraform plan output, or state IDs
- **unified_access_group**: create now accepts any 2xx response instead of requiring exactly HTTP 200; `POST /v1/unified_access_group` legitimately returns 201, so creation previously succeeded on the proxy but failed in the provider, leaving the group out of state and forcing a `terraform import` to recover on the next apply's 409. Same fix and shape as the one already applied to `mcp_server`/`model`/`key`/`organization_member`; `handleResponse` (shared by several other resources) was the one status-check helper that fix didn't reach. The legacy `litellm_access_group` resource calls the unrelated `/access_group/new` endpoint, which already returns 200, so it was never affected
- **model**: `mode` on `litellm_model` now accepts `responses`, `realtime`, `image_edit`, `ocr`, `search`, `video_generation` and `evaluation`, matching the modes `model_prices_and_context_window.json` already assigns to shipped models (for example `responses` on `azure/codex-mini` and `realtime` on `amazon.nova-2-sonic-v1:0`); previously the enum only allowed `completion`, `embedding`, `image_generation`, `chat`, `moderation`, `audio_transcription`, `audio_speech` and `rerank`, so setting a model's `mode` to any of the missing values failed at plan time with `expected mode to be one of [...]`. `guardrail` and `vector_store` are deliberately left out, since those are modeled as the dedicated `litellm_guardrail` and `litellm_vector_store` resources rather than as a `litellm_model` mode
### Changed

View file

@ -137,6 +137,13 @@ The following arguments are supported:
* `audio_transcription`
* `audio_speech`
* `rerank`
* `responses`
* `realtime`
* `image_edit`
* `ocr`
* `search`
* `video_generation`
* `evaluation`
* `tpm` - (Optional) integer. Tokens per minute limit for this model.

View file

@ -110,6 +110,13 @@ func resourceLiteLLMModel() *schema.Resource {
"audio_transcription",
"audio_speech",
"rerank",
"responses",
"realtime",
"image_edit",
"ocr",
"search",
"video_generation",
"evaluation",
}, false),
},
"input_cost_per_million_tokens": {

View file

@ -242,3 +242,22 @@ func TestResourceLiteLLMModelUpdateSkipsPatchWhenDisplayNameUnchanged(t *testing
t.Fatalf("update failed: %v", err)
}
}
func TestResourceLiteLLMModel_ModeValidation(t *testing.T) {
validateMode := resourceLiteLLMModel().Schema["mode"].ValidateFunc
valid := []string{
"completion", "embedding", "image_generation", "chat", "moderation",
"audio_transcription", "audio_speech", "rerank",
"responses", "realtime", "image_edit", "ocr", "search", "video_generation", "evaluation",
}
for _, mode := range valid {
if _, errs := validateMode(mode, "mode"); len(errs) != 0 {
t.Errorf("mode %q: expected no validation error, got %v", mode, errs)
}
}
if _, errs := validateMode("not_a_real_mode", "mode"); len(errs) == 0 {
t.Error(`mode "not_a_real_mode": expected a validation error, got none`)
}
}