Skip to content

Add gateway implementations for custom LLM provider feature#2456

Open
Tharanidk wants to merge 2 commits into
wso2:mainfrom
Tharanidk:templates_gateway
Open

Add gateway implementations for custom LLM provider feature#2456
Tharanidk wants to merge 2 commits into
wso2:mainfrom
Tharanidk:templates_gateway

Conversation

@Tharanidk

Copy link
Copy Markdown
Contributor

Purpose

Extends the LLM provider template model with three new spec fields: groupId, managedBy, and version, and wires them through the gateway-controller management API.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 957b62d5-f9eb-4bd6-84cb-7769d78fedfe

📥 Commits

Reviewing files that changed from the base of the PR and between fd188d2 and 4d2febd.

📒 Files selected for processing (2)
  • gateway/examples/llm-provider-template.yaml
  • gateway/gateway-controller/api/management-openapi.yaml
✅ Files skipped from review due to trivial changes (1)
  • gateway/examples/llm-provider-template.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • gateway/gateway-controller/api/management-openapi.yaml

📝 Walkthrough

Walkthrough

This PR adds groupId, managedBy, and version metadata to LLM provider templates across the gateway controller, updates the OpenAPI and generated model definitions, refreshes default template YAMLs and the example template, and adds getter and parsing normalization logic with tests.

Changes

LLM provider template metadata fields

