Skip to content

feat(gooddata-sdk): [AUTO] Add resolveLlmProviders endpoint and ResolvedLlm polymorphic schemas#1554

Closed
yenkins-admin wants to merge 1 commit intomasterfrom
auto/openapi-sync-C005-20260419-r49222
Closed

feat(gooddata-sdk): [AUTO] Add resolveLlmProviders endpoint and ResolvedLlm polymorphic schemas#1554
yenkins-admin wants to merge 1 commit intomasterfrom
auto/openapi-sync-C005-20260419-r49222

Conversation

@yenkins-admin
Copy link
Copy Markdown
Contributor

Summary

Added SDK wrapper for the new resolveLlmProviders GET endpoint (/api/v1/actions/workspaces/{workspaceId}/ai/resolveLlmProviders). Created four new model classes (CatalogResolvedLlms, CatalogResolvedLlmEndpoint, CatalogResolvedLlmProvider, CatalogResolvedLlmModelItem) in a new entity_model file, added resolve_llm_providers() service method to CatalogWorkspaceContentService, exported all new classes from gooddata_sdk/init.py, and added pure-unit tests covering the polymorphic parsing logic.

Impact: new_feature | Services: gooddata-afm-client

Files changed

  • packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/resolved_llm.py
  • packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/content_service.py
  • packages/gooddata-sdk/src/gooddata_sdk/__init__.py
  • packages/gooddata-sdk/tests/catalog/test_resolved_llm.py

Agent decisions

Decisions (4)

Service method placement — Added resolve_llm_providers() to CatalogWorkspaceContentService

  • Alternatives: Add to CatalogWorkspaceService (workspace management), Add to CatalogOrganizationService alongside LLM provider CRUD
  • Why: The endpoint is workspace-scoped (/workspaces/{id}/ai/resolveLlmProviders), matching other workspace content action methods already in this service (compute_valid_objects, get_label_elements, get_dependent_entities_graph).

Polymorphic oneOf parsing (endpoint vs provider) — Check for presence of the 'models' key in the raw data dict to dispatch to CatalogResolvedLlmProvider vs CatalogResolvedLlmEndpoint

  • Alternatives: Use a discriminator field (none exists), Merge both subtypes into a single class with optional models field
  • Why: No discriminator field exists in the spec. The only structural difference between the two subtypes is the presence of 'models' in ResolvedLlmProvider. Consistent with how llm_provider.py handles similar type detection.

client_class() with deferred imports — Lazy-import generated client classes inside client_class() static methods to avoid circular imports at module load time

  • Alternatives: Top-level imports from gooddata_api_client
  • Why: Matches existing pattern in graph.py and other entity_model files.

Test type: unit vs integration — Pure unit tests (no mocks, no cassettes)

  • Alternatives: Integration test with VCR cassette (unnecessary for pure parsing logic)
  • Why: The only non-trivial logic is dict-based type dispatch in CatalogResolvedLlms.from_api(). Unit tests cover all branching paths with zero external dependencies.
Assumptions to verify (3)
  • The API returns 'models' only for provider-backed configurations and never for endpoint-backed ones, making the 'models' key a reliable discriminator.
  • When _check_return_type=False, the actions_api.resolve_llm_providers() return value supports dict-style .get() access (consistent with how other _check_return_type=False calls are consumed in the codebase).
  • The 'data' field is absent or null when no LLM is configured, rather than raising an HTTP error.
Risks (2)
  • If the live backend returns a 404 or non-200 when no LLM is configured (instead of {data: null}), the service method will raise rather than returning CatalogResolvedLlms(data=None).
  • If the API response dict uses a key other than 'models' the type-dispatch heuristic would break silently (parsing as endpoint instead of provider).
Layers touched (3)
  • entity_model — New file with CatalogResolvedLlms, CatalogResolvedLlmEndpoint, CatalogResolvedLlmProvider, CatalogResolvedLlmModelItem
    • packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/resolved_llm.py
  • public_api — Added resolve_llm_providers() to CatalogWorkspaceContentService; exported 4 new classes from init.py
    • packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/content_service.py
    • packages/gooddata-sdk/src/gooddata_sdk/__init__.py
  • tests — Unit tests for polymorphic from_api() parsing — no cassettes needed
    • packages/gooddata-sdk/tests/catalog/test_resolved_llm.py

Source commits (gdc-nas)

  • 699c75c Merge pull request #21420 from hkad98/jkd/resolve-llm-provider
OpenAPI diff
diff --git a/microservices/afm-exec-api/src/test/resources/openapi/open-api-spec.json
@@ -3825,20 +3825,38 @@
-      "ResolvedLlmEndpoint" : {
+      "ResolvedLlm" : {
+        "description" : "The resolved LLM configuration, or null if none is configured.",
         "properties" : {
           "id" : { "type" : "string" },
           "title" : { "type" : "string" }
         },
         "required" : [ "id", "title" ],
         "type" : "object"
       },
+      "ResolvedLlmEndpoint" : {
+        "allOf" : [ { "$ref" : "#/components/schemas/ResolvedLlm" }, {
+          "properties" : {
+            "id" : { "description" : "Endpoint Id", "type" : "string" },
+            "title" : { "description" : "Endpoint Title", "type" : "string" }
+          }, "type" : "object"
+        } ],
+        "required" : [ "id", "title" ],
+        "type" : "object"
+      },
+      "ResolvedLlmProvider" : {
+        "allOf" : [ { "$ref" : "#/components/schemas/ResolvedLlm" }, {
+          "properties" : {
+            "id" : { "description" : "Provider Id", "type" : "string" },
+            "models" : { "items" : { "$ref" : "#/components/schemas/LlmModel" }, "maxItems" : 1, "minItems" : 1, "type" : "array" },
+            "title" : { "description" : "Provider Title", "type" : "string" }
+          }, "type" : "object"
+        } ],
+        "required" : [ "id", "models", "title" ],
+        "type" : "object"
+      },
+      "ResolvedLlms" : {
+        "properties" : {
+          "data" : { "oneOf" : [ { "$ref" : "#/components/schemas/ResolvedLlmEndpoint" }, { "$ref" : "#/components/schemas/ResolvedLlmProvider" } ] }
+        },
+        "type" : "object"
+      },
@@ -5987,6 +6044,36 @@
+    "/api/v1/actions/workspaces/{workspaceId}/ai/resolveLlmProviders" : {
+      "get" : {
+        "description" : "Resolves the active LLM configuration for the given workspace.",
+        "operationId" : "resolveLlmProviders",
+        "parameters" : [ { "description" : "Workspace identifier", "in" : "path", "name" : "workspaceId", "required" : true, "schema" : { "pattern" : "^(?!\\.)[.A-Za-z0-9_-]{1,255}$", "type" : "string" } } ],
+        "responses" : { "200" : { "content" : { "application/json" : { "schema" : { "$ref" : "#/components/schemas/ResolvedLlms" } } }, "description" : "OK" } },
+        "summary" : "Get Active LLM configuration for this workspace",
+        "tags" : [ "Smart Functions", "actions" ]
+      }
+    },

Workflow run


Generated by SDK OpenAPI Sync workflow

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 19, 2026

Codecov Report

❌ Patch coverage is 83.33333% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.68%. Comparing base (37d0593) to head (7393758).

Files with missing lines Patch % Lines
...sdk/catalog/workspace/entity_model/resolved_llm.py 85.45% 8 Missing ⚠️
.../gooddata_sdk/catalog/workspace/content_service.py 50.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1554      +/-   ##
==========================================
+ Coverage   78.66%   78.68%   +0.01%     
==========================================
  Files         230      231       +1     
  Lines       15405    15465      +60     
==========================================
+ Hits        12118    12168      +50     
- Misses       3287     3297      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tychtjan tychtjan closed this Apr 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants