This commit is contained in:
Julian Wachter 2026-09-13 00:12:31 +08:00 committed by GitHub
commit 3cd92cebea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 75 additions and 6 deletions

View file

@ -4,6 +4,7 @@ import (
"fmt"
"net/http"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
@ -29,7 +30,12 @@ func resourceLiteLLMVectorStoreCreate(d *schema.ResourceData, m interface{}) err
paramsMap[k] = v
}
// /vector_store/new rejects a missing vector_store_id, and the attribute is
// computed, so the provider has to mint the id it stores under.
vectorStoreID := uuid.New().String()
vectorStoreRequest := VectorStoreRequest{
VectorStoreID: vectorStoreID,
CustomLLMProvider: customLLMProvider,
VectorStoreName: vectorStoreName,
VectorStoreDescription: vectorStoreDescription,
@ -49,9 +55,7 @@ func resourceLiteLLMVectorStoreCreate(d *schema.ResourceData, m interface{}) err
return fmt.Errorf("failed to create vector store: %w", err)
}
// Set the resource ID to the vector store name for now
// We'll update this after reading the response to get the actual ID
d.SetId(vectorStoreName)
d.SetId(vectorStoreID)
return resourceLiteLLMVectorStoreRead(d, m)
}
@ -76,8 +80,11 @@ func resourceLiteLLMVectorStoreRead(d *schema.ResourceData, m interface{}) error
return nil
}
var vectorStoreResp VectorStoreResponse
err = handleVectorStoreAPIResponse(resp, &vectorStoreResp, client)
// /vector_store/info nests the store under "vector_store".
var infoResp struct {
VectorStore VectorStoreResponse `json:"vector_store"`
}
err = handleVectorStoreAPIResponse(resp, &infoResp, client)
if err != nil {
if err.Error() == "vector_store_not_found" {
d.SetId("")
@ -85,6 +92,7 @@ func resourceLiteLLMVectorStoreRead(d *schema.ResourceData, m interface{}) error
}
return fmt.Errorf("failed to read vector store: %w", err)
}
vectorStoreResp := infoResp.VectorStore
// Update the resource ID to the actual vector store ID from the response
if vectorStoreResp.VectorStoreID != "" {

View file

@ -19,7 +19,7 @@ func TestVectorStoreReadDoesNotPersistServerLitellmParams(t *testing.T) {
"api_base": "https://upstream.example.com",
},
}
body, _ := json.Marshal(resp)
body, _ := json.Marshal(map[string]interface{}{"vector_store": resp})
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
@ -53,3 +53,64 @@ func TestVectorStoreReadDoesNotPersistServerLitellmParams(t *testing.T) {
t.Fatalf("read did not populate non-sensitive fields")
}
}
// /vector_store/new 400s without a vector_store_id, and the attribute is
// computed, so create has to mint one and key the resource on it rather than on
// the store's name.
func TestVectorStoreCreateSendsGeneratedIDAndUsesItAsResourceID(t *testing.T) {
var createBody map[string]interface{}
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
if r.URL.Path == "/vector_store/new" {
json.NewDecoder(r.Body).Decode(&createBody)
id, _ := createBody["vector_store_id"].(string)
if id == "" {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(`{"detail":"vector_store_id and custom_llm_provider are required"}`))
return
}
json.NewEncoder(w).Encode(map[string]interface{}{
"status": "success",
"vector_store": VectorStoreResponse{VectorStoreID: id, VectorStoreName: "kb", CustomLLMProvider: "openai"},
})
return
}
var info VectorStoreInfoRequest
json.NewDecoder(r.Body).Decode(&info)
json.NewEncoder(w).Encode(map[string]interface{}{
"vector_store": VectorStoreResponse{
VectorStoreID: info.VectorStoreID,
VectorStoreName: "kb",
CustomLLMProvider: "openai",
CreatedAt: "2026-01-01T00:00:00Z",
},
})
}))
defer srv.Close()
d := schema.TestResourceDataRaw(t, resourceLiteLLMVectorStore().Schema, map[string]interface{}{
"vector_store_name": "kb",
"custom_llm_provider": "openai",
})
if err := resourceLiteLLMVectorStoreCreate(d, NewClient(srv.URL, "test-key", true)); err != nil {
t.Fatalf("create failed: %v", err)
}
sentID, _ := createBody["vector_store_id"].(string)
if sentID == "" {
t.Fatal("create payload omitted vector_store_id, which the proxy rejects")
}
if d.Id() != sentID {
t.Errorf("resource id = %q, want the created store id %q", d.Id(), sentID)
}
if d.Get("vector_store_id").(string) != sentID {
t.Errorf("vector_store_id = %q, want %q", d.Get("vector_store_id").(string), sentID)
}
if d.Get("created_at").(string) != "2026-01-01T00:00:00Z" {
t.Errorf("create did not refresh computed fields from the API: %v", d.Get("created_at"))
}
}