Layer / File(s) Summary
OpenAPI schema and generated Go model updates
gateway/gateway-controller/api/management-openapi.yaml, gateway/gateway-controller/pkg/api/management/generated.go
Adds groupId, managedBy, and version to LLMProviderTemplateData and regenerates the embedded Swagger spec bytes.
Default provider template YAML updates
gateway/gateway-controller/default-llm-provider-templates/*.yaml, gateway/examples/llm-provider-template.yaml
Adds groupId, managedBy, and version under spec for the default provider templates and the example template.
StoredLLMProviderTemplate getter methods and defaults
gateway/gateway-controller/pkg/models/llm_provider_template.go, gateway/gateway-controller/pkg/models/llm_provider_template_test.go
Adds default constants and getter methods for groupId, version, and managedBy, with tests for fallback and shared-group behavior.
Template default normalization during parsing
gateway/gateway-controller/pkg/utils/llm_deployment.go, gateway/gateway-controller/pkg/utils/llm_deployment_test.go
Normalizes missing template metadata during parsing and verifies defaulting and preserved explicit values in tests.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • wso2/api-platform#380: Both PRs touch gateway/examples/llm-provider-template.yaml and the LLM provider template shape.
  • wso2/api-platform#491: Shares the StoredLLMProviderTemplate metadata/handle logic that this PR extends with groupId, version, and managedBy.
  • wso2/api-platform#2316: Builds on the same LLM provider template metadata additions and schema changes introduced here.

Suggested reviewers: Krishanx92, renuka-fernando, RakhithaRR, Tharsanan1

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description only covers Purpose and is missing the required Goals, Approach, tests, security checks, samples, related PRs, and test environment sections. Expand the PR description to fill all template sections, especially Goals, Approach, Automation tests, Security checks, Samples, Related PRs, and Test environment.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is related to the main change, though it is broader than the specific LLM provider template updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
gateway/gateway-controller/api/management-openapi.yaml (1)

5569-5588: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Consider adding a pattern constraint on version.

Other version fields in this spec (APIConfigData.version, LLMProviderConfigData.version, LLMProxyConfigData.version) enforce pattern: '^v\d+\.\d+$', and Policy.version enforces '^v\d+$'. The new LLMProviderTemplateData.version field has no format constraint, so malformed values (e.g., 1.0, latest) could be accepted and persisted as template metadata.

📝 Suggested diff
         version:
           type: string
           description: |
             Template content version (e.g. v1.0). Multiple versions of the same
             groupId can coexist; defaults to v1.0 when omitted.
+          pattern: '^v\d+\.\d+$'
           example: v1.0
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gateway/gateway-controller/api/management-openapi.yaml` around lines 5569 -
5588, The new LLMProviderTemplateData.version field is missing the same format
validation used by other version fields in the OpenAPI spec. Update the version
property in management-openapi.yaml to add a pattern constraint consistent with
the existing version schema (matching the other template/config version fields),
so only valid version strings are accepted and persisted; keep the change
localized to the LLMProviderTemplateData.version definition.
gateway/gateway-controller/pkg/models/llm_provider_template.go (1)

46-72: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Correct fallback behavior; consider extracting shared helper.

GetGroupID, GetVersion, and GetManagedBy each repeat the same nil-check/trim/fallback pattern. A shared private helper would reduce duplication and keep the trimming semantics consistent if this logic changes later.

♻️ Suggested refactor
+func stringOrDefault(v *string, fallback string) string {
+	if v != nil {
+		if trimmed := strings.TrimSpace(*v); trimmed != "" {
+			return trimmed
+		}
+	}
+	return fallback
+}
+
 func (t *StoredLLMProviderTemplate) GetGroupID() string {
-	if t.Configuration.Spec.GroupId != nil {
-		if v := strings.TrimSpace(*t.Configuration.Spec.GroupId); v != "" {
-			return v
-		}
-	}
-	return t.Configuration.Metadata.Name
+	return stringOrDefault(t.Configuration.Spec.GroupId, t.Configuration.Metadata.Name)
 }

 func (t *StoredLLMProviderTemplate) GetVersion() string {
-	if t.Configuration.Spec.Version != nil {
-		if v := strings.TrimSpace(*t.Configuration.Spec.Version); v != "" {
-			return v
-		}
-	}
-	return DefaultTemplateVersion
+	return stringOrDefault(t.Configuration.Spec.Version, DefaultTemplateVersion)
 }

 func (t *StoredLLMProviderTemplate) GetManagedBy() string {
-	if t.Configuration.Spec.ManagedBy != nil {
-		if p := strings.TrimSpace(*t.Configuration.Spec.ManagedBy); p != "" {
-			return p
-		}
-	}
-	return DefaultTemplateManagedBy
+	return stringOrDefault(t.Configuration.Spec.ManagedBy, DefaultTemplateManagedBy)
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gateway/gateway-controller/pkg/models/llm_provider_template.go` around lines
46 - 72, GetGroupID, GetVersion, and GetManagedBy all duplicate the same
nil-check, trim, and fallback logic in StoredLLMProviderTemplate. Extract that
shared behavior into a private helper on StoredLLMProviderTemplate that accepts
the optional string pointer and fallback value, then have all three methods
delegate to it so the trimming semantics stay consistent and future changes only
need to be made in one place.
gateway/gateway-controller/pkg/utils/llm_deployment.go (1)

595-616: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Correct defaulting logic and placement.

normalizeTemplateDefaults is invoked after parsing and before render/validation, so validation and returned config both reflect the defaults — matches the documented OpenAPI fallback contract (groupId → metadata.name, version → v1.0, managedBy → customer) and is covered by tests.

Note: the nil-check/trim/fallback logic here duplicates the same pattern in StoredLLMProviderTemplate.GetGroupID/GetVersion/GetManagedBy (gateway/gateway-controller/pkg/models/llm_provider_template.go). Consider exposing a small shared helper from models (e.g., a NormalizeOptionalString(v *string, fallback string) *string) that both this function and the getters can use, to avoid the fallback semantics drifting between the two packages over time.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gateway/gateway-controller/pkg/utils/llm_deployment.go` around lines 595 -
616, The defaulting logic in normalizeTemplateDefaults is duplicated in
StoredLLMProviderTemplate.GetGroupID/GetVersion/GetManagedBy, which risks the
fallback behavior drifting over time. Extract the nil/trim/fallback handling
into a shared helper in models, such as a NormalizeOptionalString-style
function, and have both normalizeTemplateDefaults and the
StoredLLMProviderTemplate getters use that shared helper so groupId, version,
and managedBy stay consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@gateway/gateway-controller/api/management-openapi.yaml`:
- Around line 5569-5588: The new LLMProviderTemplateData.version field is
missing the same format validation used by other version fields in the OpenAPI
spec. Update the version property in management-openapi.yaml to add a pattern
constraint consistent with the existing version schema (matching the other
template/config version fields), so only valid version strings are accepted and
persisted; keep the change localized to the LLMProviderTemplateData.version
definition.

In `@gateway/gateway-controller/pkg/models/llm_provider_template.go`:
- Around line 46-72: GetGroupID, GetVersion, and GetManagedBy all duplicate the
same nil-check, trim, and fallback logic in StoredLLMProviderTemplate. Extract
that shared behavior into a private helper on StoredLLMProviderTemplate that
accepts the optional string pointer and fallback value, then have all three
methods delegate to it so the trimming semantics stay consistent and future
changes only need to be made in one place.

In `@gateway/gateway-controller/pkg/utils/llm_deployment.go`:
- Around line 595-616: The defaulting logic in normalizeTemplateDefaults is
duplicated in StoredLLMProviderTemplate.GetGroupID/GetVersion/GetManagedBy,
which risks the fallback behavior drifting over time. Extract the
nil/trim/fallback handling into a shared helper in models, such as a
NormalizeOptionalString-style function, and have both normalizeTemplateDefaults
and the StoredLLMProviderTemplate getters use that shared helper so groupId,
version, and managedBy stay consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 38d5cf89-042b-4b5e-bbf7-216ed87092df

📥 Commits

Reviewing files that changed from the base of the PR and between eb1d7be and fd188d2.

📒 Files selected for processing (13)
  • gateway/gateway-controller/api/management-openapi.yaml
  • gateway/gateway-controller/default-llm-provider-templates/anthropic-template.yaml
  • gateway/gateway-controller/default-llm-provider-templates/awsbedrock-template.yaml
  • gateway/gateway-controller/default-llm-provider-templates/azureaifoundry-template.yaml
  • gateway/gateway-controller/default-llm-provider-templates/azureopenai-template.yaml
  • gateway/gateway-controller/default-llm-provider-templates/gemini-template.yaml
  • gateway/gateway-controller/default-llm-provider-templates/mistral-template.yaml
  • gateway/gateway-controller/default-llm-provider-templates/openai-template.yaml
  • gateway/gateway-controller/pkg/api/management/generated.go
  • gateway/gateway-controller/pkg/models/llm_provider_template.go
  • gateway/gateway-controller/pkg/models/llm_provider_template_test.go
  • gateway/gateway-controller/pkg/utils/llm_deployment.go
  • gateway/gateway-controller/pkg/utils/llm_deployment_test.go

Comment thread gateway/gateway-controller/api/management-openapi.yaml
const DefaultTemplateVersion = "v1.0"

// DefaultTemplateManagedBy is used when a template does not declare managedBy.
const DefaultTemplateManagedBy = "customer"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @malinthaprasan

For Custom Policies, we are using.

managedBy: customer

Should we use the same for the LLM Provider template?
Or something like other?

managedBy: other

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use one approach ideally. Do we see any issue in managedBy: wso2/customer pair?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mm, yeah +1 for a consistent approach.
Ok. In the last code review meeting, we discussed changing this.

name: my-llm-provider-template
spec:
displayName: OpenAI
groupId: anthropic

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shall we change this to openai for consistency?

thivindu
thivindu previously approved these changes Jul 6, 2026
@thivindu thivindu dismissed their stale review July 6, 2026 12:04

Requested changes

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.

4 participants