diff --git a/docs-site/content/kagent/1.x/agents/agent-harness.md b/docs-site/content/kagent/1.x/agents/agent-harness.md index 7b628a92..b011c34f 100644 --- a/docs-site/content/kagent/1.x/agents/agent-harness.md +++ b/docs-site/content/kagent/1.x/agents/agent-harness.md @@ -26,10 +26,6 @@ spec: env: - name: LOG_LEVEL value: info - - name: MY_API_KEY - credentialRef: - name: my-secret - key: api-key substrate: workerPoolRef: name: kagent-default @@ -50,7 +46,7 @@ EOF | `workload.image` | Yes | The runtime image, pinned by `sha256` digest. A tag alone is rejected, because a revision must be reproducible. | | `workload.command` | For `byo` | Overrides the image entrypoint, up to 32 entries. Required for the `byo` runtime, optional otherwise. | | `workload.args` | No | Overrides the image arguments, up to 64 entries. | -| `env` | No | Environment variables for the runtime, up to 100. Each entry sets either a literal `value` or a `credentialRef` naming a key in a same-namespace Secret, never both. | +| `env` | No | Environment variables for the runtime, up to 100. Each entry sets a literal `value`. A `credentialRef` is accepted by the API and then rejected at compile time on every runtime, so put credentials on a ModelConfig or a RemoteMCPServer instead. For more information, see [About model providers]({{< link path="setup/model-providers/about-model-providers#credentials-that-do-not-compile" >}}). | | `substrate.workerPoolRef.name` | Yes | The {{< gloss "WorkerPool" >}}WorkerPool{{< /gloss >}} that this Harness's Actors are scheduled onto. An operator must provision one before any agent can run. | | `substrate.snapshotPolicy.location` | Yes | The object storage location for Actor {{< gloss "Snapshot" >}}snapshots{{< /gloss >}}. | | `allowedAgentTemplates.selector` | No | A label selector naming which AgentTemplates this Harness admits. Omitting it admits none, which makes the Harness unusable. Admission is a one-way match. An {{< gloss "AgentTemplate" >}}AgentTemplate{{< /gloss >}} has no field naming a Harness, so whoever controls a Harness's selector decides what it accepts. | @@ -97,14 +93,16 @@ The runtime that a Harness selects decides which ModelConfig its AgentTemplates | `OpenAI` | ✅ | ✅ | ✅ | ❌ | | `Anthropic` | ✅ | ✅ | ❌ | ✅ | | `Bedrock` | ✅ | ✅ | ✅ | ✅ | -| `AnthropicVertexAI` | ❌ | ❌ | ❌ | ✅ | +| `AnthropicVertexAI` | ❌ | ❌ | ❌ | ❌ | | `GeminiVertexAI` | ❌ | ❌ | ❌ | ❌ | | `AzureOpenAI` | ✅ | ✅ | ❌ | ❌ | | `Gemini` | ✅ | ✅ | ❌ | ❌ | | `Ollama` | ✅ | ✅ | ❌ | ❌ | -| `SAPAICore` | ✅ | ✅ | ❌ | ❌ | +| `SAPAICore` | ❌ | ❌ | ❌ | ❌ | | `Foundry` | ✅ | ✅ | ❌ | ❌ | +`AnthropicVertexAI`, `GeminiVertexAI`, and `SAPAICore` run on no runtime today. Each authenticates with a credential that the egress gateway cannot place in an HTTP header, so kagent rejects the ModelConfig before it compiles. For the alternatives, see [About model providers]({{< link path="setup/model-providers/about-model-providers#credentials-that-do-not-compile" >}}). + Some supported combinations still carry restrictions. | Combination | Restriction | @@ -113,10 +111,10 @@ Some supported combinations still carry restrictions. | `codex` with `Bedrock` | Accepts only OpenAI `gpt-*` model IDs, and no `bedrock` settings beyond `region`. | | `claude` with `Anthropic` | Accepts no `anthropic` settings beyond `baseUrl`. | | `claude` with `Bedrock` | Accepts no `bedrock` settings beyond `region`. | -| `claude` with `AnthropicVertexAI` | Accepts only `projectID` and `location`. The Secret must hold a `service_account` key whose `project_id` matches and whose `token_uri` is `https://oauth2.googleapis.com`. | +| `Bedrock` on any runtime | The Secret must hold an `AWS_BEARER_TOKEN_BEDROCK` key. A Secret of IAM access keys is rejected, because IAM signs each request locally. | > [!IMPORTANT] -> Neither `codex` nor `claude` accepts a ModelConfig that sets `defaultHeaders`, `tls`, or `apiKeyPassthrough`. Separately, the `kagent` and `byo` runtimes cannot use a ModelConfig whose credential is a file rather than a string. This restriction rules out both Vertex AI providers there. For more information about that limitation, see [About model providers]({{< link path="setup/model-providers/about-model-providers" >}}). +> Neither `codex` nor `claude` accepts a ModelConfig that sets `defaultHeaders`, `tls`, or `apiKeyPassthrough`. Separately, every runtime rejects a credential that the egress gateway cannot place in an HTTP header, such as an IAM key pair or a Google service account key. For more information about that limitation, see [About model providers]({{< link path="setup/model-providers/about-model-providers#credentials-that-do-not-compile" >}}). ## Tool and skill support diff --git a/docs-site/content/kagent/1.x/setup/model-providers/about-model-providers.md b/docs-site/content/kagent/1.x/setup/model-providers/about-model-providers.md index 5449a339..2aa9371f 100644 --- a/docs-site/content/kagent/1.x/setup/model-providers/about-model-providers.md +++ b/docs-site/content/kagent/1.x/setup/model-providers/about-model-providers.md @@ -21,20 +21,52 @@ Every ModelConfig shares the same three parts, regardless of the provider that i Credentials come from a Kubernetes Secret in the same namespace as the ModelConfig. The `apiKeySecret` field names the Secret, and `apiKeySecretKey` names the key within that Secret. To forward the bearer token from the incoming request to the provider instead, set `apiKeyPassthrough: true`. A ModelConfig cannot set both `apiKeyPassthrough` and `apiKeySecret`. For every ModelConfig field, including its type, default, and validation rules, see the [API reference]({{< link path="reference/api-ref#modelconfigspec" >}}). -**Credential files** +## How a credential reaches the provider -kagent passes model credentials to an agent as environment variables. A ModelConfig that instead requires a credential **file** mounted into the agent does not compile. The AgentTemplate reports the `Compatible` condition as `False`, with the reason `UnsupportedConfiguration` and the message `ModelConfig requires volume mounts unsupported by Substrate ActorTemplate`. kagent compiles no revision from that AgentTemplate, so no agent runs from it, and any AgentInstance that already exists keeps running the last revision that compiled. Three configurations encounter this today. -- **The Vertex AI providers, on the `kagent` and `byo` runtimes.** `GeminiVertexAI` and `AnthropicVertexAI` mount the Google credentials file that `apiKeySecret` names. Leaving `apiKeySecret` unset compiles, but a Substrate Actor does not inherit cloud workload identity, so the agent still has no credentials to send. The `claude` runtime is the exception: it passes the same credentials as an environment variable, so `AnthropicVertexAI` works there. For more information, see [Google Vertex AI]({{< link path="setup/model-providers/google-vertexai" >}}). -- **A private certificate authority (CA), on any provider.** Setting `tls.caCertSecretRef` mounts the CA bundle as a file. Every provider accepts the `tls` block, so this affects all of them, not only the Vertex AI providers. You cannot reach a provider endpoint that presents a certificate from a private CA, unless you set `tls.disableVerify: true`, which skips certificate verification entirely and belongs only in a test environment. -- **OpenAI token exchange.** The `openAI.tokenExchange` block acquires a bearer token by reading a mounted service account file, so a ModelConfig that sets it never compiles. An OpenAI-compatible endpoint must accept a static API key instead. For more information, see [OpenAI]({{< link path="setup/model-providers/openai" >}}). +A credential never enters the agent. kagent compiles the Secret that a ModelConfig names into a destination-scoped binding, and the {{< gloss "Agent Substrate" >}}Agent Substrate{{< /gloss >}} egress gateway fetches the Secret and writes the value into an outgoing HTTP header. Where an SDK requires an API key, the runtime receives the inert placeholder `kagent-credential-injected`. A compiled {{< gloss "Revision" >}}revision{{< /gloss >}} therefore records the Secret name, key, destination, and header, and never the credential itself. + +To rotate a credential, update the Secret. The gateway refreshes its cache within five minutes, so neither a recompile nor a restart is needed. + +Each provider carries its credential in the one header that the provider expects, and the destination is the endpoint that the ModelConfig resolves to. + +| Credential | Header | +| ---------- | ------ | +| `OpenAI` API key | `authorization: Bearer ` | +| `Anthropic` API key | `x-api-key: ` | +| `AzureOpenAI` API key, and `Foundry` in OpenAI format | `api-key: ` | +| `Foundry` API key in Anthropic format | `x-api-key: ` | +| `Gemini` API key | `x-goog-api-key: ` | +| `Bedrock` bearer token | `authorization: Bearer ` | +| A Secret-backed `RemoteMCPServer` header | The header that the server names | + +Substrate matches a destination on the exact DNS hostname, without path, port, or scheme. Two credentials that target the same hostname and header are rejected, including a conflict between an agent's model, a memory embedding model, and an MCP server. Give such origins distinct DNS names. A destination given as an IP address cannot carry an injected credential at all. + +### Credentials that do not compile + +Header injection accepts one shape of credential: a static string. A credential that requires a local signature, a token exchange, or a file mounted into the agent cannot be injected, so kagent rejects the configuration instead of passing the credential to the runtime. The AgentTemplate reports the `Compatible` condition as `False` with the reason `UnsupportedConfiguration`, and kagent compiles no revision from that template. Any AgentInstance that already exists keeps running the last revision that compiled. + +| Configuration | Why it cannot be injected | What to use instead | +| ------------- | ------------------------- | ------------------- | +| `Bedrock` with `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` | IAM keys sign each request locally. | A Bedrock bearer token in `AWS_BEARER_TOKEN_BEDROCK`. See [Amazon Bedrock]({{< link path="setup/model-providers/amazon-bedrock" >}}). | +| `AnthropicVertexAI` and `GeminiVertexAI` | A Google service account key is signed locally to obtain a token, and the `kagent` and `byo` runtimes also mount it as a file. | `Anthropic` or `Bedrock` for Claude models, and `Gemini` for Gemini models. See [Google Vertex AI]({{< link path="setup/model-providers/google-vertexai" >}}). | +| `SAPAICore` | OAuth2 client credentials are exchanged for a token before any request. | A provider that authenticates with an API key. See [SAP AI Core]({{< link path="setup/model-providers/sap-ai-core" >}}). | +| A `credentialRef` in a Harness `spec.env` entry | An arbitrary variable names no destination and no header to bind it to. | A ModelConfig or a RemoteMCPServer, each of which carries a destination. See [Agent harness]({{< link path="agents/agent-harness#configure-a-harness" >}}). | +| `openAI.tokenExchange` | The block reads a mounted service account file to acquire a token. | An endpoint that accepts a static API key. See [OpenAI]({{< link path="setup/model-providers/openai" >}}). | +| `tls.caCertSecretRef`, on any provider | The CA bundle is mounted as a file. | An endpoint whose certificate chains to a public CA. Setting `tls.disableVerify: true` skips certificate verification entirely and belongs only in a test environment. | + +A rejected credential reports one of two messages. A credential that cannot be injected reports `cannot use gateway header injection`, and one that needs a mounted file reports `ModelConfig requires volume mounts unsupported by Substrate ActorTemplate`. + +The `Ollama` provider is unaffected, because it authenticates with no credential. ## The Harness runtime decides which providers are available A ModelConfig is only half of the decision. The runtime that a {{< gloss "Harness" >}}Harness{{< /gloss >}} selects also constrains which providers an agent can use, because each runtime integrates a different set. -- The **`kagent`** runtime supports every provider, and the **`byo`** runtime supports the same set, because both compile through the same path. -- The **`codex`** runtime supports only `OpenAI` and `Bedrock`. -- The **`claude`** runtime supports only `Anthropic`, `Bedrock`, and `AnthropicVertexAI`. +- The **`kagent`** runtime integrates every provider, and the **`byo`** runtime integrates the same set, because both compile through the same path. +- The **`codex`** runtime integrates only `OpenAI` and `Bedrock`. +- The **`claude`** runtime integrates only `Anthropic` and `Bedrock`. + +Integration alone is not enough. A provider whose credential cannot be injected as a header is rejected on every runtime that integrates it, so `AnthropicVertexAI`, `GeminiVertexAI`, and `SAPAICore` run nowhere today. For the alternatives, see [Credentials that do not compile](#credentials-that-do-not-compile). Neither `codex` nor `claude` accepts a ModelConfig that sets `defaultHeaders`, `tls`, or `apiKeyPassthrough`, and each narrows the provider settings it takes. A pair that asks for a provider its runtime does not integrate fails to compile, and the AgentTemplate reports the `Compatible` condition as `False` with the reason `UnsupportedConfiguration`. diff --git a/docs-site/content/kagent/1.x/setup/model-providers/amazon-bedrock.md b/docs-site/content/kagent/1.x/setup/model-providers/amazon-bedrock.md index cca31389..08d147a0 100644 --- a/docs-site/content/kagent/1.x/setup/model-providers/amazon-bedrock.md +++ b/docs-site/content/kagent/1.x/setup/model-providers/amazon-bedrock.md @@ -10,27 +10,36 @@ Amazon Bedrock serves models from several families behind one AWS API. {{< reuse Prefer the native provider. If you need the OpenAI request format, or an inference profile that only that endpoint exposes, use the OpenAI-compatible path. > [!NOTE] -> Bedrock is the only provider that every runtime supports. A `codex` Harness accepts only OpenAI `gpt-*` model IDs, and both `codex` and `claude` accept no `bedrock` settings beyond `region`. For more information, see [Agent harness]({{< link path="agents/agent-harness#model-provider-support" >}}). +> Bedrock is the only provider that every runtime supports, and on every one of them the credential must be a bearer token. A `codex` Harness accepts only OpenAI `gpt-*` model IDs, and both `codex` and `claude` accept no `bedrock` settings beyond `region`. For more information, see [Agent harness]({{< link path="agents/agent-harness#model-provider-support" >}}). > [!IMPORTANT] > Both paths authenticate with credentials from a Kubernetes Secret. Attaching an AWS IAM role to the agent, such as with [EKS IAM Roles for Service Accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html), is not currently supported: an agent runs as a Substrate Actor rather than as a pod that kagent controls, so there is no per-agent ServiceAccount to attach a role to. ## Before you begin -1. Create an IAM user or role with permissions for Bedrock. At minimum you need `bedrock:InvokeModel` for the models that you use. For more information, see the [AWS Bedrock model access docs](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html). +1. Grant the identity that issues your API key permission to call Bedrock. At minimum you need `bedrock:InvokeModel` for the models that you use. For more information, see the [AWS Bedrock model access docs](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html). 2. Choose an AWS region and a Bedrock model, and confirm that your account has access to that model in that region. For the available models, see the [AWS Bedrock supported models docs](https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html). ## Native Bedrock provider -1. Create a Kubernetes Secret that stores your AWS access keys. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`. +The native provider authenticates with a Bedrock API key, which kagent sends as a bearer token. + +1. Create a Bedrock API key. For more information, see the [AWS Bedrock API keys guide](https://docs.aws.amazon.com/bedrock/latest/userguide/getting-started-api-keys.html). + ```bash + export AWS_BEARER_TOKEN_BEDROCK= + ``` + +2. Create a Kubernetes Secret that holds the token under the key `AWS_BEARER_TOKEN_BEDROCK`. kagent looks that key up by name, so no other key works. Create the Secret in the same namespace as the AgentTemplates that use it, such as `kagent`. ```bash kubectl create secret generic bedrock-credentials -n kagent \ - --from-literal AWS_ACCESS_KEY_ID= \ - --from-literal AWS_SECRET_ACCESS_KEY= + --from-literal AWS_BEARER_TOKEN_BEDROCK=$AWS_BEARER_TOKEN_BEDROCK ``` -2. Create a `ModelConfig` that uses the `Bedrock` provider. + > [!IMPORTANT] + > A Secret that holds `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` instead does not work on any runtime. IAM credentials sign each request locally, and an agent reaches its provider through an egress gateway that injects a static header, so kagent rejects the ModelConfig at compile time. The AgentTemplate reports the `Compatible` condition as `False` with the message `environment credential "AWS_ACCESS_KEY_ID" cannot use gateway header injection`. For more information, see [About model providers]({{< link path="setup/model-providers/about-model-providers#credentials-that-do-not-compile" >}}). + +3. Create a `ModelConfig` that uses the `Bedrock` provider. ```yaml kubectl apply -f - < [!NOTE] -> This provider works on the `kagent`, `byo`, and `claude` runtimes, but not on `codex`. A `claude` Harness accepts no `anthropic` settings beyond `baseUrl`. For more information, see [Agent harness]({{< link path="agents/agent-harness#model-provider-support" >}}). To reach Claude models through Google Cloud instead, see [Google Vertex AI]({{< link path="setup/model-providers/google-vertexai" >}}). +> This provider works on the `kagent`, `byo`, and `claude` runtimes, but not on `codex`. A `claude` Harness accepts no `anthropic` settings beyond `baseUrl`. For more information, see [Agent harness]({{< link path="agents/agent-harness#model-provider-support" >}}). Claude models served through Google Cloud Vertex AI do not run on 1.0. For the reason and the alternatives, see [Google Vertex AI]({{< link path="setup/model-providers/google-vertexai" >}}). ## Create the ModelConfig diff --git a/docs-site/content/kagent/1.x/setup/model-providers/gemini.md b/docs-site/content/kagent/1.x/setup/model-providers/gemini.md index ab539f3b..2da5147d 100644 --- a/docs-site/content/kagent/1.x/setup/model-providers/gemini.md +++ b/docs-site/content/kagent/1.x/setup/model-providers/gemini.md @@ -5,7 +5,7 @@ weight: 20 author: kagent.dev --- -The `Gemini` provider reaches Google's Gemini models through the Google AI Studio API, authenticating with a single API key. To reach Gemini through Google Cloud instead, see [Google Vertex AI]({{< link path="setup/model-providers/google-vertexai" >}}). +The `Gemini` provider reaches Google's Gemini models through the Google AI Studio API, authenticating with a single API key. Gemini models served through Google Cloud Vertex AI do not run on 1.0. For the reason, see [Google Vertex AI]({{< link path="setup/model-providers/google-vertexai" >}}). ## Before you begin diff --git a/docs-site/content/kagent/1.x/setup/model-providers/google-vertexai.md b/docs-site/content/kagent/1.x/setup/model-providers/google-vertexai.md index 7e245dda..0e5ea2b2 100644 --- a/docs-site/content/kagent/1.x/setup/model-providers/google-vertexai.md +++ b/docs-site/content/kagent/1.x/setup/model-providers/google-vertexai.md @@ -1,86 +1,35 @@ --- title: Google Vertex AI -description: Configure kagent to use Claude models through Google Cloud Vertex AI on a Claude harness. +description: Understand why Vertex AI models do not run on kagent 1.0, and which providers serve the same models instead. weight: 20 author: kagent.dev --- -Google Cloud Vertex AI serves both Gemini and Claude models, and the {{< gloss "ModelConfig" >}}ModelConfig{{< /gloss >}} schema has a provider for each: `GeminiVertexAI` and `AnthropicVertexAI`. Which of them works depends on the runtime that your {{< gloss "Harness" >}}Harness{{< /gloss >}} selects. +Neither Vertex AI provider runs on kagent 1.0. `AnthropicVertexAI` and `GeminiVertexAI` both authenticate with a Google service account key, and such a key is signed locally to obtain an access token. An agent reaches its model provider through the {{< gloss "Agent Substrate" >}}Agent Substrate{{< /gloss >}} egress gateway, which injects a static credential into an HTTP header and performs no signing, so kagent rejects a Vertex AI {{< gloss "ModelConfig" >}}ModelConfig{{< /gloss >}} rather than passing the key to the runtime. -| Provider | Harness runtime | Supported | -| -------- | --------------- | --------- | -| `AnthropicVertexAI` | `claude` | Yes | -| `AnthropicVertexAI` | `kagent` or `byo` | No | -| `GeminiVertexAI` | any | No | +The rejection happens at compile time. The AgentTemplate reports the `Compatible` condition as `False` with the reason `UnsupportedConfiguration`, and kagent compiles no revision from it. On a `claude` {{< gloss "Harness" >}}Harness{{< /gloss >}} the message names the credential. -For the full provider matrix across all four runtimes, see [Agent harness]({{< link path="agents/agent-harness#model-provider-support" >}}). +``` +environment credential "KAGENT_CLAUDE_GOOGLE_CREDENTIALS_JSON" cannot use gateway header injection; local signing and arbitrary secret environment variables are unsupported +``` -The difference is how each runtime receives the Google credentials. Vertex AI authenticates with a service account key, which is a JSON document rather than a single string. The `claude` runtime takes that document as an environment variable. The `kagent` runtime instead writes it to a file and mounts it, and an agent running on {{< gloss "Agent Substrate" >}}Agent Substrate{{< /gloss >}} cannot mount files. +On the `kagent` and `byo` runtimes the same ModelConfig fails for a second reason as well, because those runtimes mount the key as a file: `ModelConfig requires volume mounts unsupported by Substrate ActorTemplate`. -## Claude models on a Claude harness +## Reach the same models another way -1. Create a [Google service account key](https://cloud.google.com/iam/docs/keys-create-delete) with access to Vertex AI, and store the JSON in a Kubernetes Secret. Create it in the same namespace as the AgentTemplates that use it, such as `kagent`. - ```bash - kubectl create secret generic kagent-vertex -n kagent \ - --from-file=credentials.json=.json - ``` +Vertex AI serves two model families, and a provider that authenticates with an API key is available for each. -2. Create a `ModelConfig` that uses the `AnthropicVertexAI` provider. - ```yaml - kubectl apply -f - <}}), [Amazon Bedrock]({{< link path="setup/model-providers/amazon-bedrock" >}}) | +| Gemini models | `Gemini`, which serves the same family through the Google AI Studio API | [Gemini]({{< link path="setup/model-providers/gemini" >}}) | - | Field | Description | - | ----- | ----------- | - | `apiKeySecret` | The name of the Kubernetes Secret that holds the service account key. | - | `apiKeySecretKey` | The key within that Secret that holds the JSON document. | - | `model` | The Vertex AI model ID, such as `claude-sonnet-4@20250514`. | - | `provider` | The provider to use, `AnthropicVertexAI`. | - | `anthropicVertexAI.projectID` | Your Google Cloud project ID. This field is required, and must match the `project_id` inside the service account key. | - | `anthropicVertexAI.location` | The Vertex AI region, such as `us-east5`. This field is required. | - - The `claude` runtime accepts no other settings in the `anthropicVertexAI` block yet, and rejects a ModelConfig that sets `defaultHeaders`, `tls`, or `apiKeyPassthrough`. For every field, including its type, default, and validation rules, see the [API reference]({{< link path="reference/api-ref#anthropicvertexaiconfig" >}}). - -3. Pair the ModelConfig with a Harness that selects the `claude` runtime. - ```yaml - spec: - claude: {} - workload: - image: {{< reuse "kagent-docs/versions/runtime-image-claude.md" >}} - ``` - -### What kagent checks before it compiles - -kagent validates the service account key at compile time rather than failing at run time, so a malformed credential surfaces on the AgentTemplate's `Compatible` condition. - -- The Secret key must hold valid JSON. -- The document must be a `service_account` key. Other credential types are not accepted yet. -- Its `project_id` must match `anthropicVertexAI.projectID`. -- Its `token_uri` must be `https://oauth2.googleapis.com`. - -## Gemini models on Vertex AI - -The `GeminiVertexAI` provider does not compile on any runtime. On a `kagent` Harness it fails with `ModelConfig requires volume mounts unsupported by Substrate ActorTemplate`, and the `claude` runtime does not accept the provider at all. - -To reach Gemini models, use the [Gemini]({{< link path="setup/model-providers/gemini" >}}) provider, which serves the same model family through the Google AI Studio API and authenticates with an ordinary API key. +For every credential that the gateway cannot inject, and the alternative for each, see [About model providers]({{< link path="setup/model-providers/about-model-providers#credentials-that-do-not-compile" >}}). ## Next steps {{< cards >}} {{< card link=`{{< link path="setup/model-providers/gemini" >}}` title="Gemini" subtitle="Reach Gemini models with an API key instead." >}} - {{< card link=`{{< link path="setup/model-providers/about-model-providers" >}}` title="About model providers" subtitle="Understand which provider configurations a Harness can run." >}} + {{< card link=`{{< link path="setup/model-providers/anthropic" >}}` title="Anthropic" subtitle="Reach Claude models with an Anthropic API key." >}} + {{< card link=`{{< link path="setup/model-providers/about-model-providers" >}}` title="About model providers" subtitle="Understand which credentials a Harness can run." >}} {{< /cards >}} diff --git a/docs-site/content/kagent/1.x/setup/model-providers/sap-ai-core.md b/docs-site/content/kagent/1.x/setup/model-providers/sap-ai-core.md index d943135f..a4efd484 100644 --- a/docs-site/content/kagent/1.x/setup/model-providers/sap-ai-core.md +++ b/docs-site/content/kagent/1.x/setup/model-providers/sap-ai-core.md @@ -1,73 +1,33 @@ --- title: SAP AI Core -description: Configure kagent to use models served through the SAP AI Core Orchestration Service. +description: Understand why SAP AI Core models do not run on kagent 1.0, and what to use instead. weight: 20 author: kagent.dev --- -{{< reuse "kagent-docs/snippets/name-product.md" >}} reaches SAP AI Core through its [Orchestration Service](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/orchestration), a single endpoint that serves models from several families, including Anthropic, OpenAI, Gemini, Amazon, Meta, and Mistral. Authentication uses OAuth2 client credentials from your SAP AI Core service key. +The `SAPAICore` provider does not run on kagent 1.0. SAP AI Core authenticates with OAuth2 client credentials, which a client exchanges at a token endpoint for a short-lived access token before it calls the API. An agent reaches its model provider through the {{< gloss "Agent Substrate" >}}Agent Substrate{{< /gloss >}} egress gateway, which injects a static credential into an HTTP header and performs no token exchange, so kagent rejects a SAP AI Core {{< gloss "ModelConfig" >}}ModelConfig{{< /gloss >}} rather than passing the client secret to the runtime. -## Create the ModelConfig +The rejection happens at compile time on every runtime. The AgentTemplate reports the `Compatible` condition as `False` with the reason `UnsupportedConfiguration`, and kagent compiles no revision from it. -1. Save the OAuth2 client credentials from your SAP AI Core service key as environment variables. - ```bash - export SAP_AI_CORE_CLIENT_ID= - export SAP_AI_CORE_CLIENT_SECRET= - ``` - -2. Create a Kubernetes Secret that stores both credentials. The Secret must contain the keys `client_id` and `client_secret` under exactly those names. - ```bash - kubectl create secret generic kagent-sapaicore -n kagent \ - --from-literal client_id=$SAP_AI_CORE_CLIENT_ID \ - --from-literal client_secret=$SAP_AI_CORE_CLIENT_SECRET - ``` - - > [!NOTE] - > SAP AI Core is the one provider that does not use `apiKeySecretKey`. kagent reads `client_id` and `client_secret` directly from the Secret that `apiKeySecret` names, so setting `apiKeySecretKey` has no effect. - -3. Create a `ModelConfig` that references the Secret. The endpoint, resource group, and OAuth2 token endpoint all come from your SAP AI Core service key. - ```yaml - kubectl apply -f - <.authentication.eu10.hana.ondemand.com - resourceGroup: default - EOF - ``` - - | Field | Description | - | ----- | ----------- | - | `apiKeySecret` | The name of the Kubernetes Secret that holds `client_id` and `client_secret`. | - | `model` | The model to use, in the Orchestration Service naming convention, such as `anthropic--claude-4.5-sonnet`, `gpt-5-mini`, or `gemini-3-pro-preview`. For the full list, see the [SAP AI Core models docs](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/models-and-scenarios-in-generative-ai-hub). | - | `provider` | The provider to use, `SAPAICore`. | - | `sapAICore.baseUrl` | The base URL for the SAP AI Core API. This field is required. | - | `sapAICore.authUrl` | The OAuth2 token endpoint. | - | `sapAICore.resourceGroup` | The resource group within SAP AI Core. Defaults to `default`. | +``` +environment credential "SAP_AI_CORE_CLIENT_ID" cannot use gateway header injection; local signing and arbitrary secret environment variables are unsupported +``` - For every `sapAICore` field, including its type, default, and validation rules, see the [API reference]({{< link path="reference/api-ref#sapaicoreconfig" >}}). +## Reach the same models another way -## Use the ModelConfig +The SAP AI Core Orchestration Service serves models from several families, and kagent supports most of those families directly through a provider that authenticates with an API key. Choose the provider for the model that you want to run, rather than for the gateway that serves it. -Reference the ModelConfig by name from an AgentTemplate in the same namespace. +| To run | Use | Guide | +| ------ | --- | ----- | +| Claude models | `Anthropic` or `Bedrock` | [Anthropic]({{< link path="setup/model-providers/anthropic" >}}), [Amazon Bedrock]({{< link path="setup/model-providers/amazon-bedrock" >}}) | +| GPT models | `OpenAI`, or `AzureOpenAI` for an Azure deployment | [OpenAI]({{< link path="setup/model-providers/openai" >}}), [Azure OpenAI]({{< link path="setup/model-providers/azure-openai" >}}) | +| Gemini models | `Gemini` | [Gemini]({{< link path="setup/model-providers/gemini" >}}) | -```yaml -spec: - modelConfig: - name: sapaicore-model-config -``` +For every credential that the gateway cannot inject, and the alternative for each, see [About model providers]({{< link path="setup/model-providers/about-model-providers#credentials-that-do-not-compile" >}}). ## Next steps {{< cards >}} - {{< card link=`{{< link path="get-started/your-first-agent" >}}` title="Your first agent" subtitle="Create an agent that uses this model, and hold a conversation with it." >}} - {{< card link=`{{< link path="setup/model-providers/about-model-providers" >}}` title="About model providers" subtitle="Understand how a ModelConfig reaches a running agent." >}} + {{< card link=`{{< link path="setup/model-providers/about-model-providers" >}}` title="About model providers" subtitle="Understand which credentials a Harness can run." >}} + {{< card link=`{{< link path="setup/model-providers/openai" >}}` title="OpenAI" subtitle="Reach GPT models with an API key." >}} {{< /cards >}}