Skip to content

feat(gooddata-sdk): [AUTO] Add resolveLlmProviders endpoint and ResolvedLlmProvider schemas#1552

Closed
yenkins-admin wants to merge 3 commits intomasterfrom
auto/openapi-sync-C006-20260419-r33866
Closed

feat(gooddata-sdk): [AUTO] Add resolveLlmProviders endpoint and ResolvedLlmProvider schemas#1552
yenkins-admin wants to merge 3 commits intomasterfrom
auto/openapi-sync-C006-20260419-r33866

Conversation

@yenkins-admin
Copy link
Copy Markdown
Contributor

Summary

Added SDK support for the new resolveLlmProviders endpoint. Created CatalogResolvedLlms, CatalogResolvedLlmEndpoint, CatalogResolvedLlmProvider, and CatalogResolvedLlmModel model classes in a new file resolved_llm.py. Added resolve_llm_providers(workspace_id) method to CatalogWorkspaceContentService. Exported all new classes from gooddata_sdk/__init__.py. Added 3 unit tests (all passing) and 1 integration test requiring a cassette.

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_catalog_workspace_content.py

Agent decisions

Decisions (3)

discriminating oneOf data field — Use presence of 'models' key to distinguish CatalogResolvedLlmProvider from CatalogResolvedLlmEndpoint

  • Alternatives: Add a 'type' field to the model, Try to structure both and catch errors
  • Why: The OpenAPI diff shows models is required in ResolvedLlmProvider but absent in ResolvedLlmEndpoint; checking for the key is the only reliable runtime discriminator since there is no explicit type field.

placement of new model file — catalog/workspace/entity_model/resolved_llm.py (workspace domain)

  • Alternatives: Place under organization domain alongside CatalogLlmProvider
  • Why: The endpoint is workspace-scoped (/api/v1/actions/workspaces/{workspaceId}/...) and the response does not follow JSON:API entity structure, so it belongs in the workspace entity_model layer rather than the organization domain.

API call style — Call resolve_llm_providers with _check_return_type=False then call .to_dict()

  • Alternatives: Call without _check_return_type=False and pass API object directly to from_api
  • Why: The response contains a oneOf ResolvedLlmsData whose schema validation may fail with type checking when the server returns a ResolvedLlmProvider (contains models list). Using _check_return_type=False avoids this and .to_dict() normalises to a plain dict for custom from_api() parsing.
Assumptions to verify (3)
  • The 'models' field presence is a reliable discriminator between ResolvedLlmProvider and ResolvedLlmEndpoint at runtime (no case where both have models or neither do)
  • The API returns null/missing 'data' field when no LLM is configured for the workspace
  • Pre-existing type errors in filter.py (3 diagnostics about EmptyValueHandling) are not related to this change and were present before
Risks (2)
  • test_resolve_llm_providers_integration: will be skipped/fail if the test environment has no LLM provider configured — the assertion checks result.data is None or a valid typed object, so it should be safe either way
  • test_resolve_llm_providers_integration: if the server returns ResolvedLlmEndpoint (ENABLE_LLM_ENDPOINT_REPLACEMENT disabled) the cassette will capture an endpoint response; test logic handles both shapes
Layers touched (4)
  • entity_model — New file with CatalogResolvedLlms, CatalogResolvedLlmEndpoint, CatalogResolvedLlmProvider, CatalogResolvedLlmModel
    • packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/entity_model/resolved_llm.py
  • public_api — Export of all 4 new classes
    • packages/gooddata-sdk/src/gooddata_sdk/__init__.py
  • converter — resolve_llm_providers() service method added to CatalogWorkspaceContentService
    • packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/content_service.py
  • tests — 3 unit tests for model deserialization + 1 integration test needing a cassette
    • packages/gooddata-sdk/tests/catalog/test_catalog_workspace_content.py

Source commits (gdc-nas)

  • 699c75c Merge pull request #21420 from hkad98/jkd/resolve-llm-provider
OpenAPI diff
--- a/gooddata-afm-client.json
+++ b/gooddata-afm-client.json
@@ -4765,14 +4871,13 @@
-      "ResolvedLlmEndpoint": {
+      "ResolvedLlm": {
+        "description": "The resolved LLM configuration, or null if none is configured.",
         "properties": {
           "id": {
-            "description": "Endpoint Id",
             "type": "string"
           },
           "title": {
-            "description": "Endpoint Title",
             "type": "string"
           }
@@ -4782,6 +4887,31 @@
+      "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"
+      },
@@ -4794,6 +4924,55 @@
+      "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"
+      },
@@ -7150,6 +7452,41 @@
+    "/api/v1/actions/workspaces/{workspaceId}/ai/resolveLlmProviders": {
+      "get": {
+        "description": "Resolves the active LLM configuration for the given workspace. When the ENABLE_LLM_ENDPOINT_REPLACEMENT feature flag is enabled, returns LLM Providers with their associated models. Otherwise, falls back to the legacy LLM Endpoints.",
+        "operationId": "resolveLlmProviders",
+        "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

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.72%. Comparing base (37d0593) to head (76047d6).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1552      +/-   ##
==========================================
+ Coverage   78.66%   78.72%   +0.06%     
==========================================
  Files         230      231       +1     
  Lines       15405    15450      +45     
==========================================
+ Hits        12118    12163      +45     
  Misses       3287     3287              

☔ 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.

The implement agent writes its message log to transcript-implement-C006.jsonl.
This file was accidentally committed by 'git add -A' in the deliver step of
sdk-py-openapi-sync.yml (gdc-nas).  The workflow has been patched to write
transcripts outside the sdk/ checkout so future auto-PRs won't contain them.
@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