diff --git a/src/app/docs/kagent/concepts/agent-substrate/page.mdx b/src/app/docs/kagent/concepts/agent-substrate/page.mdx index 7acbbfd1..523382da 100644 --- a/src/app/docs/kagent/concepts/agent-substrate/page.mdx +++ b/src/app/docs/kagent/concepts/agent-substrate/page.mdx @@ -63,7 +63,9 @@ Agent Substrate is composed of a control plane, a data plane, and snapshot stora ### Declarative agents -Run a (Go) declarative agent on Agent Substrate by creating a `SandboxAgent` resource. It carries the same spec as a regular `Agent`, but the kagent controller runs it as a sandboxed workload on the runtime instead of a plain Deployment. +Run a declarative agent on Agent Substrate by creating a `SandboxAgent` resource. It carries the same spec as a regular `Agent`, but the kagent controller runs it as a sandboxed workload on the runtime instead of a plain Deployment. All three declarative runtimes are supported: **Go** (default), **Python**, and **BYO**. + +Session history for Go and Python declarative sandbox agents is persisted to a local SQLite database backed by the agent's `durableDir` volume, so conversation state survives pod restarts and Deployment rollouts. Session metadata is mirrored to PostgreSQL to support session-listing APIs. BYO agents do not get local session storage automatically; set the `kagent.dev/local-session-storage` annotation on the `SandboxAgent` if your BYO agent implements its own local store. ### AgentHarness diff --git a/src/app/docs/kagent/concepts/agents/page.mdx b/src/app/docs/kagent/concepts/agents/page.mdx index 4cd4f5c4..fa35f954 100644 --- a/src/app/docs/kagent/concepts/agents/page.mdx +++ b/src/app/docs/kagent/concepts/agents/page.mdx @@ -238,13 +238,13 @@ To learn more about using skills in your agents, see the [Skills example guide]( ## Runtime -You can choose between two Agent Development Kit (ADK) runtimes for declarative agents: **Python** (default) and **Go**. +You can choose between two Agent Development Kit (ADK) runtimes for declarative agents: **Go** (default) and **Python**. -| Feature | Python ADK | Go ADK | -|---------|-----------|--------| -| Startup time | ~15 seconds | ~2 seconds | -| Ecosystem | Google ADK, LangGraph, CrewAI integrations | Native Go implementation | -| Resource usage | Higher (Python runtime) | Lower (compiled binary) | +| Feature | Go ADK | Python ADK | +|---------|--------|-----------| +| Startup time | ~2 seconds | ~15 seconds | +| Ecosystem | Native Go implementation | Google ADK, LangGraph, CrewAI integrations | +| Resource usage | Lower (compiled binary) | Higher (Python runtime) | | Default | Yes | No | | Memory support | Yes | Yes | | MCP support | Yes | Yes | @@ -256,7 +256,7 @@ Select the runtime via the `runtime` field in the declarative agent spec. spec: type: Declarative declarative: - runtime: go # or "python" (default) + runtime: go # or "python" modelConfig: default-model-config systemMessage: "You are a helpful agent." ``` @@ -267,6 +267,45 @@ spec: For more benchmarks and details, see the [Go vs Python runtime blog post](/blog/go-vs-python-runtime). +## Deployment configuration + +Control how the agent's Kubernetes Deployment is configured in the `spec.declarative.deployment` stanza. + +### Environment variables + +Use `env` to set individual environment variables, or `envFrom` to bulk-inject all keys from a ConfigMap or Secret. + +```yaml +spec: + declarative: + deployment: + env: + - name: LOG_LEVEL + value: debug + envFrom: + - configMapRef: + name: my-agent-config + - secretRef: + name: my-agent-secrets +``` + +### Deployment annotations + +Use `deploymentAnnotations` to add annotations to the Deployment object itself. This field is distinct from the `annotations` field, which targets pod template metadata only. + +```yaml +spec: + declarative: + deployment: + deploymentAnnotations: + argocd.argoproj.io/sync-wave: "5" + notifications.argoproj.io/subscribe.on-degraded.slack: my-channel + annotations: + prometheus.io/scrape: "true" # pod template only +``` + +`deploymentAnnotations` is useful for GitOps tooling such as Argo CD sync waves and Flux annotations, which key off Deployment-level metadata rather than pod metadata. + ## Memory Your agents can save and retrieve relevant context across conversations using vector similarity search. When you enable memory on an agent, it receives three additional tools (`save_memory`, `load_memory`, `prefetch_memory`) and automatically extracts key information every 5th user message. @@ -300,10 +339,32 @@ Compaction removes older conversation events to free up space in the context win ## Sandboxed Agents -You can run a declarative agent in an isolated sandbox by creating a `SandboxAgent` resource instead of a regular `Agent`. A `SandboxAgent` runs on [Agent Substrate](/docs/kagent/concepts/agent-substrate): the kagent controller runs it as a gVisor-sandboxed actor instead of a Deployment, snapshotting it to object storage when idle and rehydrating it on demand. The spec mirrors the `Agent` spec, with a few constraints: sandboxed agents always use the Go ADK runtime, and `spec.skills` and `BYO` agents are not supported. Configure substrate placement with the optional `spec.substrate` field (for example, `workerPoolRef`). +You can run a declarative agent in an isolated sandbox by creating a `SandboxAgent` resource instead of a regular `Agent`. A `SandboxAgent` runs on [Agent Substrate](/docs/kagent/concepts/agent-substrate): the kagent controller runs it as a gVisor-sandboxed actor instead of a Deployment, snapshotting it to object storage when idle and rehydrating it on demand. The spec mirrors the `Agent` spec. All three runtimes are supported: **Go** (default), **Python**, and **BYO**. For Go and Python agents, session history is persisted to a local SQLite database in the agent's `durableDir` volume, so conversation state survives pod restarts and Deployment rollouts. BYO agents do not get local session storage automatically. Configure substrate placement with the optional `spec.substrate` field (for example, `workerPoolRef`). For setup steps, see the [Agent Substrate example](/docs/kagent/examples/agent-substrate). +## A2A AgentCard metadata + +When another agent or client discovers your agent over the [A2A protocol](https://google.github.io/A2A/specification/#5-agent-discovery-using-an-agent-card), it reads a machine-readable AgentCard from your agent's `/.well-known/agent.json` endpoint. You can enrich that card with optional metadata fields on the `Agent` spec. + +```yaml +spec: + iconUrl: https://example.com/icons/my-agent.png + documentationUrl: https://docs.example.com/my-agent/ + version: "1.0.0" + provider: + organization: My Organization + url: https://example.com +``` + +| Field | Description | +|-------|-------------| +| `iconUrl` | URL to an icon image representing the agent. Must be a valid URI. | +| `documentationUrl` | URL to human-readable documentation for the agent. Must be a valid URI. | +| `version` | Version string for the agent, such as `"1.0.0"`. | +| `provider.organization` | Name of the organization responsible for the agent. | +| `provider.url` | URL to the agent provider's website or documentation. Must be a valid URI. | + ## Agents as Tools kagent also supports using agents as tools. Any agent you create can be referenced and used by other agents you have. An example use case would be to have a PromQL agent that knows how to create PromQL queries from natural language. Then you'd create a second agent that would use the PromQL agent whenever it needs to create a PromQL query. diff --git a/src/app/docs/kagent/introduction/installation/page.mdx b/src/app/docs/kagent/introduction/installation/page.mdx index 44bd3b3e..e15fd503 100644 --- a/src/app/docs/kagent/introduction/installation/page.mdx +++ b/src/app/docs/kagent/introduction/installation/page.mdx @@ -317,6 +317,143 @@ controller: This example loads all key-value pairs from the `controller-secrets` secret as environment variables in the controller pod. +### Customize Kubernetes resources + +Use the following Helm values to meet cluster admission policies or integrate with external tooling. + +#### Pod labels + +Add labels to the pod templates of the controller and UI Deployments. Pod labels can be useful for clusters with policies (OPA Gatekeeper, Kyverno) that require specific labels on every pod. + +A global `podLabels` map applies to all component pods; per-component values override it: + +```yaml +podLabels: + team: platform + +controller: + podLabels: + cost-center: infra + +ui: + podLabels: + cost-center: frontend +``` + +To add labels to all **agent** pods, use `controller.agentDeployment.podLabels`. + +#### ServiceAccount annotations + +Add annotations to the controller and UI ServiceAccount resources. These annotations are required for cloud provider workload identity integrations (GCP Workload Identity, AWS IRSA, Azure Workload Identity) that grant IAM permissions to workloads by annotating their Kubernetes ServiceAccount. + +```yaml +controller: + serviceAccount: + annotations: + iam.gke.io/gcp-service-account: kagent@my-project.iam.gserviceaccount.com + +ui: + serviceAccount: + annotations: + iam.gke.io/gcp-service-account: kagent-ui@my-project.iam.gserviceaccount.com +``` + +#### Deployment annotations + +Add annotations to the controller and UI Deployment resources. For example, to add annotations for cluster autoscaler or Datadog: + +```yaml +controller: + annotations: + cluster-autoscaler.kubernetes.io/safe-to-evict: "false" + +ui: + annotations: + cluster-autoscaler.kubernetes.io/safe-to-evict: "false" +``` + +To add annotations to the controller **Service** (for AWS Load Balancer Controller or ExternalDNS), use `controller.service.annotations`. + +#### Default nodeSelector for agent deployments + +Set a default `nodeSelector` that is applied to every agent Deployment that the controller creates. This setting can be useful when admission policies require a `nodeSelector` on all Deployments, since agents created through the UI carry none by default. + +```yaml +controller: + agentDeployment: + nodeSelector: + kubernetes.io/os: linux +``` + +Per-agent `nodeSelector` values in the `Agent` spec take precedence over this default. + +#### Deploy companion resources with extraObjects + +Use `extraObjects` to deploy arbitrary Kubernetes manifests in the same Helm chart lifecycle as kagent. Entries are rendered through `tpl`, so they can reference the release context. + +```yaml +extraObjects: + - apiVersion: external-secrets.io/v1beta1 + kind: ExternalSecret + metadata: + name: kagent-api-key + namespace: "{{ .Release.Namespace }}" + spec: + refreshInterval: 1h + secretStoreRef: + name: my-store + kind: ClusterSecretStore + target: + name: kagent-api-key + data: + - secretKey: ANTHROPIC_API_KEY + remoteRef: + key: anthropic-api-key +``` + +### Disable the default ModelConfig + +By default, kagent creates a `ModelConfig` resource and associated Kubernetes Secret for the provider that you set with `providers.default`. To skip this and manage `ModelConfig` resources entirely outside the Helm chart, set `providers` to null: + +```yaml +providers: null +``` + +When `providers` is null (or omitted), kagent does not create the `ModelConfig` or its Secret. Use this setting when you apply `ModelConfig` resources through GitOps, a separate Helm chart, or another external process. + +### Private registry and image mirroring + +If your cluster cannot pull from `ghcr.io` directly, such as in air-gapped environments, corporate proxies, or mandatory image scanning, you can mirror the kagent images to an internal registry and configure the chart to pull from this registry. + +kagent uses three independently configurable image locations: + +| Helm value | Default image | Description | +|---|---|---| +| `image.registry` | `ghcr.io` | Global registry prefix applied to all images that do not set their own registry. | +| `controller.agentImage` | `ghcr.io/kagent-dev/kagent/app` | Python ADK runtime image used for Python and BYO declarative agents. | +| `controller.goAgentImage` | `ghcr.io/kagent-dev/kagent/golang-adk` | Go ADK runtime image used for Go declarative agents. Must be set separately from `agentImage`. | + +To redirect all images to an internal mirror, set `image.registry` to your registry and override both agent images: + +```yaml +image: + registry: my-registry.example.com + +controller: + agentImage: + registry: my-registry.example.com + repository: kagent/app + tag: v0.10.0 + goAgentImage: + registry: my-registry.example.com + repository: kagent/golang-adk + tag: v0.10.0 +``` + +When unset, the `registry` and `pullPolicy` fields of `agentImage` and `goAgentImage` default to the global `image.registry` and `image.pullPolicy` values. For many mirror setups, setting only `image.registry` and overriding `repository` and `tag` on each image is sufficient. + +> **Note**: If you set only `agentImage` without also setting `controller.goAgentImage`, Go declarative agents still try to pull the Go ADK image from its default location, `ghcr.io`. The controller logs a startup warning when the two image registries differ. + ## Uninstallation Refer to the [Uninstall](/docs/kagent/operations/uninstall) guide. diff --git a/src/app/docs/kagent/observability/launch-ui/page.mdx b/src/app/docs/kagent/observability/launch-ui/page.mdx index 4b740811..ac555014 100644 --- a/src/app/docs/kagent/observability/launch-ui/page.mdx +++ b/src/app/docs/kagent/observability/launch-ui/page.mdx @@ -54,6 +54,58 @@ If you prefer to manually set up port-forwarding, or if you're on a platform whe 3. When you're done, stop the port-forward by pressing `Ctrl+C` in the terminal where the port-forward is running. +## Expose the UI outside the cluster + +Port-forwarding is suitable for local access. For persistent or team-accessible deployments, use one of the following options. + +### LoadBalancer service + +Set `ui.service.type: LoadBalancer` in your Helm values to provision a cloud load balancer for the UI service. + +```yaml +ui: + service: + type: LoadBalancer +``` + +After the load balancer is provisioned, get the external IP or hostname from the service. + +```bash +kubectl get svc -n kagent kagent-ui +``` + +### OpenShift Route + +On OpenShift clusters, kagent automatically creates an edge-terminated `Route` for the UI when the `route.openshift.io/v1` API is present. The route is enabled by default via `ui.route.enabled: true`. + +The default HAProxy timeout is overridden to 120 minutes to prevent long-lived A2A and SSE streams from being terminated. To adjust the timeout: + +```yaml +ui: + openshiftRoute: + annotations: + haproxy.router.openshift.io/timeout: 60m +``` + +To disable the auto-created Route and front the UI with your own ingress instead, set `ui.route.enabled: false`. + +### Gateway API HTTPRoute + +If your cluster uses a Gateway API implementation such as kgateway, Istio, or Envoy Gateway, you can enable an `HTTPRoute` for the UI with `ui.httpRoute.enabled: true`. + +```yaml +ui: + httpRoute: + enabled: true + parentRefs: + - name: my-gateway + namespace: gateway-system + hostnames: + - kagent.example.com +``` + +The `parentRefs` field is required and must reference an existing `Gateway`. The `HTTPRoute` resource requires the Gateway API CRDs (`gateway.networking.k8s.io/v1`) to be installed in your cluster. + ## Next steps You can use the UI to view and manage your agents, tools, and models. For more information, see the following guides: diff --git a/src/app/docs/kagent/operations/operational-considerations/page.mdx b/src/app/docs/kagent/operations/operational-considerations/page.mdx index 4e43ed9d..e809a64b 100644 --- a/src/app/docs/kagent/operations/operational-considerations/page.mdx +++ b/src/app/docs/kagent/operations/operational-considerations/page.mdx @@ -225,6 +225,43 @@ spec: ``` +## Long-running connections + +Agents that run multi-step tasks or stream results over SSE can take minutes or longer to respond. To ensure that long-running sessions work correctly from end to end, tune the following timeout values together. + +### Streaming timeouts + +The UI uses nginx as a sidecar proxy and a client-side EventSource for streaming. Both have independent inactivity timeouts that default to 1800 seconds (30 minutes). + +| Helm value | Default | Description | +|---|---|---| +| `ui.streamTimeoutSeconds` | `1800` | Client-side EventSource inactivity timeout. | +| `ui.nginx.proxyReadTimeout` | `1800s` | nginx `proxy_read_timeout` — max time between successive reads from the upstream. | +| `ui.nginx.proxySendTimeout` | `1800s` | nginx `proxy_send_timeout` — max time between successive writes to the upstream. | + +To ensure that the nginx proxy is not the silent limit, set `ui.streamTimeoutSeconds` to a value greater than or equal to `ui.nginx.proxyReadTimeout`. For example, to support 2-hour sessions: + +```yaml +ui: + streamTimeoutSeconds: 7200 + nginx: + proxyReadTimeout: 7200s + proxySendTimeout: 7200s +``` + +On OpenShift, also set the HAProxy route timeout via `ui.openshiftRoute.annotations`. For more information, see [Expose the UI outside the cluster](/docs/kagent/observability/launch-ui#expose-the-ui-outside-the-cluster). + +### A2A client timeout + +When one agent calls another agent as a tool over the A2A protocol, the request uses an HTTP client with a configurable timeout. The default is no timeout (`""`), which replaced a previous hard-coded 3-minute limit. + +If you need to enforce a ceiling on A2A call duration, set `controller.a2aClientTimeout`: + +```yaml +controller: + a2aClientTimeout: "10m" # empty string = no timeout (default) +``` + ## Proxy configuration for agent traffic When agents and MCP servers run behind an API gateway or proxy, you can configure kagent to route agent-to-agent and agent-to-MCP traffic through that proxy. Set `proxy.url` in your Helm values to the proxy endpoint. diff --git a/src/app/docs/kagent/operations/upgrade/page.mdx b/src/app/docs/kagent/operations/upgrade/page.mdx index 87fbad37..2d3f757c 100644 --- a/src/app/docs/kagent/operations/upgrade/page.mdx +++ b/src/app/docs/kagent/operations/upgrade/page.mdx @@ -35,6 +35,8 @@ Follow these steps to upgrade kagent to the latest version and keep your cluster 4. **v0.9.0 and later**: You must be running at least v0.8.0 before upgrading to v0.9.0. Check the [release notes](/docs/kagent/resources/release-notes#v09) for 0.9-specific upgrades related to database migrations and RBAC scope. +5. **v0.10.0 and later — mirror registry operators**: If you mirror kagent images and previously relied on `agentImage` alone, you must now also set `controller.goAgentImage` to point to your mirrored Go ADK image. In v0.10, the controller no longer derives the Go image location from the Python image path. If `controller.goAgentImage` is unset and you overrode `agentImage`, the controller will fall back to pulling `ghcr.io/kagent-dev/kagent/golang-adk` directly. The controller logs a startup warning when the two registries differ. For details, see [Private registry and image mirroring](/docs/kagent/introduction/installation#private-registry-and-image-mirroring). + ## Upgrade kagent 1. Get the Helm values file for your current kagent release. @@ -88,6 +90,44 @@ After upgrading, verify that kagent is running. kubectl get pods -n kagent ``` +## Run migrations out-of-band + +By default, kagent runs database migrations automatically at controller startup. You can disable this behavior and manage migrations separately, for example, from a CI/CD pipeline or a Helm pre-upgrade hook. + +### Skip startup migrations + +Set `database.postgres.skipMigrations: true` in your Helm values file: + +```yaml +database: + postgres: + skipMigrations: true +``` + +When enabled, the controller does not run migrations at startup. Instead, it verifies that the schema is already fully migrated and exits with an error if it is not. Apply all pending migrations before installing or upgrading kagent. + +### Apply migrations + +Use `kagent db migrate up` to apply all pending migrations before starting or upgrading the controller. Set `POSTGRES_DATABASE_URL` to your database connection string (see [Database configuration](/docs/kagent/operations/operational-considerations#database-configuration)). + +```bash +export POSTGRES_DATABASE_URL="postgres://:@:5432/" +kagent db migrate up +``` + +### Check migration status + +```bash +kagent db migrate status +``` + +Example output: +``` +9 migration(s) applied, 0 pending + core: 6 applied (at v6), 0 pending + vector: 3 applied (at v3), 0 pending +``` + ## Roll back kagent If you need to roll back to a previous version after a successful upgrade, use the following steps. @@ -147,28 +187,23 @@ pg_restore \ After restoring, follow the steps to [roll back the kagent application](#steps-to-roll-back). -#### Option 2: Run down migrations +#### Option 2: Use the kagent CLI -Use `golang-migrate` to run down migrations one minor version at a time. This preserves data written after the snapshot but requires more steps. +Use the `kagent db migrate` command to run down migrations one minor version at a time. This preserves data written after the snapshot but requires more steps. -The source must be the current (newer) version that you are rolling back from, because it contains the down migrations needed to reverse the schema changes. The `goto` target is the highest migration sequence number present in the version that you are rolling back to. +The target is the highest migration sequence number present in the version that you are rolling back to. For example, `v0.9.9` has migrations up to `000005_a2a_protocol_version.up.sql` and `v0.9.3` has migrations up to `000004_feedback_single_pk.up.sql`. To roll back from `v0.9.9` to `v0.9.3`, you set `ROLLBACK_VERSION=0.9.3` and run `goto 4` because you want to go back to migration sequence 4 (v0.9.3's `000004`). -For example, `v0.9.9` has migrations up to `000005_a2a_protocol_version.up.sql` and `v0.9.3` has migrations up to `000004_feedback_single_pk.up.sql`. To roll back from `v0.9.9` to `v0.9.3`, you set `CURRENT_VERSION=0.9.9`, `ROLLBACK_VERSION=0.9.3`, and run `goto 4` because you want to go back to migration sequence 4 (v0.9.3's `000004`). - -1. Save your current kagent version and the kagent version you want to roll back to in environment variables. +1. Save the version you want to roll back to in an environment variable. ```bash - export CURRENT_VERSION= export ROLLBACK_VERSION= ``` -2. Install [`golang-migrate`](https://github.com/golang-migrate/migrate/tree/master/cmd/migrate). - -3. Stop the kagent controller. +2. Stop the kagent controller. ```bash kubectl -n kagent scale deploy/kagent-controller --replicas=0 ``` -4. Open the core migration directory for your rollback version and save the sequence number of the highest-numbered file in an environment variable, such as `4` from the previous v0.9.3 `goto 4` example. +3. Open the core migration directory for your rollback version and save the sequence number of the highest-numbered file in an environment variable. ```bash open "https://github.com/kagent-dev/kagent/tree/v${ROLLBACK_VERSION}/go/core/pkg/migrations/core/" ``` @@ -176,26 +211,21 @@ For example, `v0.9.9` has migrations up to `000005_a2a_protocol_version.up.sql` export ROLLBACK_MIGRATION_VERSION= ``` -5. Reset the core track. The `github://` source references the migration files directly from the release tag without a local checkout. For the database connection string, see [Database configuration](/docs/kagent/operations/operational-considerations#database-configuration). +4. Reset the core track. For the database connection string, see [Database configuration](/docs/kagent/operations/operational-considerations#database-configuration). ```bash - migrate \ - -source "github://kagent-dev/kagent/go/core/pkg/migrations/core#v$CURRENT_VERSION" \ - -database "postgres://:@:5432/?sslmode=require&x-migrations-table=schema_migrations" \ - goto $ROLLBACK_MIGRATION_VERSION + export POSTGRES_DATABASE_URL="postgres://:@:5432/" + kagent db migrate goto $ROLLBACK_MIGRATION_VERSION --source core ``` -6. If vector features are enabled, reset the vector track as well. - 1. Open the vector migration directory for your rollback version and save the sequence number of the highest-numbered file in an environment variable. +5. If vector features are enabled, reset the vector track as well. + 1. Open the vector migration directory for your rollback version and save the sequence number of the highest-numbered file. ```bash open "https://github.com/kagent-dev/kagent/tree/v${ROLLBACK_VERSION}/go/core/pkg/migrations/vector/" export ROLLBACK_VECTOR_MIGRATION_VERSION= ``` 2. Reset the vector track. ```bash - migrate \ - -source "github://kagent-dev/kagent/go/core/pkg/migrations/vector#v$CURRENT_VERSION" \ - -database "postgres://:@:5432/?sslmode=require&x-migrations-table=vector_schema_migrations" \ - goto $ROLLBACK_VECTOR_MIGRATION_VERSION + kagent db migrate goto $ROLLBACK_VECTOR_MIGRATION_VERSION --source vector ``` -7. After the database is at the correct schema version, follow the steps to [roll back the kagent application](#steps-to-roll-back). +6. After the database is at the correct schema version, follow the steps to [roll back the kagent application](#steps-to-roll-back). diff --git a/src/app/docs/kagent/resources/release-notes/page.mdx b/src/app/docs/kagent/resources/release-notes/page.mdx index 45e0084a..e3a3cd8c 100644 --- a/src/app/docs/kagent/resources/release-notes/page.mdx +++ b/src/app/docs/kagent/resources/release-notes/page.mdx @@ -18,6 +18,519 @@ The kagent documentation shows information only for the latest release. If you r For more details on the changes between versions, review the [kagent GitHub releases](https://github.com/kagent-dev/kagent/releases). +# v0.10 + +Review this summary of significant changes from kagent version 0.9 to v0.10. + +## What's included + +**Agent runtimes** + +* [Go ADK is now the default runtime](#go-adk-is-now-the-default-runtime): New declarative agents use the Go ADK by default. +* [A2A AgentCard metadata](#a2a-agentcard-metadata): New optional fields on the Agent spec for enriching the A2A AgentCard. +* [maxOutputTokens for Gemini and Vertex AI](#maxoutputtokens-for-gemini-and-vertex-ai): New `maxOutputTokens` field on Gemini and Vertex AI providers for capping model output length. +* [AWS Bedrock Guardrails](#aws-bedrock-guardrails): Native guardrail support for the Bedrock provider, enabling content filtering, topic denial, and PII redaction. + +**Helm & configuration** + +* [Configurable streaming timeouts](#configurable-streaming-timeouts): New Helm values for nginx proxy and client-side EventSource inactivity timeouts, including OpenShift HAProxy support. +* [Controller service annotations](#controller-service-annotations): New `controller.service.annotations` Helm value for integrations like AWS Load Balancer Controller and ExternalDNS. +* [Configurable A2A client timeout](#configurable-a2a-client-timeout): New `controller.a2aClientTimeout` Helm value removes the previous 3-minute hard cutoff for long-running agents. +* [UI HTTPRoute](#ui-httproute): New `ui.httpRoute` Helm value for fronting the UI with a Gateway API HTTPRoute (kgateway, Istio, Envoy Gateway). +* [Pod labels for controller and UI](#pod-labels-for-controller-and-ui): New `podLabels`, `controller.podLabels`, and `ui.podLabels` Helm values for pod template labels on the controller and UI Deployments. +* [Default nodeSelector for agent deployments](#default-nodeselector-for-agent-deployments): New `controller.agentDeployment.nodeSelector` Helm value applies a global default nodeSelector to all agent Deployments created by the controller. +* [Configurable Go ADK agent image](#configurable-go-adk-agent-image): New `controller.goAgentImage` Helm values configure the Go ADK runtime image independently, fixing mirror registry layouts that the previous derivation could not produce. +* [Max completion tokens for OpenAI](#max-completion-tokens-for-openai): New `openAI.maxCompletionTokens` field for capping output on reasoning models (o-series, GPT-5), which reject the deprecated `maxTokens` field. +* [ServiceAccount annotations](#serviceaccount-annotations): New `controller.serviceAccount.annotations` and `ui.serviceAccount.annotations` Helm values for cloud workload identity integrations (GCP, AWS IRSA, Azure). +* [extraObjects](#extraobjects): New `extraObjects` Helm value for deploying arbitrary Kubernetes manifests in the same chart lifecycle as kagent. +* [Deployment annotations](#deployment-annotations): New `controller.annotations` and `ui.annotations` Helm values for annotating the controller and UI Deployment resources. +* [nodeSelector for agent Helm charts](#nodeselector-for-agent-helm-charts): New `nodeSelector` value in every bundled agent Helm chart for pinning agent pods to specific node pools. +* [envFrom for agent deployments](#envfrom-for-agent-deployments): New `envFrom` field on the agent deployment spec for bulk-injecting environment variables from ConfigMaps and Secrets. +* [Disable default ModelConfig](#disable-default-modelconfig): Set `providers: null` to suppress the Helm-generated default `ModelConfig` and `Secret`. + +**Agent Substrate** + +* [ACP protocol support for substrate agents](#acp-protocol-support-for-substrate-agents): New ACP shim enabling WebSocket-to-stdio translation for agents running on substrate. +* [Substrate support for BYO and Python agents](#substrate-support-for-byo-and-python-agents): `SandboxAgent` now supports BYO and Python runtime agents in addition to Go declarative agents. +* [Durable session state for sandbox agents](#durable-session-state-for-sandbox-agents): Go and Python declarative sandbox agents now persist session history to a local SQLite database in the `durableDir` volume, surviving pod restarts and Deployment rollouts. + +**UI & auth** + +* [Chat session sharing](#chat-session-sharing): Session owners can now generate shareable links in read-only or read-write mode. +* [SSO session expiry re-authentication](#sso-session-expiry-re-authentication): Expired OIDC proxy sessions now automatically redirect to re-authenticate instead of showing an error. +* [MCP App chat widgets](#mcp-app-chat-widgets): MCP tools that expose UI resources now render interactive widgets inline in the chat interface. + +**Database** + +* [Out-of-band database migrations](#out-of-band-database-migrations): New `kagent db migrate` CLI and `database.postgres.skipMigrations` Helm value for managing migrations independently of controller startup. + +[**Additional changes**](#additional-changes-in-v010) + +## Go ADK is now the default runtime + +The default declarative agent runtime is now **Go**. Previously, new declarative agents used the Python ADK unless `runtime: go` was explicitly set. The Go ADK starts in approximately 2 seconds (versus ~15 seconds for Python) and uses fewer resources. + +Existing agents with an explicit `runtime: python` are unaffected. Agents that relied on the Python default will now use Go unless you add `runtime: python` to their spec. + +For a full comparison, see [Agents — Runtime](/docs/kagent/concepts/agents#runtime). + +## A2A AgentCard metadata + +You can now enrich your agent's [A2A AgentCard](https://google.github.io/A2A/specification/#5-agent-discovery-using-an-agent-card) with optional metadata fields on the `Agent` spec. The AgentCard is served from `/.well-known/agent.json` and is read by other agents and A2A-compatible clients when they discover your agent. + +```yaml +spec: + iconUrl: https://example.com/icons/my-agent.png + documentationUrl: https://docs.example.com/my-agent/ + version: "1.0.0" + provider: + organization: My Organization + url: https://example.com +``` + +| Field | Description | +|-------|-------------| +| `iconUrl` | URL to an icon image representing the agent. | +| `documentationUrl` | URL to human-readable documentation for the agent. | +| `version` | Version string for the agent, such as `"1.0.0"`. | +| `provider.organization` | Name of the organization responsible for the agent. | +| `provider.url` | URL to the agent provider's website or documentation. | + +For more information, see [Agents — A2A AgentCard metadata](/docs/kagent/concepts/agents#a2a-agentcard-metadata). + +## Configurable streaming timeouts + +New Helm values let you tune how long nginx and the browser keep streaming connections open. The defaults are all set to 1800 seconds (30 minutes). + +| Helm value | Default | Description | +|---|---|---| +| `ui.streamTimeoutSeconds` | `1800` | Client-side EventSource inactivity timeout. Exposed to the UI container at runtime. | +| `ui.nginx.proxyReadTimeout` | `1800` | nginx `proxy_read_timeout` for the UI sidecar. | +| `ui.nginx.proxySendTimeout` | `1800` | nginx `proxy_send_timeout` for the UI sidecar. | +| `ui.openshiftRoute.annotations` | — | Annotations added to the OpenShift Route resource. Set `haproxy.router.openshift.io/timeout: 120m` to prevent the default 60-second HAProxy timeout from terminating A2A and SSE streams. | + +Example for OpenShift deployments: + +```yaml +ui: + openshiftRoute: + annotations: + haproxy.router.openshift.io/timeout: 120m +``` + +For tuning timeouts end-to-end for long-running agent sessions, see [Long-running connections](/docs/kagent/operations/operational-considerations#long-running-connections). + +## Controller service annotations + +You can now add custom annotations to the kagent controller's Kubernetes Service via `controller.service.annotations`. This is useful for integrations such as AWS Load Balancer Controller and ExternalDNS. + +```yaml +controller: + service: + annotations: + service.beta.kubernetes.io/aws-load-balancer-type: external + external-dns.alpha.kubernetes.io/hostname: kagent.example.com +``` + +## Configurable A2A client timeout + +A new `controller.a2aClientTimeout` Helm value (default: `""` — no timeout) lets you override the A2A client HTTP timeout. Previously, the a2a-go SDK applied a hard 3-minute timeout to all A2A client requests, causing `context deadline exceeded` errors during long-running agent interactions or SSE streams. + +```yaml +controller: + a2aClientTimeout: "10m" # or "" for no timeout (default) +``` + +For more information, see [Long-running connections](/docs/kagent/operations/operational-considerations#long-running-connections). + +## UI HTTPRoute + +You can now front the kagent UI by a [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io/) `HTTPRoute` instead of a plain `Ingress` or OpenShift `Route`. This is useful when your cluster uses kgateway, Istio, or Envoy Gateway as its traffic management layer. + +The HTTPRoute is off by default. Enable it with `ui.httpRoute.enabled: true` and configure `parentRefs` and `hostnames`: + +```yaml +ui: + httpRoute: + enabled: true + parentRefs: + - name: my-gateway + namespace: istio-system + hostnames: + - kagent.example.com +``` + +For all UI exposure options including LoadBalancer service and OpenShift Route, see [Expose the UI outside the cluster](/docs/kagent/observability/launch-ui#expose-the-ui-outside-the-cluster). + +## Pod labels for controller and UI + +You can now add custom labels to the pod templates of the controller and UI Deployments. A global `podLabels` map applies to all component pods, with per-component overrides via `controller.podLabels` and `ui.podLabels` (component keys win on conflict). + +```yaml +podLabels: + team: platform + environment: production + +controller: + podLabels: + cost-center: infra + +ui: + podLabels: + cost-center: frontend +``` + +This is useful for clusters with admission policies (such as OPA Gatekeeper or Kyverno) that require specific labels on every pod template. Note that selector labels always take precedence and cannot be overridden. + +For more information, see [Customize Kubernetes resources](/docs/kagent/introduction/installation#customize-kubernetes-resources). + +## Default nodeSelector for agent deployments + +A new `controller.agentDeployment.nodeSelector` Helm value sets a global default nodeSelector applied to every agent Deployment created by the controller. Per-agent `nodeSelector` values in the `Agent` CRD take precedence over this default (per-key merge, agent wins). + +```yaml +controller: + agentDeployment: + nodeSelector: + kubernetes.io/os: linux +``` + +This is useful in clusters where admission policies (Gatekeeper, Kyverno) require a `nodeSelector` on every Deployment. Without this, agents created through the UI wizard carry no nodeSelector and fail admission. + +For more information, see [Customize Kubernetes resources](/docs/kagent/introduction/installation#customize-kubernetes-resources). + +## Configurable Go ADK agent image + +You can now use the `controller.goAgentImage` Helm values to configure the Go ADK runtime image independently of the main agent image. Previously, the controller derived the Go image repository from the Python image by replacing the last path segment with `golang-adk`. This pattern breaks in flat-name mirror registries where the image name cannot be produced by that derivation. + +```yaml +controller: + goAgentImage: + registry: my-registry.io + repository: kagent/golang-adk + tag: v0.10.0 + pullPolicy: IfNotPresent +``` + +The `registry` and `pullPolicy` fields default to the global `image.registry` and `image.pullPolicy` values. The `tag` coalesces to the global image tag, then the chart version. + +> **Breaking change for mirror registry operators**: If you mirror kagent images and only set `agentImage`, you must now also set `controller.goAgentImage` to point to your mirrored Go ADK image. The controller logs a startup warning when the Go image registry differs from the main image registry, so that a misconfigured mirror is visible before a Go agent fails to pull. + +For more information, see [Private registry and image mirroring](/docs/kagent/introduction/installation#private-registry-and-image-mirroring). + +## Max completion tokens for OpenAI + +OpenAI reasoning models (o-series, GPT-5) reject the `max_tokens` request parameter with a 400 error. Use the new `openAI.maxCompletionTokens` field instead, which maps to OpenAI's `max_completion_tokens` parameter and caps both visible output tokens and internal reasoning tokens. + +```yaml +spec: + provider: OpenAI + model: o3 + openAI: + reasoningEffort: medium + maxCompletionTokens: 16000 +``` + +The existing `openAI.maxTokens` field is unchanged and continues to work for standard models and OpenAI-compatible endpoints. The two fields are independent: set `maxCompletionTokens` for reasoning models and `maxTokens` only for endpoints that still require `max_tokens`. + +For more information, see [Max completion tokens](/docs/kagent/supported-providers/openai#max-completion-tokens). + +## ServiceAccount annotations + +You can now annotate the controller and UI Kubernetes ServiceAccounts via `controller.serviceAccount.annotations` and `ui.serviceAccount.annotations`. This standard mechanism is required for cloud provider workload identity integrations that grant IAM permissions by annotating a ServiceAccount. + +```yaml +controller: + serviceAccount: + annotations: + iam.gke.io/gcp-service-account: kagent@my-project.iam.gserviceaccount.com + +ui: + serviceAccount: + annotations: + iam.gke.io/gcp-service-account: kagent-ui@my-project.iam.gserviceaccount.com +``` + +For more information, see [Customize Kubernetes resources](/docs/kagent/introduction/installation#customize-kubernetes-resources). + +## extraObjects + +A new top-level `extraObjects` Helm value lets you deploy arbitrary Kubernetes manifests in the same chart lifecycle as kagent. Entries are rendered through `tpl`, so they can reference the release context such as `{{ .Release.Namespace }}`. + +```yaml +extraObjects: + - apiVersion: external-secrets.io/v1beta1 + kind: ExternalSecret + metadata: + name: kagent-api-key + namespace: "{{ .Release.Namespace }}" + spec: + refreshInterval: 1h + secretStoreRef: + name: my-store + kind: ClusterSecretStore + target: + name: kagent-api-key + data: + - secretKey: ANTHROPIC_API_KEY + remoteRef: + key: anthropic-api-key +``` + +For more information, see [Customize Kubernetes resources](/docs/kagent/introduction/installation#customize-kubernetes-resources). + +## Deployment annotations + +You can now add custom annotations to the kagent controller and UI Deployment resources. A global `annotations` map applies to all deployments, with per-component overrides via `controller.annotations` and `ui.annotations`. + +```yaml +controller: + annotations: + cluster-autoscaler.kubernetes.io/safe-to-evict: "false" + +ui: + annotations: + cluster-autoscaler.kubernetes.io/safe-to-evict: "false" +``` + +This is useful for tools that read Deployment annotations such as cluster autoscaler, Datadog, and Karpenter. + +For more information, see [Customize Kubernetes resources](/docs/kagent/introduction/installation#customize-kubernetes-resources). + +## nodeSelector for agent Helm charts + +Every bundled agent Helm chart now accepts an optional `nodeSelector` value. Use it to constrain agent pods to specific node pools. + +```yaml +# Per-agent chart +nodeSelector: + disktype: ssd +``` + +When installing agents through the parent `kagent` chart, pass the value under the dependency name: + +```yaml +helm-agent: + nodeSelector: + kubernetes.io/os: linux +k8s-agent: + nodeSelector: + kubernetes.io/os: linux +``` + +When unset, `nodeSelector` is omitted entirely, so there is no change for existing deployments. + +## ACP protocol support for substrate agents + +kagent now includes an [ACP (Agent Client Protocol)](https://agentclientprotocol.com/) shim in the base images for agents running on substrate. The shim reuses the WebSocket connection from the substrate actor and translates it to stdio, enabling agents built with OpenClaw and Hermes to communicate over the substrate runtime without additional configuration. + +For more information, see [Agent Substrate](/docs/kagent/concepts/agent-substrate). + +## Substrate support for BYO and Python agents + +`SandboxAgent` now supports running BYO agents and Python runtime declarative agents on Agent Substrate, in addition to Go declarative agents. This means any `Agent` type can be run as a sandboxed substrate workload. + +For setup details, see [Agent Substrate](/docs/kagent/concepts/agent-substrate). + +## Durable session state for sandbox agents + +Go and Python declarative `SandboxAgent` instances now persist session history to a local SQLite database backed by the agent's `durableDir` volume. Session history survives pod restarts and Deployment rollouts; for example, a previous conversation continues seamlessly after a rollout triggered by a prompt change. + +Session metadata is mirrored to the PostgreSQL database to support session-listing APIs. BYO agents do not get local session storage automatically; set the `kagent.dev/local-session-storage` annotation on the `SandboxAgent` if your BYO agent implements its own local store and you want to enable the same behavior. + +You can override the session database endpoint with the `KAGENT_SESSION_DB_URL` environment variable. + +For more information, see [Agent Substrate — Declarative agents](/docs/kagent/concepts/agent-substrate#declarative-agents). + +## Chat session sharing + +Session owners can now generate shareable links for any chat session. Shared sessions support two modes: + +- **Read-only** (default): Recipients can view the conversation but cannot send messages or respond to tool confirmations. Useful for review, handoff documentation, and broadcasting agent output. +- **Read-write** (interactive): Recipients can interact with the session as if they were the owner, such as sending messages, approving or rejecting tool calls, and answering agent questions. All parties see the results in real time. + +Shared sessions that a user has accessed appear in their sidebar alongside their own sessions, so recipients do not need to keep the original link to return. Agents can also generate and revoke share links as part of their own workflows. + +Read-only share tokens can also read A2A tasks on the shared session (`ListTasks`, `GetTask`, `SubscribeToTask`). Mutating operations (`SendMessage`, `CancelTask`) still require a read-write share token. + +## SSO session expiry re-authentication + +When deployed behind an OIDC proxy (such as oauth2-proxy), expired sessions now trigger an automatic redirect to `/oauth2/start` for re-authentication instead of showing an error. A loop guard prevents infinite redirects if re-authentication fails. Sessions in unsecured (no-proxy) mode are unaffected. + +## MCP App chat widgets + +MCP tools that expose UI resources (MCP Apps) now render interactive widgets inline in the kagent chat interface. When an agent calls such a tool, the response appears as an embedded widget rather than raw text, and users can interact with it directly in the chat window. The backend compacts MCP App tool responses sent to the model to prevent redundant repeated calls. + +## Out-of-band database migrations + +Two new features give operators control over when and how database migrations run. + +### kagent db migrate CLI + +A new `kagent db migrate` command group lets you apply, inspect, and recover database migrations without relying on controller startup. This is useful for CI/CD pipelines and environments where migration timing must be explicit. + +| Subcommand | Description | +|---|---| +| `kagent db migrate up` | Apply all pending migrations across all sources. | +| `kagent db migrate status` | Show applied and pending migration counts per source. | +| `kagent db migrate version` | Print the highest applied version per source. | +| `kagent db migrate goto V --source ` | Move the schema to version V (forward or backward). Used for rollbacks. | +| `kagent db migrate down N --source ` | Roll back the N most recent migrations on the named source. | +| `kagent db migrate force V --source ` | Mark version V as applied without running SQL. Used to recover from a dirty migration state. | + +Set `POSTGRES_DATABASE_URL` or pass `--db-url` to provide the database connection string. If `DATABASE_VECTOR_ENABLED` is not set in the environment, the CLI reads it from the `kagent-controller` ConfigMap in the current cluster context. + +### Skip startup migrations + +A new `database.postgres.skipMigrations` Helm value (default: `false`) prevents the controller from running migrations at startup. When enabled, the controller verifies the schema is already fully migrated and exits with an error if it is not. Apply migrations out-of-band before installing or upgrading when this option is set. + +For details and usage examples, see [Run migrations out-of-band](/docs/kagent/operations/upgrade#run-migrations-out-of-band). + +## maxOutputTokens for Gemini and Vertex AI + +The `maxOutputTokens` field is now wired for the native Gemini and Vertex AI providers. Previously, this field was declared on `GeminiVertexAIConfig` but never applied, and `GeminiConfig` did not define this field at all. + +```yaml +spec: + provider: Gemini + model: gemini-2.5-pro + gemini: + maxOutputTokens: 8192 +``` + +```yaml +spec: + provider: GeminiVertexAI + model: gemini-2.5-pro + geminiVertexAI: + project: my-project + location: us-central1 + maxOutputTokens: 8192 +``` + +A per-request value set by the agent always takes precedence over the model-level default. + +For more information, see [Gemini](/docs/kagent/supported-providers/gemini#max-output-tokens) and [Vertex AI](/docs/kagent/supported-providers/google-vertexai). + +## AWS Bedrock Guardrails + +You can now apply native [AWS Bedrock Guardrails](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html) directly from `ModelConfig`. The controller passes the guardrail configuration to the Bedrock Converse and ConverseStream APIs, enabling content filtering, topic denial, and PII redaction without an external proxy. + +```yaml +spec: + provider: Bedrock + model: us.anthropic.claude-sonnet-4-20250514-v1:0 + bedrock: + region: us-east-1 + guardrail: + identifier: "abc123def456" + version: "1" + trace: "enabled" +``` + +| Field | Description | +|---|---| +| `identifier` | The guardrail ID or ARN. Required when the `guardrail` block is present. | +| `version` | The guardrail version to apply. Required when the `guardrail` block is present. | +| `trace` | Trace mode: `disabled` (default), `enabled`, or `enabled_full`. | + +Guardrail interventions apply before content returns to the caller so that blocked content does not leak to the stream. Interventions surface in the response content rather than as hard errors, allowing the agent loop to continue. + +For more information, see [Amazon Bedrock — Bedrock Guardrails](/docs/kagent/supported-providers/amazon-bedrock#bedrock-guardrails). + +## envFrom for agent deployments + +You can now bulk-inject environment variables from ConfigMaps and Secrets into agent pods using the `envFrom` field on the agent deployment spec. This field complements the existing `env` field, which requires enumerating individual keys. + +```yaml +apiVersion: kagent.dev/v1alpha2 +kind: Agent +spec: + declarative: + deployment: + envFrom: + - configMapRef: + name: my-agent-config + - secretRef: + name: my-agent-secrets +``` + +For more information, see [Agents — Deployment configuration](/docs/kagent/concepts/agents#deployment-configuration). + +## Disable default ModelConfig + +To suppress the default `ModelConfig` and its associated `Secret` from being created, set `providers: null` in your Helm values. This setting is useful when you manage `ModelConfig` resources outside of the kagent Helm chart. + +```yaml +providers: null +``` + +When `providers` is unset or null, neither the `modelconfig` nor the `modelconfig-secret` templates are rendered. Existing installs that define `providers` are unaffected. + +For more information, see [Disable the default ModelConfig](/docs/kagent/introduction/installation#disable-the-default-modelconfig). + +## Additional changes in v0.10 + +**Security** + +* **CVE patches**: Critical and high CVEs patched in the Go ADK and app container images. +* **A2A task security scoping**: Task `get`, `create`, and `delete` operations are now scoped to the session owner, preventing one user from accessing another user's A2A tasks. + +**Helm and configuration** + +* **Image registry updated to ghcr.io**: The `cr.kagent.dev` registry alias is removed. All default image references now use `ghcr.io/kagent-dev/kagent`. If you pinned images using the `cr.kagent.dev` alias, update your references to `ghcr.io`. +* **Helm image registry fixes**: Helm charts for the grafana-mcp and querydoc subcharts now correctly handle an empty `image.registry` value, avoiding malformed image paths in air-gapped or registry-less deployments. +* **Declarative agents referenced by tag**: Regular declarative agent images are now referenced by tag (`registry/repository:tag`) rather than digest, so they respect `IMAGE_TAG` overrides. Digest pinning is kept for sandbox agents where Substrate requires it. New controller flags (`--app-image-digest`, `--golang-adk-image-digest`, and their `-full` variants) let operators override baked-in sandbox digests when using a mirror registry. +* **Configurable cluster DNS domain**: A `clusterDomain` controller setting (default `cluster.local`) makes the in-cluster service URLs configurable for clusters that use a non-standard DNS domain. +* **`kgateway.dev/a2a` appProtocol for BYO agents**: The controller now sets `kgateway.dev/a2a` as the `appProtocol` on the Service for BYO agents, which is required for A2A routing to work correctly in kgateway environments. +* **`nodeSelector` and `tolerations` for `kagent-tools` subchart**: The `kagent-tools` bundled subchart now accepts `nodeSelector` and `tolerations` values, so tools pods can be placed on specific nodes or tolerate taints. +* **oauth2-proxy subchart updated to ~10.7.0**: The bundled oauth2-proxy dependency is bumped to the 10.7.x chart series. +* **Custom annotations on the default ModelConfig**: A new per-provider `annotations` map under `providers..annotations` is applied to the Helm-generated default ModelConfig. Useful for downstream tooling or UI extensions that key off resource annotations. +* **`deploymentAnnotations` for agent deployments**: New `deploymentAnnotations` field on the agent deployment spec sets annotations on the Deployment object itself. The existing `annotations` field targets pod template metadata only. Useful for GitOps tooling such as Argo CD sync waves, Flux, and Kyverno policies that key off Deployment-level annotations. + +**Agent runtimes and providers** + +* **Go ADK v2.0.0**: The Go Agent Development Kit is upgraded to v2.0.0. +* **Anthropic thinking blocks in Python ADK**: Google ADK bumped to 1.32.0, enabling Anthropic thinking block support for agents using the Python runtime. +* **Go ADK OpenAI embeddings**: Fixed embeddings generation when using the OpenAI provider with the Go ADK runtime. +* **Python ADK minimum version is now 3.11**: The Python Agent Development Kit now requires Python 3.11 or later. +* **Claude ACP sandbox image**: A new `acp-sandbox-claude` image wraps the Claude Agent SDK behind the ACP protocol, enabling Claude-based agents to run in the ACP sandbox alongside the existing openclaw and hermes targets. Authenticate via `ANTHROPIC_API_KEY` at runtime. +* **`none` reasoning effort**: `none` is now a valid option for reasoning effort on `ModelConfig`, in addition to the existing `low`, `medium`, and `high` values. +* **`xhigh` reasoning effort**: `xhigh` is now a valid value for `openAI.reasoningEffort`, in addition to `none`, `minimal`, `low`, `medium`, and `high`. +* **Bedrock nil tool-call args fix**: Nil tool-call arguments from the Bedrock API are now coerced to an empty JSON object before processing, preventing a nil-pointer panic in the Go ADK runtime. +* **Azure OpenAI secretKeyRef fix**: Fixed an issue where an empty `secretKeyRef` was generated for Azure OpenAI model configurations that do not use a Kubernetes secret for credentials. +* **Azure OpenAI API key env var name**: The `AZURE_OPENAI_API_KEY` environment variable name is now used consistently throughout the codebase, fixing providers that were reading a mismatched key name. +* **OpenTelemetry double-instrumentation fix**: The OpenAI client is no longer double-instrumented on the Go ADK runtime, preventing duplicate spans in OTel traces when using OpenAI with the Go runtime. +* **Configurable Bedrock read/connect timeout**: New `bedrock.readTimeout` and `bedrock.connectTimeout` fields on `ModelConfig` replace the ~60s botocore default that caused `ReadTimeoutError` on long completions. Both values are in seconds and are optional. +* **RFC 8707 resource and audience for STS token exchange**: The Go and Python ADK token-propagation plugins now read `KAGENT_STS_RESOURCE` and `KAGENT_STS_AUDIENCE` environment variables to scope issued STS tokens to a specific backend. Backwards compatible so that existing deployments are unaffected when neither variable is set. + +**Agent Substrate** + +* **Substrate actor namespace scoping**: Actors created by `SandboxAgent` and `AgentHarness` are now isolated per Kubernetes namespace, so that actors in different namespaces cannot see or conflict with each other. Also fixes an infinite `ActorTemplate` delete/recreate loop caused by `SnapshotsConfig` defaults drift. +* **SandboxAgent readiness gating**: `SandboxAgent` actors are now only marked ready once the agent application is confirmed to be serving traffic, preventing requests from reaching actors that have started but are not yet initialized. +* **Agent Substrate bumped to v0.0.9**: The bundled Agent Substrate runtime is updated to v0.0.9. +* **Substrate badge on agent cards**: Sandbox agents running on Agent Substrate are now visually marked in the UI agent card list. +* **OTel trace flush for substrate agents**: Trace spans are now force-flushed before the A2A response completes for substrate agents, ensuring spans are not lost at the end of a session. + +**Database** + +* **Migration orchestrator**: The internal database migration runner is refactored from two hardcoded tracks to an extensible orchestrator with ordered source registration and coordinated rollback. No change to the `kagent db migrate` CLI. +* **Concurrent memory search deadlock fix**: Fixed intermittent PostgreSQL deadlocks when concurrent memory searches (such as `PrefetchMemoryTool` fan-out) updated overlapping rows. Row locks are now acquired in ID order and access-count updates are best-effort. +* **Memory vector search normalization**: Agent names are now normalized before querying the memory vector index, fixing cases where a name stored in mixed case would miss records indexed under a different casing. +* **Database checkpoint write performance**: Session checkpoint writes are now batched, removing an N+1 query pattern that caused performance degradation for long conversations. + +**Reliability and UI** + +* **MCP server startup resilience**: An MCP toolset is no longer silently dropped when an MCP server is unreachable at agent startup. The error is surfaced rather than causing tools to disappear. +* **Agent ready on first available replica**: An agent is now marked ready as soon as at least one replica is available, rather than waiting for all replicas. +* **A2A `ListTasks` served from the task store**: `ListTasks` calls over A2A now return results from a persistent task store rather than being rebuilt from event history, improving reliability and performance for long sessions. +* **UI tool call grouping**: Tool calls in the chat interface are now visually grouped, making it easier to follow multi-step agent reasoning. +* **Model config name editing fix**: Fixed an issue where the model name field could not be edited on the model configuration form in the UI. +* **UI rendering optimization**: Redundant background fetches in the chat interface are reduced, improving rendering performance for long sessions. +* **ADK token refresh loop resilience**: Exceptions during token reads in the Python ADK no longer kill the background refresh goroutine. Failed reads are logged and the loop continues on the next cycle instead of silently stopping. +* **ACP shim teardown deadlock fix**: Fixed a deadlock where `terminate()` could hang indefinitely when a WebSocket client stalled, blocking the stdout reader goroutine on a full channel and preventing the shim from shutting down. +* **ADK session state with `num_recent_events`**: Fixed a bug where `session.state` was built from only the last `n` events when `num_recent_events` was set, silently dropping state deltas from older events. Full event history is now always used to compute state; `num_recent_events` only trims the returned events list. + # v0.9 Review this summary of significant changes from kagent version 0.8 to v0.9. @@ -30,11 +543,11 @@ Review this summary of significant changes from kagent version 0.8 to v0.9. **What's included:** -* Agent Sandbox — run agents in isolated sandboxes with network controls using the Kubernetes agent-sandbox project. -* OIDC proxy authentication — optional enterprise authentication via oauth2-proxy with support for Cognito, Okta, Dex, and other OIDC providers. -* SAP AI Core provider — new model provider for SAP AI Core via the Orchestration Service. -* Database migration tooling — the database backend is refactored from GORM + AutoMigrate to golang-migrate + sqlc. -* Bedrock embedding support — native Bedrock embedding models for agent memory. +* Agent Sandbox: Run agents in isolated sandboxes with network controls using the Kubernetes agent-sandbox project. +* OIDC proxy authentication: Optional enterprise authentication via oauth2-proxy with support for Cognito, Okta, Dex, and other OIDC providers. +* SAP AI Core provider: New model provider for SAP AI Core via the Orchestration Service. +* Database migration tooling: The database backend is refactored from GORM + AutoMigrate to golang-migrate + sqlc. +* Bedrock embedding support: Native Bedrock embedding models for agent memory. ## Agent Sandbox @@ -133,32 +646,32 @@ Before you upgrade: ## Additional changes in v0.9 -* **Default model update** — the retired `claude-3-5-haiku-20241022` model is replaced with `claude-haiku-4-5`. -* **Bedrock embedding support** — native Bedrock embedding models are now available for agent memory, extending the existing AWS Bedrock provider. -* **Token exchange for model auth** — a new authentication mechanism that supports token exchange for model configurations. -* **Prompt templates in UI** — prompt templates are now manageable directly in the UI. -* **Require approval toggle in UI** — you can now enable or disable the `requireApproval` setting for tools directly in the UI. -* **Enhanced Go ADK model config** — broader model and provider support in the Go runtime. -* **IPv6/dual-stack support** — agent bind host and UI probes now support IPv6 and dual-stack configurations. -* **AWS LoadBalancer annotations** — the UI Service now supports AWS LoadBalancer service annotations for easier AWS deployment. -* **SSH auth for git-based skills** — fixed SSH authentication when loading skills from private Git repositories. -* **MCP connection error handling** — MCP connection errors are now returned to the LLM as context instead of raising exceptions. -* **RemoteMCPServer TLS (v0.9.6)** — you can now connect to an MCP server that uses a private CA, self-signed certificate, or corporate internal CA by setting the `spec.tls` field on a `RemoteMCPServer`. The `spec.tls` shape mirrors the `ModelConfig` TLS configuration. +* **Default model update**: The retired `claude-3-5-haiku-20241022` model is replaced with `claude-haiku-4-5`. +* **Bedrock embedding support**: Native Bedrock embedding models are now available for agent memory, extending the existing AWS Bedrock provider. +* **Token exchange for model auth**: A new authentication mechanism that supports token exchange for model configurations. +* **Prompt templates in UI**: Prompt templates are now manageable directly in the UI. +* **Require approval toggle in UI**: You can now enable or disable the `requireApproval` setting for tools directly in the UI. +* **Enhanced Go ADK model config**: Broader model and provider support in the Go runtime. +* **IPv6/dual-stack support**: Agent bind host and UI probes now support IPv6 and dual-stack configurations. +* **AWS LoadBalancer annotations**: The UI Service now supports AWS LoadBalancer service annotations for easier AWS deployment. +* **SSH auth for git-based skills**: Fixed SSH authentication when loading skills from private Git repositories. +* **MCP connection error handling**: MCP connection errors are now returned to the LLM as context instead of raising exceptions. +* **RemoteMCPServer TLS (v0.9.6)**: You can now connect to an MCP server that uses a private CA, self-signed certificate, or corporate internal CA by setting the `spec.tls` field on a `RemoteMCPServer`. The `spec.tls` shape mirrors the `ModelConfig` TLS configuration. # v0.8 Review this summary of significant changes from kagent version 0.7 to v0.8. -* Human-in-the-Loop (HITL) — tool approval gates and interactive `ask_user` tool. -* Agent Memory — vector-backed long-term memory for agents. -* Go ADK runtime — new Go-based agent runtime for faster startup and lower resource usage. -* Agents as MCP servers — expose A2A agents via MCP for cross-tool interoperability. -* Skills — markdown knowledge documents loaded from OCI images or Git repositories. -* Go workspace restructure — the Go codebase is split into `api`, `core`, and `adk` modules for composability. -* Prompt templates — reusable prompt fragments from ConfigMaps using Go template syntax. -* Context management — automatic event compaction for long conversations. -* AWS Bedrock support — new model provider for AWS Bedrock. -* **PostgreSQL-only database backend** — SQLite support has been removed. PostgreSQL is now the only supported database backend. +* Human-in-the-Loop (HITL): Tool approval gates and interactive `ask_user` tool. +* Agent Memory: Vector-backed long-term memory for agents. +* Go ADK runtime: New Go-based agent runtime for faster startup and lower resource usage. +* Agents as MCP servers: Expose A2A agents via MCP for cross-tool interoperability. +* Skills: Markdown knowledge documents loaded from OCI images or Git repositories. +* Go workspace restructure: The Go codebase is split into `api`, `core`, and `adk` modules for composability. +* Prompt templates: Reusable prompt fragments from ConfigMaps using Go template syntax. +* Context management: Automatic event compaction for long conversations. +* AWS Bedrock support: New model provider for AWS Bedrock. +* **PostgreSQL-only database backend**: SQLite support has been removed. PostgreSQL is now the only supported database backend. ## Human-in-the-Loop (HITL) diff --git a/src/app/docs/kagent/supported-providers/amazon-bedrock/page.mdx b/src/app/docs/kagent/supported-providers/amazon-bedrock/page.mdx index 3c798a81..846295ee 100644 --- a/src/app/docs/kagent/supported-providers/amazon-bedrock/page.mdx +++ b/src/app/docs/kagent/supported-providers/amazon-bedrock/page.mdx @@ -106,6 +106,51 @@ spec: If you want to use one shared ServiceAccount for multiple agents, you can also set `controller.agentDeployment.serviceAccountName` in the [Helm chart configuration](/docs/kagent/resources/helm). +## Bedrock Guardrails + +You can apply [AWS Bedrock Guardrails](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html) directly from the native Bedrock `ModelConfig` to enable content filtering, topic denial, and PII redaction. The guardrail applies on every request to the Converse and ConverseStream APIs. + +```yaml +spec: + provider: Bedrock + model: us.anthropic.claude-sonnet-4-20250514-v1:0 + bedrock: + region: us-east-1 + guardrail: + identifier: "abc123def456" + version: "1" + trace: "enabled" +``` + +| Field | Description | +|---|---| +| `bedrock.guardrail.identifier` | The guardrail ID or ARN. Required when the `guardrail` block is present. | +| `bedrock.guardrail.version` | The guardrail version to apply. Required when the `guardrail` block is present. | +| `bedrock.guardrail.trace` | Trace mode: `disabled` (default), `enabled`, or `enabled_full`. | + +Guardrail interventions apply before content returns to the caller so that blocked content does not leak to the stream. Interventions surface in the response content rather than as hard errors, allowing the agent loop to continue. + +## Request timeouts + +By default, the Bedrock client uses botocore's ~60 second read timeout, which can cause `ReadTimeoutError` on long completions. To override these values, use `bedrock.readTimeout` and `bedrock.connectTimeout`. + +```yaml +spec: + provider: Bedrock + model: us.anthropic.claude-sonnet-4-20250514-v1:0 + bedrock: + region: us-east-1 + readTimeout: 1800 + connectTimeout: 30 +``` + +| Field | Description | +|---|---| +| `bedrock.readTimeout` | Maximum seconds to wait for a response chunk. Minimum: 1. | +| `bedrock.connectTimeout` | Maximum seconds to wait for the initial connection. Minimum: 1. Optional. | + +Both fields are optional. When neither is set, botocore defaults apply and existing behavior is unchanged. + ## Option 2: OpenAI-compatible API You can also use Bedrock models via the [OpenAI Chat Completions API](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-chat-completions.html). This option is useful when you need compatibility with the OpenAI API format or when using Bedrock's inference profiles. diff --git a/src/app/docs/kagent/supported-providers/gemini/page.mdx b/src/app/docs/kagent/supported-providers/gemini/page.mdx index 67a3b57d..4fde4aad 100644 --- a/src/app/docs/kagent/supported-providers/gemini/page.mdx +++ b/src/app/docs/kagent/supported-providers/gemini/page.mdx @@ -47,3 +47,17 @@ spec: 4. Apply the above resource to the cluster. Once the resource is applied, you can select the model from the Model dropdown in the UI when creating or updating agents. + +## Max output tokens + +Use `gemini.maxOutputTokens` to cap the number of tokens that the model can generate in a single response. + +```yaml +spec: + provider: Gemini + model: gemini-2.5-pro + gemini: + maxOutputTokens: 8192 +``` + +A per-request value set by the agent always takes precedence over this model-level default. diff --git a/src/app/docs/kagent/supported-providers/openai/page.mdx b/src/app/docs/kagent/supported-providers/openai/page.mdx index c5855bde..8bc84f51 100644 --- a/src/app/docs/kagent/supported-providers/openai/page.mdx +++ b/src/app/docs/kagent/supported-providers/openai/page.mdx @@ -40,3 +40,34 @@ For OpenAI's standard models like GPT-4 and GPT-3.5, kagent automatically config 3. Apply the above resource to the cluster. Once the resource is applied, you can select the model from the Model dropdown in the UI when creating or updating agents. + +## Reasoning effort + +For OpenAI reasoning models (o-series, GPT-5), you can control how many reasoning tokens the model generates before producing a response with the `openAI.reasoningEffort` field. Valid values are `none`, `minimal`, `low`, `medium`, `high`, and `xhigh`. + +For models that require reasoning to be explicitly disabled (such as some GPT-5 variants), set `reasoningEffort: none`. For standard models that do not support it, omit the field. + +```yaml +spec: + provider: OpenAI + model: o3 + openAI: + reasoningEffort: medium +``` + +## Max completion tokens + +For OpenAI reasoning models (o-series, GPT-5), use `openAI.maxCompletionTokens` to cap the total number of tokens the model can generate in a response, including both visible output tokens and reasoning tokens. + +> **Note**: Do not use `openAI.maxTokens` for reasoning models. OpenAI deprecated `max_tokens` for the Chat Completions API, and reasoning models reject it outright with a 400 error. Use `maxCompletionTokens` instead. + +```yaml +spec: + provider: OpenAI + model: o3 + openAI: + reasoningEffort: medium + maxCompletionTokens: 16000 +``` + +For standard (non-reasoning) models and OpenAI-compatible endpoints, `openAI.maxTokens` continues to work as before. The two fields are independent.