feat: add SAP AI Core provider via Orchestration Service#1610
Open
Huimintai wants to merge 6 commits intokagent-dev:mainfrom
Open
feat: add SAP AI Core provider via Orchestration Service#1610Huimintai wants to merge 6 commits intokagent-dev:mainfrom
Huimintai wants to merge 6 commits intokagent-dev:mainfrom
Conversation
Add SAPAICore as a new model provider that routes through SAP AI Core's Orchestration Service, providing unified access to all model families (Anthropic, OpenAI, Gemini, Amazon, Meta, Mistral, DeepSeek, Qwen, etc.) via a single endpoint. Go changes: - Add ModelProviderSAPAICore enum and SAPAICoreConfig CRD struct - Add SAPAICore ADK model type with MarshalJSON/ParseModel/ModelToEmbeddingConfig - Add translateModel case with OAuth2 credential injection via K8s Secret - Add HTTP API support (create/update/list/get) with proper flatten - Add CEL validation rules (XValidation, apiKeySecretKey exemption) - Add 48 supported models from Orchestration Service - Add SAP_AI_CORE_CLIENT_ID/SECRET env var registration Python changes: - Add KAgentSAPAICoreLlm (BaseLlm) with Orchestration protocol support - Async OAuth2 token management (asyncio.to_thread, threading.Lock) - Cached httpx.AsyncClient with TLS configuration - Auto-discovery of orchestration deployment URL (1h TTL) - Automatic retry on 401/403/404/502/503/504 with cache invalidation - Full tool call support (streaming + non-streaming) - api_key_passthrough support via set_passthrough_key() UI changes: - Add SAPAICore to provider type union, combobox icons, and form handling - Add SAPAICoreConfigPayload for create/update flows Signed-off-by: Huimin Tai <huimin.tai@sap.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request adds comprehensive support for SAP AI Core as a new model provider. The implementation enables users to access all SAP AI Core model families (Anthropic, OpenAI, Gemini, Amazon, Meta, Mistral, DeepSeek, Qwen, etc.) through a unified Orchestration Service endpoint.
Changes:
- Adds SAPAICore model provider enum and configuration types across Go, Python, and UI layers
- Implements KAgentSAPAICoreLlm with full Orchestration protocol support, OAuth2 token caching, and automatic deployment URL discovery
- Integrates OAuth2 credential injection via Kubernetes secrets for secure authentication
- Adds HTTP API endpoints (create/update/list/get) with proper configuration flattening
- Implements CEL validation rules for provider-specific configuration enforcement
- Registers 48 supported models from SAP's Orchestration Service
- Adds environment variable registration for SAP_AI_CORE_CLIENT_ID and SAP_AI_CORE_CLIENT_SECRET
- Updates UI components to include SAPAICore provider with appropriate icons and form handling
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| go/api/v1alpha2/modelconfig_types.go | Defines SAPAICoreConfig struct with BaseURL, ResourceGroup, and AuthURL fields; adds validation rules for provider configuration |
| go/api/adk/types.go | Adds SAPAICore model type with JSON marshaling and embedding config support |
| go/core/internal/controller/translator/agent/adk_api_translator.go | Implements translation of K8s ModelConfig resources to ADK SAPAICore models with OAuth2 secret injection |
| go/core/internal/httpserver/handlers/modelconfig.go | Adds SAPAICore parameter handling in create, update, list, and get endpoints |
| go/core/internal/httpserver/handlers/modelproviderconfig.go | Registers SAPAICore in supported provider list with required/optional field metadata |
| go/core/internal/httpserver/handlers/models.go | Lists 48 supported models from SAP Orchestration Service with function calling capabilities |
| go/core/pkg/env/providers.go | Registers SAP_AI_CORE_CLIENT_ID and SAP_AI_CORE_CLIENT_SECRET environment variables |
| go/api/httpapi/types.go | Adds SAPAICoreParams to create/update model config request types |
| python/packages/kagent-adk/src/kagent/adk/types.py | Adds SAPAICore Pydantic model and includes it in ModelUnion |
| python/packages/kagent-adk/src/kagent/adk/models/_sap_ai_core.py | Implements KAgentSAPAICoreLlm with async OAuth2 token management, TLS configuration, deployment URL discovery, and stream/non-stream request handling |
| python/packages/kagent-adk/src/kagent/adk/models/init.py | Exports KAgentSAPAICoreLlm from models package |
| ui/src/types/index.ts | Adds SAPAICoreConfigPayload interface for UI form handling |
| ui/src/lib/providers.ts | Registers SAPAICore in provider list with documentation links |
| ui/src/components/ProviderCombobox.tsx | Adds SAPAICore to provider icon mapping |
| ui/src/components/ModelProviderCombobox.tsx | Adds SAPAICore to model provider icon mapping |
| ui/src/components/icons/SAPAICore.tsx | Adds SAPAICore provider SVG icon component |
| ui/src/app/models/new/page.tsx | Adds SAPAICore payload handling in model configuration form |
| helm/kagent-crds/templates/kagent.dev_modelproviderconfigs.yaml | Updates CRD to include SAPAICore enum value |
| helm/kagent-crds/templates/kagent.dev_modelconfigs.yaml | Adds SAPAICore configuration schema and validation rules to CRD |
| go/api/config/crd/bases/*.yaml | Corresponding CRD base definitions for SAPAICore support |
| go/api/v1alpha2/zz_generated.deepcopy.go | Auto-generated deep copy functions for SAPAICoreConfig |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Author
7c83010 to
71e796a
Compare
…skills (kagent-dev#1551) ## Problem When an `Agent` spec includes a container `securityContext` with `allowPrivilegeEscalation: false` (PSS Restricted profile) **and** the agent has `spec.skills.refs` configured, the controller generates an invalid pod spec: ``` cannot set allowPrivilegeEscalation to false and privileged to true ``` Kubernetes rejects this combination at admission time, leaving the agent stuck in a reconciliation loop with all pods failing to start. ## Root cause `buildManifest()` sets `needSandbox = true` when skills are present (because skills use `BashTool` which calls `srt` → bubblewrap for sandboxing), then blindly sets `Privileged: true` on whatever `securityContext` is provided — including one that already has `AllowPrivilegeEscalation: false`. The securityContext merge did not check for this conflict before setting `Privileged: true`. ## Fix Add a helper `allowPrivilegeEscalationExplicitlyFalse()` that detects when the user has opted out of privilege escalation, and skip `Privileged: true` in that case. When `Privileged` is withheld, `srt` degrades gracefully: on modern kernels (EKS, GKE, AL2023 ≥ 5.10) that have unprivileged user namespaces enabled (`user.max_user_namespaces > 0`), bubblewrap can still create sandboxes using `clone(CLONE_NEWUSER)` without requiring a privileged seccomp profile. > **Note on seccomp**: The containerd `RuntimeDefault` seccomp profile blocks > `clone(CLONE_NEWUSER)` without `CAP_SYS_ADMIN`. Users who need full bwrap > sandbox execution (running bash scripts inside skills) must additionally > provide a custom `seccompProfile: Localhost` with a profile that allows > user namespace syscalls. This PR makes agent deployment possible for > PSS-Restricted namespaces; the seccomp tuning is an operational concern > separate from this bug. ## Behaviour matrix | Agent spec | needSandbox | Result | |---|---|---| | skills or executeCode, **no** custom securityContext | `true` | `Privileged: true` — full bwrap sandbox (unchanged) | | skills + `allowPrivilegeEscalation: false` | `true` | No `Privileged` — srt uses user-namespace mode | | executeCode + `allowPrivilegeEscalation: false` | `true` | No `Privileged` — srt uses user-namespace mode | | No skills, no executeCode | `false` | No securityContext created (unchanged) | ## Changes ### `go/core/internal/controller/translator/agent/adk_api_translator.go` - Add comment explaining *why* `needSandbox = true` for skills (BashTool → srt → bwrap) - Fix securityContext merge: guard `Privileged: true` with `allowPrivilegeEscalationExplicitlyFalse()` - Add `allowPrivilegeEscalationExplicitlyFalse()` helper ### `go/core/internal/controller/translator/agent/security_context_test.go` - Replace `TestSecurityContext_WithSandbox` (which tested an internally contradictory state) with two focused tests: - `TestSecurityContext_SkillsDefaultPrivilegedSandbox`: no custom securityContext → `Privileged: true` (default sandbox path) - `TestSecurityContext_SkillsPSSRestricted`: `allowPrivilegeEscalation: false` → no `Privileged`, original securityContext fields preserved intact ## Testing ```bash cd go go test -race -skip 'TestE2E.*' -v ./core/internal/controller/translator/agent/... ``` All existing tests pass. Two new tests cover both code paths. ## Related - PSS Restricted policy: https://kubernetes.io/docs/concepts/security/pod-security-standards/ - Bubblewrap user namespaces: https://github.com/containers/bubblewrap#usage Signed-off-by: skhedim <sebastien.khedim@gmail.com> Co-authored-by: Eitan Yarmush <eitan.yarmush@solo.io>
…#1604) ## Summary Closes kagent-dev#1560 The bundled PostgreSQL deployment now ships with Pod Security Admission restricted-compliant defaults and exposes both pod-level and container-level security context values for overrides. - add default `RuntimeDefault` seccomp profiles for the bundled PostgreSQL pod and container - drop all container capabilities by default while keeping `allowPrivilegeEscalation: false` - move the bundled PostgreSQL pod and container security contexts into chart values so users can customize them without patching templates - extend Helm unit coverage for the new defaults and override paths ## Testing - `make helm-version` - `helm unittest helm/kagent` - `helm lint helm/kagent` Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> Co-authored-by: Eitan Yarmush <eitan.yarmush@solo.io>
Chromatic allows us to visually review UI changes: https://www.chromatic.com/builds?appId=69ccd5e5ca68b9aa5a54b890 --------- Signed-off-by: Peter Jausovec <peter.jausovec@solo.io>
## Summary - Bumps `github.com/a2aproject/a2a-go` from v0.3.6 to v0.3.13 - Updates `KAgentTaskStore.Save` to match the new `a2asrv.TaskStore` interface which added a `prev *a2a.Task` parameter Supersedes kagent-dev#1598 (dependabot PR that fails CI due to the breaking interface change). ## Test plan - [ ] CI go-lint passes - [ ] CI go-unit-tests pass - [ ] CI build (golang-adk) passes Signed-off-by: Jaison Paul <paul.jaison@gmail.com>
Implement SAPAICoreModel in the Go ADK runtime, enabling the golang-adk image to use SAP AI Core models via the Orchestration Service. - Add SAPAICoreModel with OAuth2 token management (thread-safe cache) - Add automatic orchestration deployment URL discovery (1h TTL) - Implement model.LLM interface (GenerateContent) with Orchestration protocol: modules format request, orchestration_result/final_result SSE stream parsing - Add retry logic on 401/403/404/502/503/504 with cache invalidation - Add *adk.SAPAICore case in CreateLLM() Verified with go vet, existing unit tests, and oneshot E2E against live SAP AI Core (both streaming and non-streaming). Signed-off-by: Huimin Tai <huimin.tai@sap.com>
71e796a to
1cfa50a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Add SAPAICore as a new model provider that routes through SAP AI Core's Orchestration Service, providing unified access to all model families (Anthropic, OpenAI, Gemini, Amazon, Meta, Mistral, DeepSeek, Qwen, etc.) via a single endpoint.
Go changes:
Python changes:
UI changes: