diff --git a/docs-site/content/kagent/concepts/agent-substrate.md b/docs-site/content/kagent/concepts/agent-substrate.md index 85e7ff20..f27c74f4 100644 --- a/docs-site/content/kagent/concepts/agent-substrate.md +++ b/docs-site/content/kagent/concepts/agent-substrate.md @@ -5,7 +5,7 @@ weight: 5 author: kagent.dev --- -Agent Substrate is a Kubernetes-native runtime for running AI agents and other stateful workloads efficiently. Instead of dedicating one pod per agent — which wastes capacity while agents sit idle — Substrate decouples an agent's lifecycle from pod infrastructure. Idle agents are snapshotted to object storage and rehydrated on demand, so a small pool of pre-warmed workers can host far more agents than there are pods. +Agent Substrate is a Kubernetes-native runtime for running AI agents and other stateful workloads efficiently. Instead of dedicating one pod per agent, which wastes capacity while agents sit idle, Substrate decouples an agent's lifecycle from pod infrastructure. Idle agents are snapshotted to object storage and rehydrated on demand, so a small pool of pre-warmed workers can host far more agents than there are pods. kagent can run workloads on Agent Substrate in two ways: @@ -14,10 +14,10 @@ kagent can run workloads on Agent Substrate in two ways: ## Why Agent Substrate -- **Fast startup** — Agents cold-start by restoring a compressed snapshot rather than booting a fresh pod, so they resume in a fraction of the time. -- **Efficient resource usage** — A pool of pre-warmed workers multiplexes many actors across far fewer pods, persisting idle actors to object storage instead of holding a pod each. -- **Secure execution** — Each workload runs inside a gVisor sandbox, isolating untrusted agent code from the host and from other actors. -- **Declarative management** — WorkerPools and ActorTemplates are Kubernetes CRDs, so the runtime is configured and versioned with the same GitOps workflow as the rest of your platform. +- **Fast startup**: Agents cold-start by restoring a compressed snapshot rather than booting a fresh pod, so they resume in a fraction of the time. +- **Efficient resource usage**: A pool of pre-warmed workers multiplexes many actors across far fewer pods, persisting idle actors to object storage instead of holding a pod each. +- **Secure execution**: Each workload runs inside a gVisor sandbox, isolating untrusted agent code from the host and from other actors. +- **Declarative management**: WorkerPools and ActorTemplates are Kubernetes CRDs, so the runtime is configured and versioned with the same GitOps workflow as the rest of your platform. ## Core concepts @@ -31,7 +31,7 @@ kagent can run workloads on Agent Substrate in two ways: ## How it works -When an agent is invoked, Substrate restores its actor onto an available worker from the WorkerPool — rehydrating from a snapshot if the actor was idle. The agent runs inside a gVisor sandbox for the duration of the session. When the actor goes idle, its state is checkpointed back to object storage and the worker is freed to host another actor. This snapshot-and-restore cycle is what lets a single worker pool serve many more agents than a pod-per-agent model. +When an agent is invoked, Substrate restores its actor onto an available worker from the WorkerPool, rehydrating from a snapshot if the actor was idle. The agent runs inside a gVisor sandbox for the duration of the session. When the actor goes idle, its state is checkpointed back to object storage and the worker is freed to host another actor. This snapshot-and-restore cycle is what lets a single worker pool serve many more agents than a pod-per-agent model. ## Architecture @@ -56,7 +56,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/docs-site/content/kagent/concepts/agents.md b/docs-site/content/kagent/concepts/agents.md index 9cd432b2..b7ce79f0 100644 --- a/docs-site/content/kagent/concepts/agents.md +++ b/docs-site/content/kagent/concepts/agents.md @@ -15,7 +15,7 @@ Each agent consists of the following components: ## Agent Instructions -Agent instructions tell the agent what its role is, how to interact with the user, what actions it can take, how to behave and respond to user queries, and how to interact with other agents. Here's an example of simple agent instructions: +Agent instructions tell the agent what its role is, how to interact with the user, what actions it can take, how to behave and respond to user queries, and how to interact with other agents. The following example shows simple agent instructions: ```yaml You're a Kubernetes agent that can help users manage their Kubernetes resources. @@ -24,7 +24,7 @@ Your responses should be clear and concise; you should provide helpful informati Instructions are an important part of the agent's behavior. They define the agent's role and capabilities and help the agent understand its environment and the tasks it can perform. -Writing good instructions is an art and a science. It requires a good understanding of the task at hand, the tools available, and the user's needs. In order to make it easier to write good instructions, we've created a [system prompt tutorial](/docs/kagent/getting-started/system-prompts) that can help you get started. +Writing good instructions is an art and a science. It requires a good understanding of the task at hand, the tools available, and the user's needs. To help you write good instructions, see the [system prompt tutorial](/docs/kagent/getting-started/system-prompts). ### Prompt templates @@ -86,13 +86,13 @@ Tools are functions that the agent can use to interact with its environment. For Tools definitions and their descriptions are made available to the agent and are sent to the LLMs together with the instructions. Based on the user query, the agent can use the tools to interact with the environment and generate responses. -For example, we could add the **list_resources** tool to agent that would allow it to list resources in the Kubernetes cluster. The agent will determine based on the user input if it makes sense to invoke any of the available tools. +For example, add the **list_resources** tool to your agent to allow it to list resources in the Kubernetes cluster. The agent determines, based on user input, whether to invoke any available tools. -If the user asks "List all pods in the cluster", the agent can use the **list_resources** tool to list all pods in the cluster. Note that depending on how the instructions/tools are written and configure, the agent might list all the namespaces first then list all the pods in each namespace. Alternatively, if the **list_resources** tool allows listing resources across namespaces, the agent will pick that option. +If the user asks "List all pods in the cluster", the agent can use the **list_resources** tool to list all pods in the cluster. Depending on how the instructions and tools are configured, the agent might list all namespaces first, then list all pods in each namespace. Alternatively, if the **list_resources** tool allows listing resources across namespaces, the agent picks that option. -Some tools support additional configuration that can be set in when adding the tool to the agent. For example, any Grafana or Prometheus tools will require an API endpoint URL to be set. +Some tools support additional configuration that you set when adding the tool to the agent. For example, any Grafana or Prometheus tools will require an API endpoint URL to be set. -kagent comes with a set of built-in tools that you can use to interact with your environment. kagent also supports the [MCP (Model Configuration Protocol)](https://modelcontextprotocol.io/introduction) tools. Using MCP, you can bring any external tool into kagent and make it available for your agents to run. +kagent comes with a set of built-in tools that you can use to interact with your environment. kagent also supports [MCP (Model Context Protocol)](https://modelcontextprotocol.io/introduction) tools. Using MCP, you can bring any external tool into kagent and make it available for your agents to run. ## Human-in-the-Loop @@ -149,7 +149,7 @@ Skills can refer to two broad types: ### A2A skills metadata -Actions-to-actions (A2A) skills are metadata—structured descriptions of capabilities, not executable code. Think of A2A skills as a machine-readable catalog entry about what a tool can do. +Actions-to-actions (A2A) skills are metadata: structured descriptions of capabilities, not executable code. Think of A2A skills as a machine-readable catalog entry about what a tool can do. A2A skills metadata describes: @@ -214,6 +214,35 @@ skills: A single `gitAuthSecretRef` applies to all Git repositories in the agent. You can combine Git and OCI skills in the same agent by specifying both `refs` and `gitRefs`. +### S3-based skills + +You can load skills directly from S3 — either a folder prefix (a path ending with `/` that contains a `SKILL.md` and sibling files) or a single `.zip` archive. Credentials use the AWS SDK default credential chain, which you supply as environment variables on the skills init container. + +```yaml +skills: + s3Refs: + - uri: s3://kagent-skills-bucket/team-a/kebab-maker # folder prefix + name: kebab-maker + - uri: s3://kagent-skills-bucket/bundles/ops.zip # zip archive + region: us-east-1 + initContainer: + env: + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_ACCESS_KEY_ID + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_SECRET_ACCESS_KEY + - name: AWS_REGION + value: us-west-2 +``` + +You can combine S3 skills with OCI and Git skills in the same agent by specifying `refs`, `gitRefs`, and `s3Refs` together. For the full field reference, see [S3SkillRef](/docs/kagent/resources/api-ref/#s3skillref). + ### Best practices for skills Containerize and store your skills in a specialized registry so that you can reuse them across agents. You can use the [agentregistry project](https://github.com/agentregistry-dev/agentregistry) to build and push skills to a registry. @@ -230,17 +259,18 @@ 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 | | HITL support | Yes | Yes | +| File upload in chat | Yes | No | Select the runtime via the `runtime` field in the declarative agent spec. @@ -248,17 +278,56 @@ 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." ``` -**Choose Go when** fast startup matters (autoscaling, cold starts), lower resource consumption is important, or you don't need Python-specific framework integrations. +**Choose Go when** fast startup matters (autoscaling, cold starts), lower resource consumption is important, or you do not need Python-specific framework integrations. **Choose Python when** you need Google ADK-native features, CrewAI/LangGraph/OpenAI framework integrations, or Python-based custom tools. For more benchmarks and details, see the [Go vs Python runtime blog post](https://kagent.dev/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. @@ -292,15 +361,37 @@ 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. -Here's how you could reference an existing agent (`promql-agent`) as a tool: +The following example shows how to reference an existing agent (`promql-agent`) as a tool: ```yaml ... @@ -326,6 +417,22 @@ Here's how you could reference an existing agent (`promql-agent`) as a tool: namespace: other-namespace ``` +### Per-call session isolation + +By default, all calls to the same sub-agent share a single session, which preserves stateful continuity across calls. When a coordinator agent calls the same sub-agent in parallel, shared sessions can cause calls to interfere with each other. + +Set `isolateSessions: true` on the Agent-type tool to give each call its own fresh session, enabling safe parallel fan-out. + +```yaml +spec: + declarative: + tools: + - type: Agent + agent: + name: worker-agent + isolateSessions: true +``` + ### MCP server endpoint A2A-enabled agents are automatically exposed as an MCP server on the kagent controller. The MCP endpoint is available at `/mcp` on the same port as the A2A endpoint (default 8083). diff --git a/docs-site/content/kagent/introduction/installation.md b/docs-site/content/kagent/introduction/installation.md index 2e9b7609..88c2bd33 100644 --- a/docs-site/content/kagent/introduction/installation.md +++ b/docs-site/content/kagent/introduction/installation.md @@ -5,7 +5,7 @@ weight: 1 author: kagent.dev --- -This guide covers ways to install and configure kagent in your Kubernetes environment. For a quick setup, check out our [Quick Start Guide](/docs/kagent/getting-started/quickstart). For enterpise offerings, check out [Solo Enterprise for kagent](/docs/kagent/introduction/what-is-kagent/#enterprise-distributions). +This guide covers ways to install and configure kagent in your Kubernetes environment. For a quick setup, see the [Quick Start Guide](/docs/kagent/getting-started/quickstart). For enterprise offerings, see [Solo Enterprise for kagent](/docs/kagent/introduction/what-is-kagent/#enterprise-distributions). ## Installation Methods @@ -43,7 +43,7 @@ Install kagent by using the kagent CLI or Helm. kagent installed successfully ``` -4. Optionally: Open the kagent dashboard. +4. Optional: Open the kagent dashboard. ```bash kagent dashboard ``` @@ -85,7 +85,7 @@ Another way to install kagent is using Helm. --set providers.openAI.apiKey=$OPENAI_API_KEY ``` -5. Optionally: Port-forward the kagent UI on port 8080. +5. Optional: Port-forward the kagent UI on port 8080. ```bash kubectl port-forward -n kagent svc/kagent-ui 8080:8080 ``` @@ -108,7 +108,7 @@ Another way to install kagent is using Helm. --set providers.anthropic.apiKey=$ANTHROPIC_API_KEY ``` -5. Optionally: Port-forward the kagent UI on port 8080. +5. Optional: Port-forward the kagent UI on port 8080. ```bash kubectl port-forward -n kagent svc/kagent-ui 8080:8080 ``` @@ -131,7 +131,7 @@ Another way to install kagent is using Helm. --set providers.gemini.apiKey=$GEMINI_API_KEY ``` -5. Optionally: Port-forward the kagent UI on port 8080. +5. Optional: Port-forward the kagent UI on port 8080. ```bash kubectl port-forward -n kagent svc/kagent-ui 8080:8080 ``` @@ -154,7 +154,7 @@ Another way to install kagent is using Helm. --set providers.azureOpenAI.apiKey=$OPENAI_API_KEY ``` -5. Optionally: Port-forward the kagent UI on port 8080. +5. Optional: Port-forward the kagent UI on port 8080. ```bash kubectl port-forward -n kagent svc/kagent-ui 8080:8080 ``` @@ -170,7 +170,7 @@ Another way to install kagent is using Helm. --set providers.default=ollama ``` -4. Optionally: Port-forward the kagent UI on port 8080. +4. Optional: Port-forward the kagent UI on port 8080. ```bash kubectl port-forward -n kagent svc/kagent-ui 8080:8080 ``` @@ -226,7 +226,7 @@ Review the following advanced configuration options that you might want to set u --set substrateWorkerPool.replicas=1 ``` - Pin the kagent chart to v0.9.9 or later — earlier versions do not include the `controller.substrate.*` and `substrateWorkerPool.*` values. + Pin the kagent chart to v0.9.9 or later. Earlier versions do not include the `controller.substrate.*` and `substrateWorkerPool.*` values. For an end-to-end walkthrough on a kind cluster, see the [Agent Substrate example](/docs/kagent/examples/agent-substrate). For more information about creating harness resources, see [Agent Harness](/docs/kagent/examples/agent-harness). @@ -301,6 +301,173 @@ 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. + +#### Affinity and topology spread constraints + +Use `affinity` and `topologySpreadConstraints` to control pod scheduling for the controller and UI Deployments. Both fields accept standard Kubernetes scheduling objects. + +```yaml +controller: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/component: controller + topologyKey: kubernetes.io/hostname + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + app.kubernetes.io/component: controller + +ui: + affinity: {} + topologySpreadConstraints: [] +``` + +When unset, no affinity or spread constraints are applied. + +#### 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/docs-site/content/kagent/observability/launch-ui.md b/docs-site/content/kagent/observability/launch-ui.md index 66308306..44c9ff25 100644 --- a/docs-site/content/kagent/observability/launch-ui.md +++ b/docs-site/content/kagent/observability/launch-ui.md @@ -47,6 +47,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/docs-site/content/kagent/operations/operational-considerations.md b/docs-site/content/kagent/operations/operational-considerations.md index 9e2cd8b5..6ba9fec0 100644 --- a/docs-site/content/kagent/operations/operational-considerations.md +++ b/docs-site/content/kagent/operations/operational-considerations.md @@ -52,6 +52,7 @@ controller: - **Database requirement**: PostgreSQL is the default database backend and supports multiple controller replicas. The bundled PostgreSQL instance is deployed automatically unless you configure an external PostgreSQL. - **Leader election**: Leader election uses Kubernetes leases and is handled automatically. - **Failover**: If the leader fails, another replica automatically becomes the leader. +- **Pod disruption budgets**: You can create a `PodDisruptionBudget` for the controller and UI Deployments via `controller.pdb.enabled: true` and `ui.pdb.enabled: true`. Both default to disabled because each component defaults to `replicas: 1`, and a `minAvailable: 1` budget on a single-replica Deployment blocks every voluntary eviction, which causes node drains and cluster upgrades to hang indefinitely. When enabled, the default budget uses `maxUnavailable: 1`, which is safe at any replica count. Raise `controller.replicas` and `ui.replicas` before switching to a `minAvailable`-based budget. For all available fields, see the [Helm reference](/docs/kagent/resources/helm/). ## Database configuration @@ -83,7 +84,7 @@ urlFile > url > bundled connection string | External DB, bundled pod kept running | `true` | set | yes | external | | Bundled disabled, no external set | `false` | unset | no | error (misconfigured) | -**Migration**: This means that you can keep the bundled pod running while the controller points at an external database, which is useful for migrating data. +**Migration**: You can keep the bundled pod running while the controller points at an external database, which is useful for migrating data. ### Bundled PostgreSQL @@ -164,6 +165,20 @@ controller: readOnly: true ``` +### Session cleanup + +kagent can automatically delete idle sessions and their cascaded data — including events, tasks, checkpoints, shares, push notifications, memory, and flow states — after a configurable number of days of inactivity. Idle time is measured from `session.updated_at`, which is updated on every write so that active sessions are never affected. + +To enable cleanup, set `database.postgres.sessionRetentionDays` in your Helm values: + +```yaml +database: + postgres: + sessionRetentionDays: 30 +``` + +A value of `0` (the default) disables cleanup. Existing installs are unaffected unless you set this value. + ## Secure execution environment kagent supports Kubernetes security contexts to run agents and tool servers with reduced privileges. Configure `securityContext` and `podSecurityContext` on your Agent or ToolServer resources to enforce secure execution. @@ -211,6 +226,43 @@ spec: {{< /tab >}} {{< /tabs >}} +## 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/docs-site/content/kagent/operations/upgrade.md b/docs-site/content/kagent/operations/upgrade.md index 30159929..747855f1 100644 --- a/docs-site/content/kagent/operations/upgrade.md +++ b/docs-site/content/kagent/operations/upgrade.md @@ -30,6 +30,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. @@ -83,6 +85,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. @@ -142,28 +182,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/" ``` @@ -171,26 +206,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/docs-site/content/kagent/resources/helm.md b/docs-site/content/kagent/resources/helm.md index e3198127..85eadd2f 100644 --- a/docs-site/content/kagent/resources/helm.md +++ b/docs-site/content/kagent/resources/helm.md @@ -13,16 +13,6 @@ A Helm chart for kagent, built with Google ADK | Repository | Name | Version | |------------|------|---------| | `${SUBSTRATE_REPO}` | substrate | `${SUBSTRATE_VERSION}` | -| file://../agents/argo-rollouts | argo-rollouts-agent | | -| file://../agents/cilium-debug | cilium-debug-agent | | -| file://../agents/cilium-manager | cilium-manager-agent | | -| file://../agents/cilium-policy | cilium-policy-agent | | -| file://../agents/helm | helm-agent | | -| file://../agents/istio | istio-agent | | -| file://../agents/k8s | k8s-agent | | -| file://../agents/kgateway | kgateway-agent | | -| file://../agents/observability | observability-agent | | -| file://../agents/promql | promql-agent | | | file://../tools/grafana-mcp | grafana-mcp | | | file://../tools/querydoc | querydoc | | | https://oauth2-proxy.github.io/manifests | oauth2-proxy | ~10.7.0 | @@ -34,48 +24,10 @@ A Helm chart for kagent, built with Google ADK | Key | Type | Default | Description | |-----|------|---------|-------------| | annotations | object | `{}` | Additional annotations to add to all Kubernetes deployment resources | -| argo-rollouts-agent.enabled | bool | `true` | | -| argo-rollouts-agent.memory.enabled | bool | `false` | | -| argo-rollouts-agent.memory.modelConfigRef | string | `""` | | -| argo-rollouts-agent.memory.ttlDays | int | `15` | | -| argo-rollouts-agent.modelConfigRef | string | `""` | | -| argo-rollouts-agent.resources.limits.memory | string | `"256Mi"` | | -| argo-rollouts-agent.resources.requests.cpu | string | `"50m"` | | -| argo-rollouts-agent.resources.requests.memory | string | `"128Mi"` | | -| cilium-debug-agent.enabled | bool | `true` | | -| cilium-debug-agent.memory.enabled | bool | `false` | | -| cilium-debug-agent.memory.modelConfigRef | string | `""` | | -| cilium-debug-agent.memory.ttlDays | int | `15` | | -| cilium-debug-agent.modelConfigRef | string | `""` | | -| cilium-debug-agent.resources.limits.memory | string | `"256Mi"` | | -| cilium-debug-agent.resources.requests.cpu | string | `"50m"` | | -| cilium-debug-agent.resources.requests.memory | string | `"128Mi"` | | -| cilium-manager-agent.enabled | bool | `true` | | -| cilium-manager-agent.memory.enabled | bool | `false` | | -| cilium-manager-agent.memory.modelConfigRef | string | `""` | | -| cilium-manager-agent.memory.ttlDays | int | `15` | | -| cilium-manager-agent.modelConfigRef | string | `""` | | -| cilium-manager-agent.resources.limits.memory | string | `"256Mi"` | | -| cilium-manager-agent.resources.requests.cpu | string | `"50m"` | | -| cilium-manager-agent.resources.requests.memory | string | `"128Mi"` | | -| cilium-policy-agent.enabled | bool | `true` | | -| cilium-policy-agent.memory.enabled | bool | `false` | | -| cilium-policy-agent.memory.modelConfigRef | string | `""` | | -| cilium-policy-agent.memory.ttlDays | int | `15` | | -| cilium-policy-agent.modelConfigRef | string | `""` | | -| cilium-policy-agent.resources.limits.memory | string | `"256Mi"` | | -| cilium-policy-agent.resources.requests.cpu | string | `"50m"` | | -| cilium-policy-agent.resources.requests.memory | string | `"128Mi"` | | | controller.a2aBaseUrl | string | `http://-controller..svc:` | The base URL of the A2A Server endpoint, as advertised to clients. | | controller.a2aClientTimeout | string | "" (no timeout) | HTTP client timeout for A2A requests from the controller to agent pods. 0 (the default) means no timeout, which is correct for SSE-based streaming agents that can run for an arbitrarily long time. The previous implicit default was 3m (inherited from the a2a-go SDK), which caused `context deadline exceeded` errors for agents that take longer than 3 minutes to complete. Set a positive Go duration string (e.g. "30m", "1h") only if you need a hard upper bound on individual A2A calls. | +| controller.a2aGatewayUrl | string | `http://-controller..svc:` | Public gRPC URL advertised by AgentInstance Agent Cards. | | controller.affinity | object | `{}` | [Affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) rules for the controller pod. | -| controller.agentDeployment | object | `{"host":"","nodeSelector":{},"podLabels":{},"serviceAccountName":""}` | Global deployment defaults applied to all agent pods. Per-agent settings in the Agent CRD take precedence over these defaults. | -| controller.agentDeployment.host | string | "" (controller falls back to "0.0.0.0"; "::" when ipv6.enabled) | Default host address for agent pods to bind to. Leave empty to use the controller's default fallback of "0.0.0.0". Automatically set to "::" when ipv6.enabled is true. Can be explicitly overridden here regardless of the ipv6 flag. | -| controller.agentDeployment.nodeSelector | object | {} (no default nodeSelector) | Default nodeSelector applied to all agent deployments. Useful when admission policies require a nodeSelector on every Deployment, since wizard-created Agents carry none. A per-agent nodeSelector in the Agent CRD takes precedence over these defaults. | -| controller.agentDeployment.podLabels | object | {} (no extra labels) | Default labels applied to all agent pod templates. Per-agent labels in the Agent CRD take precedence over these defaults. | -| controller.agentDeployment.serviceAccountName | string | "" (auto-create per-agent ServiceAccount) | Default ServiceAccount name for agent pods. When set, agent pods that don't specify an explicit serviceAccountName will use this ServiceAccount instead of creating a per-agent one. Useful for Workload Identity (GCP, AWS IRSA, Azure Workload Identity). Precedence: agent-level serviceAccountName > this default > auto-created SA. | -| controller.agentImage.pullPolicy | string | `""` | | -| controller.agentImage.pullSecret | string | `""` | Image pull secret name set on agent pods created by the controller | | controller.agentImage.registry | string | `""` | | | controller.agentImage.repository | string | `"kagent-dev/kagent/app"` | | | controller.agentImage.tag | string | `""` | | @@ -84,7 +36,8 @@ A Helm chart for kagent, built with Google ADK | controller.auth.userIdClaim | string | `""` | | | controller.env | list | `[]` | | | controller.envFrom | list | `[]` | | -| controller.goAgentImage | object | `{"pullPolicy":"","registry":"","repository":"kagent-dev/kagent/golang-adk","tag":""}` | The image used for the Go (ADK) runtime agent. | +| controller.goAgentImage | object | `{"registry":"","repository":"kagent-dev/kagent/golang-adk","tag":""}` | The image used for the Go (ADK) runtime agent. | +| controller.grpc | object | `{"bindAddress":":8084","maxMessageBytes":16777216,"reflection":false,"tlsCertFile":"","tlsKeyFile":""}` | Native gRPC application API settings. This port is internal unless a separate TLS-capable GRPCRoute or ingress is configured. | | controller.image.pullPolicy | string | `""` | | | controller.image.registry | string | `""` | | | controller.image.repository | string | `"kagent-dev/kagent/controller"` | | @@ -109,21 +62,18 @@ A Helm chart for kagent, built with Google ADK | controller.resources.requests.cpu | string | `"100m"` | | | controller.resources.requests.memory | string | `"128Mi"` | | | controller.service.annotations | object | `{}` | | +| controller.service.ports.grpc | int | `8084` | | | controller.service.ports.port | int | `8083` | | | controller.service.ports.targetPort | int | `8083` | | | controller.service.type | string | `"ClusterIP"` | | | controller.serviceAccount | object | `{"annotations":{}}` | ServiceAccount settings for the controller pod | | controller.serviceAccount.annotations | object | {} (no extra annotations) | Annotations to add to the controller ServiceAccount. Useful for GCP Workload Identity, AWS IRSA, or Azure Workload Identity. | -| controller.skillsInitImage | object | `{"pullPolicy":"","registry":"","repository":"kagent-dev/kagent/skills-init","tag":""}` | The image used by the skills-init container to clone skills from Git and pull OCI skill images. | +| controller.skillsInitImage | object | `{"registry":"","repository":"kagent-dev/kagent/skills-init","tag":""}` | The image used by the skills-init container to clone skills from Git and pull OCI skill images. | | controller.startupProbe | object | httpGet /health on port http, periodSeconds=15, initialDelaySeconds=15 | Custom startup probe for the controller container. Setting a value replaces the default probe entirely — include a handler (httpGet / exec / tcpSocket / grpc) when overriding. | | controller.streaming | string | `nil` | @deprecated Removed in 0.10.0. The A2A SDK now handles SSE buffering and timeouts internally. These values have no effect and will be removed in a future release. | | controller.substrate.ateApiEndpoint | string | `""` | | -| controller.substrate.ateApiInsecure | bool | `false` | | | controller.substrate.ateApiServer.namespace | string | `"ate-system"` | | | controller.substrate.ateApiServer.serviceAccount | string | `"ate-api-server"` | | -| controller.substrate.ateApiTokenAudience | string | `"api.ate-system.svc"` | | -| controller.substrate.ateApiTokenExpirationSeconds | int | `3600` | | -| controller.substrate.ateApiTokenFile | string | `"/var/run/secrets/tokens/ate-api/token"` | | | controller.substrate.atenetRouterURL | string | `""` | | | controller.substrate.defaultWorkerPool.name | string | `""` | | | controller.substrate.defaultWorkerPool.namespace | string | `""` | | @@ -160,33 +110,9 @@ A Helm chart for kagent, built with Google ADK | grafana-mcp.resources.limits.memory | string | `"512Mi"` | | | grafana-mcp.resources.requests.cpu | string | `"100m"` | | | grafana-mcp.resources.requests.memory | string | `"128Mi"` | | -| helm-agent.enabled | bool | `true` | | -| helm-agent.memory.enabled | bool | `false` | | -| helm-agent.memory.modelConfigRef | string | `""` | | -| helm-agent.memory.ttlDays | int | `15` | | -| helm-agent.modelConfigRef | string | `""` | | -| helm-agent.resources.limits.memory | string | `"256Mi"` | | -| helm-agent.resources.requests.cpu | string | `"50m"` | | -| helm-agent.resources.requests.memory | string | `"128Mi"` | | | imagePullPolicy | string | `"IfNotPresent"` | | | imagePullSecrets | list | `[]` | | | ipv6 | object | false | Enable IPv6/dual-stack support. When true, configures all components for dual-stack (IPv4+IPv6) networking: - nginx listens on both IPv4 and IPv6 (adds `listen [::]:8080`) - Next.js binds to `::` instead of `0.0.0.0` - Agent pods bind to `::` for dual-stack reachability Leave disabled on clusters where IPv6 is disabled at the kernel level. | -| istio-agent.enabled | bool | `true` | | -| istio-agent.memory.enabled | bool | `false` | | -| istio-agent.memory.modelConfigRef | string | `""` | | -| istio-agent.memory.ttlDays | int | `15` | | -| istio-agent.modelConfigRef | string | `""` | | -| istio-agent.resources.limits.memory | string | `"256Mi"` | | -| istio-agent.resources.requests.cpu | string | `"50m"` | | -| istio-agent.resources.requests.memory | string | `"128Mi"` | | -| k8s-agent.enabled | bool | `true` | | -| k8s-agent.memory.enabled | bool | `false` | | -| k8s-agent.memory.modelConfigRef | string | `""` | | -| k8s-agent.memory.ttlDays | int | `15` | | -| k8s-agent.modelConfigRef | string | `""` | | -| k8s-agent.resources.limits.memory | string | `"256Mi"` | | -| k8s-agent.resources.requests.cpu | string | `"50m"` | | -| k8s-agent.resources.requests.memory | string | `"128Mi"` | | | kagent-tools.enabled | bool | `true` | | | kagent-tools.nameOverride | string | `"tools"` | | | kagent-tools.nodeSelector | object | `{}` | Node labels to match for `Pod` [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). | @@ -202,14 +128,6 @@ A Helm chart for kagent, built with Google ADK | kagent-tools.tolerations | list | `[]` | Node taints which will be tolerated for `Pod` [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). | | kagent-tools.tools.loglevel | string | `"debug"` | | | kagent-tools.tools.metrics.port | int | `8085` | | -| kgateway-agent.enabled | bool | `true` | | -| kgateway-agent.memory.enabled | bool | `false` | | -| kgateway-agent.memory.modelConfigRef | string | `""` | | -| kgateway-agent.memory.ttlDays | int | `15` | | -| kgateway-agent.modelConfigRef | string | `""` | | -| kgateway-agent.resources.limits.memory | string | `"256Mi"` | | -| kgateway-agent.resources.requests.cpu | string | `"50m"` | | -| kgateway-agent.resources.requests.memory | string | `"128Mi"` | | | kmcp.enabled | bool | `true` | | | kmcp.fullnameOverride | string | `""` | | | kmcp.nameOverride | string | `"kmcp"` | | @@ -252,14 +170,6 @@ A Helm chart for kagent, built with Google ADK | oauth2-proxy.service.portNumber | int | `4180` | | | oauth2-proxy.service.type | string | `"ClusterIP"` | | | oauth2-proxy.sessionStorage.type | string | `"cookie"` | | -| observability-agent.enabled | bool | `true` | | -| observability-agent.memory.enabled | bool | `false` | | -| observability-agent.memory.modelConfigRef | string | `""` | | -| observability-agent.memory.ttlDays | int | `15` | | -| observability-agent.modelConfigRef | string | `""` | | -| observability-agent.resources.limits.memory | string | `"256Mi"` | | -| observability-agent.resources.requests.cpu | string | `"50m"` | | -| observability-agent.resources.requests.memory | string | `"128Mi"` | | | otel.logging.enabled | bool | `false` | | | otel.logging.exporter.otlp.endpoint | string | `""` | | | otel.logging.exporter.otlp.insecure | bool | `true` | | @@ -272,14 +182,6 @@ A Helm chart for kagent, built with Google ADK | podAnnotations | object | `{}` | | | podLabels | object | `{}` | Additional labels to add to all pod templates (merged into pod labels of the controller and UI Deployments; can be overridden per component). Useful for admission policies that require specific labels on pods. | | podSecurityContext | object | `{"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}}` | Security context for all pods | -| promql-agent.enabled | bool | `true` | | -| promql-agent.memory.enabled | bool | `false` | | -| promql-agent.memory.modelConfigRef | string | `""` | | -| promql-agent.memory.ttlDays | int | `15` | | -| promql-agent.modelConfigRef | string | `""` | | -| promql-agent.resources.limits.memory | string | `"256Mi"` | | -| promql-agent.resources.requests.cpu | string | `"50m"` | | -| promql-agent.resources.requests.memory | string | `"128Mi"` | | | providers.annotations | object | `{}` | Annotations added to the metadata of the generated default ModelConfig (the one derived from `providers.default`). Omitted from the resource when empty. | | providers.anthropic.apiKeySecretKey | string | `"ANTHROPIC_API_KEY"` | | | providers.anthropic.apiKeySecretRef | string | `"kagent-anthropic"` | | @@ -296,7 +198,7 @@ A Helm chart for kagent, built with Google ADK | providers.default | string | `"openAI"` | | | providers.gemini.apiKeySecretKey | string | `"GOOGLE_API_KEY"` | | | providers.gemini.apiKeySecretRef | string | `"kagent-gemini"` | | -| providers.gemini.model | string | `"gemini-2.0-flash-lite"` | | +| providers.gemini.model | string | `"gemini-2.5-flash-lite"` | | | providers.gemini.provider | string | `"Gemini"` | | | providers.ollama.config.host | string | `"host.docker.internal:11434"` | | | providers.ollama.config.options.num_ctx | string | `"64000"` | | @@ -329,6 +231,7 @@ A Helm chart for kagent, built with Google ADK | ui.affinity | object | `{}` | [Affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) rules for the UI pod. | | ui.annotations | object | `{}` | Additional annotations to add to the UI Deployment metadata | | ui.auth.ssoRedirectPath | string | `"/oauth2/start"` | | +| ui.backendGrpcUrl | string | `""` | | | ui.backendInternalUrl | string | `""` | | | ui.env | object | `{}` | | | ui.externalUrl | string | "" (share tools return paths only) | Public-facing base URL of the UI (e.g. https://kagent.example.com). When set, the controller injects KAGENT_UI_URL into agent pods so that share link tools return full clickable URLs instead of relative paths. | diff --git a/docs-site/content/kagent/resources/release-notes.md b/docs-site/content/kagent/resources/release-notes.md index 2ec77f66..6c7d243c 100644 --- a/docs-site/content/kagent/resources/release-notes.md +++ b/docs-site/content/kagent/resources/release-notes.md @@ -9,6 +9,734 @@ 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. +* [Azure AI Foundry](#azure-ai-foundry): New provider for Azure AI Foundry models with Go ADK runtime support and Azure Workload Identity authentication. +* [OpenAI Responses API](#openai-responses-api): New `openAI.apiFormat: responses` field switches the harness to use the OpenAI Responses API instead of Chat Completions. +* [Per-call session isolation for Agent tools](#per-call-session-isolation-for-agent-tools): New `isolateSessions` flag gives each call to a sub-agent its own fresh session, enabling safe parallel fan-out. +* [File upload in agent chat](#file-upload-in-agent-chat): Attach files and images to chat messages for Go declarative agents. + +**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`. +* [Affinity and topologySpreadConstraints](#affinity-and-topologyspreadconstraints): New `controller.affinity`, `controller.topologySpreadConstraints`, `ui.affinity`, and `ui.topologySpreadConstraints` Helm values for advanced pod scheduling. +* [PodDisruptionBudget](#poddisruptionbudget): Opt-in PDB for the controller and UI Deployments. +* [Configurable tool refresh interval](#configurable-tool-refresh-interval): Control how often the controller polls tool servers for updated tool lists. +* [S3 skills](#s3-skills): Load agent skills directly from S3 buckets or archives. + +**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. +* [Database session cleanup](#database-session-cleanup): Automatically purge idle sessions and cascaded data after a configurable retention period. + +[**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). + +### Azure AI Foundry + +[Azure AI Foundry](https://ai.azure.com/) is now a supported `ModelConfig` provider. The Foundry provider uses the Azure AI Inference SDK and supports both API key authentication and Azure Workload Identity (`DefaultAzureCredential`) when no key is configured. Only the Go declarative runtime is supported; the controller rejects other runtimes. + +```yaml +apiVersion: kagent.dev/v1alpha2 +kind: ModelConfig +metadata: + name: foundry-model-config + namespace: kagent +spec: + provider: Foundry + model: gpt-5.4-mini + foundry: + endpoint: https://my-hub.services.ai.azure.com/models + deployment: my-deployment + apiVersion: "2025-01-01-preview" +``` + +To authenticate with an API key, create a Kubernetes Secret with the key stored as `FOUNDRY_API_KEY` and reference it via `spec.apiKeySecret`. To use Azure Workload Identity instead, omit `apiKeySecret` and annotate the agent's ServiceAccount with the appropriate IAM role. + +| Field | Description | +|---|---| +| `foundry.endpoint` | The Azure AI Foundry endpoint URL. | +| `foundry.endpointFrom` | Reference to a ConfigMap key containing the endpoint URL. Use with Azure Service Operator to inject the endpoint without hardcoding it. | +| `foundry.deployment` | The deployment name within the Foundry project. | +| `foundry.apiVersion` | The Azure AI Inference API version (for example, `2025-01-01-preview`). | + +Memory embeddings are supported and use 768-dimensional vectors. Anthropic (Claude) models on Foundry are not yet supported. + +For more information, see [Azure AI Foundry](/docs/kagent/supported-providers/azure-ai-foundry). + +### OpenAI Responses API + +You can now switch the harness to use the [OpenAI Responses API](https://platform.openai.com/docs/api-reference/responses) instead of Chat Completions by setting `openAI.apiFormat: responses` on a `ModelConfig`. This is also compatible with gateways such as AgentGateway that expose the Responses API. + +```yaml +spec: + provider: OpenAI + model: gpt-5.4-mini + openAI: + apiFormat: responses +``` + +Omit `apiFormat` (or set it to `chatCompletions`) to continue using Chat Completions, which remains the default. Native tool use and stateful Responses API chaining are not yet supported. + +For more information, see [OpenAI — Responses API](/docs/kagent/supported-providers/openai#responses-api). + +### Per-call session isolation for Agent tools + +When a coordinator agent calls the same sub-agent in parallel, all calls previously shared a single session, causing them to interfere with each other. Setting `isolateSessions: true` on an Agent-type tool gives each call its own fresh `context_id`, enabling safe parallel fan-out. + +```yaml +spec: + declarative: + tools: + - type: Agent + agent: + name: worker-agent + isolateSessions: true +``` + +The default (`isolateSessions: false`) preserves the existing behavior where calls to the same sub-agent share a session for stateful continuity. + +For more information, see [Agents — Per-call session isolation](/docs/kagent/concepts/agents#per-call-session-isolation). + +### Affinity and topologySpreadConstraints + +New Helm values let you configure pod affinity rules and topology spread constraints for the controller and UI Deployments. + +```yaml +controller: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/component: controller + topologyKey: kubernetes.io/hostname + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + app.kubernetes.io/component: controller + +ui: + affinity: {} + topologySpreadConstraints: [] +``` + +Both fields accept standard Kubernetes scheduling objects. When unset, no affinity or spread constraints are applied and existing behavior is unchanged. + +For more information, see [Installing kagent — Affinity and topology spread constraints](/docs/kagent/introduction/installation#affinity-and-topology-spread-constraints). + +### S3 skills + +You can now load agent skills directly from S3 — either a folder prefix (containing a `SKILL.md` and siblings) or a single `.zip` archive. Credentials use the AWS SDK default credential chain, supplied via environment variables on the skills init container. + +```yaml +apiVersion: kagent.dev/v1alpha2 +kind: Agent +metadata: + name: s3-skills-agent + namespace: kagent +spec: + skills: + s3Refs: + - uri: s3://kagent-skills-bucket/team-a/kebab-maker # S3 folder prefix + name: kebab-maker + - uri: s3://kagent-skills-bucket/bundles/ops.zip # Zipped archive + region: us-east-1 + initContainer: + env: + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_ACCESS_KEY_ID + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_SECRET_ACCESS_KEY + - name: AWS_REGION + value: us-west-2 + type: Declarative + declarative: + systemMessage: You are a helpful assistant with skills. + modelConfig: default-model-config + tools: [] +``` + +For the full field reference, see [S3SkillRef](/docs/kagent/resources/api-ref/#s3skillref) in the API reference. + +### File upload in agent chat + +The kagent UI now supports attaching files and images to chat messages for agents that use the Go declarative runtime. You can attach files using the paperclip button, by dragging and dropping onto the chat window, or by selecting from previously uploaded files. + +Files are forwarded to the model using the provider's native document support. The following table summarizes what each provider accepts: + +| Provider | Images | Documents | +|---|---|---| +| OpenAI (Chat Completions / Azure / Foundry) | `image/*` | PDF only; text extracted from plain text files | +| OpenAI (Responses) | `image/*` | PDF, text, markdown, CSV, HTML, JSON, Word, PowerPoint, and more | +| Anthropic | `image/*` | PDF, `text/plain`, `text/markdown` | +| Bedrock | `image/png`, `image/jpeg`, `image/gif`, `image/webp` | PDF, TXT, MD, CSV, HTML, DOC/DOCX, XLS/XLSX | +| Ollama | `image/*` | — | + +File upload is available only for Go declarative agents. Python ADK agents do not yet support file attachments. + +### Database session cleanup + +kagent can now automatically delete idle sessions and their cascaded data — including events, tasks, checkpoints, shares, push notifications, memory, and flow states — after a configurable number of days of inactivity. Idle time is measured from the session's last write (`session.updated_at`), so active sessions are not affected. + +To enable cleanup, set `database.postgres.sessionRetentionDays` in your Helm values: + +```yaml +database: + postgres: + sessionRetentionDays: 30 +``` + +A value of `0` (the default) disables cleanup. Existing installs are unaffected unless you set this value. + +### Configurable tool refresh interval + +The `RemoteMCPServer`, `MCPServer`, and `Service` controllers periodically re-poll each tool server to discover and record updated tool lists. This interval was previously fixed at 60 seconds. You can now configure it with the `controller.toolRefreshInterval` Helm value: + +```yaml +controller: + toolRefreshInterval: "15m" +``` + +The value accepts Go duration strings (for example `30s`, `5m`, `1h`). Increasing the interval reduces API server load in large clusters; decreasing it makes newly registered tools available faster. + +### PodDisruptionBudget + +You can now create a `PodDisruptionBudget` for the kagent controller and UI Deployments. PDBs are disabled by default because both components default to `replicas: 1`, and a `minAvailable: 1` budget on a single-replica Deployment blocks every voluntary eviction, which causes node drains and cluster upgrades to hang indefinitely. + +To enable a PDB, set `controller.pdb.enabled: true` and `ui.pdb.enabled: true`. The default budget uses `maxUnavailable: 1`, which is safe at any replica count: + +```yaml +controller: + pdb: + enabled: true + maxUnavailable: 1 # default; safe at replicas >= 1 + +ui: + pdb: + enabled: true + maxUnavailable: 1 +``` + +To use `minAvailable` instead, set `maxUnavailable: null` and specify `minAvailable`. Note that `minAvailable` and `maxUnavailable` are mutually exclusive — the Helm chart fails at template time if both are set. + +For all available fields, see the [Helm reference](/docs/kagent/resources/helm/). + +### Additional changes in v0.10 + +**Security** + +* **CVE patches**: Critical and high CVEs patched in the Go ADK and app container images. +* **Python dependency CVE patches**: `aiohttp` bumped to 3.14.3 (CVE-2026-69244) and `cryptography` bumped to 50.0.0 (CVE-2026-69247) in the Python ADK container images. +* **sqlparse CVE patches**: `sqlparse` bumped from 0.5.5 to 0.6.0 to address CVE-2026-54284, CVE-2026-59893, and CVE-2026-71491. +* **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. +* **pgx connection pool tuning**: New Helm values configure the idle connection timeout and check period for the PostgreSQL pgx driver, so that idle database connections are closed after a configurable period rather than held indefinitely. + +**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. +* **Session sharing nil pointer fix**: Fixed a nil pointer panic on session sharing endpoints caused by `SessionSharesHandler` not being initialized at startup. +* **OTel traces no longer sent to api.openai.com**: The Python ADK no longer forwards traces to OpenAI's hardcoded endpoint by default, preventing key leakage for proxy or gateway deployments. Set `KAGENT_OPENAI_AGENTS_NATIVE_TRACING=true` to restore the original behavior. + ## v0.9 Review this summary of significant changes from kagent version 0.8 to v0.9. diff --git a/docs-site/content/kagent/supported-providers/amazon-bedrock.md b/docs-site/content/kagent/supported-providers/amazon-bedrock.md index 72f329de..c73c8c42 100644 --- a/docs-site/content/kagent/supported-providers/amazon-bedrock.md +++ b/docs-site/content/kagent/supported-providers/amazon-bedrock.md @@ -99,6 +99,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/docs-site/content/kagent/supported-providers/gemini.md b/docs-site/content/kagent/supported-providers/gemini.md index 7f0e93a3..7198950b 100644 --- a/docs-site/content/kagent/supported-providers/gemini.md +++ b/docs-site/content/kagent/supported-providers/gemini.md @@ -21,9 +21,7 @@ Make sure that your Google Cloud account has a project with the Gemini API enabl kubectl create secret generic kagent-gemini -n kagent --from-literal GOOGLE_API_KEY= ``` -3. Create a ModelConfig resource using the `Gemini` provider. - -You can find out the latest model names and capabilities on the [Gemini API docs](https://ai.google.dev/gemini-api/docs/models). Once you have chosen a model, replace the `model` field with the name such as `gemini-2.5-pro`. +3. Create a `ModelConfig` resource using the `Gemini` provider. You can find the latest model names and capabilities on the [Gemini API docs](https://ai.google.dev/gemini-api/docs/models). Replace the `model` field with your chosen model name, such as `gemini-2.5-pro`. ```yaml apiVersion: kagent.dev/v1alpha2 @@ -42,3 +40,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/docs-site/content/kagent/supported-providers/openai.md b/docs-site/content/kagent/supported-providers/openai.md index d695db4f..73ee021e 100644 --- a/docs-site/content/kagent/supported-providers/openai.md +++ b/docs-site/content/kagent/supported-providers/openai.md @@ -14,7 +14,7 @@ export OPENAI_API_KEY= kubectl create secret generic kagent-openai -n kagent --from-literal OPENAI_API_KEY=$OPENAI_API_KEY ``` -2. Create a ModelConfig resource that references the secret and key name: +2. Create a `ModelConfig` resource that references the secret and key name. For standard models such as GPT-4 and GPT-3.5, kagent automatically configures the appropriate model capabilities. ```yaml apiVersion: kagent.dev/v1alpha2 @@ -30,8 +30,51 @@ spec: openAI: {} ``` -For OpenAI's standard models like GPT-4 and GPT-3.5, kagent automatically configures the appropriate model capabilities. - -3. Apply the above resource to the cluster. +3. Apply the 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. + +## Responses API + +By default, kagent uses the [Chat Completions API](https://platform.openai.com/docs/api-reference/chat). To switch to the [OpenAI Responses API](https://platform.openai.com/docs/api-reference/responses) instead, set `openAI.apiFormat: responses` on the `ModelConfig`. This is also compatible with gateways such as AgentGateway that expose the Responses API. + +```yaml +spec: + provider: OpenAI + model: gpt-4o + openAI: + apiFormat: responses +``` + +Omit `apiFormat` (or set it to `chatCompletions`) to continue using Chat Completions. Native tool use and stateful Responses API chaining are not yet supported.