diff --git a/docs-site/content/kagent/1.x/agents/agent-harness.md b/docs-site/content/kagent/1.x/agents/agent-harness.md index d86a5ccf..7a52fff1 100644 --- a/docs-site/content/kagent/1.x/agents/agent-harness.md +++ b/docs-site/content/kagent/1.x/agents/agent-harness.md @@ -63,6 +63,8 @@ A Harness names exactly one of the following four runtimes, and that choice deci The `kagent` and `byo` runtimes compile through the same path, so they accept the same model providers and the same AgentTemplate features, except [structured output]({{< link path="agents/structured-output" >}}), which only the `kagent` runtime supports. The `codex` and `claude` runtimes are purpose-built adapters, and each accepts a narrower slice. +The agent chat in the kagent UI allows file attachments only on the `kagent` runtime, so an agent on a `byo`, `codex`, or `claude` Harness has no attachment option in the chat. For the file types and size limits that the UI enforces, see [Attach files to a message]({{< link path="observability/launch-ui#attach-files-to-a-message" >}}). + ### Runtime-specific settings `spec.kagent` is the only runtime block that takes settings of its own. The rest are empty. diff --git a/docs-site/content/kagent/1.x/observability/launch-ui.md b/docs-site/content/kagent/1.x/observability/launch-ui.md index 9d2cf2f3..412b3b7c 100644 --- a/docs-site/content/kagent/1.x/observability/launch-ui.md +++ b/docs-site/content/kagent/1.x/observability/launch-ui.md @@ -110,6 +110,32 @@ A checkpoint appears in the transcript as a mark carrying the snapshot name and > [!NOTE] > A checkpoint is always taken at the latest turn boundary, so the UI offers **Fork** on your own most recent message and not on earlier ones. +## Attach files to a message + +In the chat interface for agents on the `kagent` runtime, you can attach files to send with a message. An agent reads any files that you attach, so you can ask the agent about a log, a manifest, or a screenshot without pasting the contents into the message box. + +Stage files in any of the following ways. + +- Select the paperclip beside the message box, then choose the files. +- Drop files anywhere on the chat page. +- Paste a file or an image from your clipboard. A clipboard that also holds plain text pastes the text instead, so that a copy from a word processor keeps its text rather than its image rendering. + +Sent files stay in the transcript as download chips, and reloading the page redraws them. Every non-image file reaches the model as text, regardless of the provider that the agent uses. An empty file, or one that holds only whitespace, reaches the model as the note `[Uploaded file "notes.txt" (text/plain) contained no extractable text.]` instead of contents, so the agent reports the gap rather than answering from nothing. Images reach the providers that accept them. Amazon Bedrock, Ollama, and SAP AI Core receive a note in place of the image. + +The following limits apply to attachments: + +| Limit | Value | Enforced by | +| ----- | ----- | ----------- | +| Accepted file types | Plain text, Markdown, CSV, JSON, XML, YAML, and HTML files, and PNG, JPEG, GIF, and WebP images | The UI, as you stage each file. A rejected file is reported by name. | +| Total size of the files in one message | 10 MB | The UI, as you stage each file. | +| Text read from one file | 200,000 characters | The runtime, which appends `[truncated]` to a longer file. | +| gRPC message that the kagent API accepts | 16 MiB | The controller's gRPC server, and every kagent gRPC client. The limit is a compiled-in constant that no Helm value changes. | +| Request body that the UI's nginx accepts | `ui.nginx.clientMaxBodySize`, default `20m` | The UI pod's nginx. The default sits just above the 16 MiB gRPC message limit. | + +The UI falls back to the file extension when the browser reports no media type, or the wrong one, for a file. For example, browsers report no media type for `.md` files. + +If you host a reverse proxy in front of the UI, the proxy applies its own body-size limit, and a default nginx allows only `1m`. Raise the limit as shown in [Serve the UI under a sub-path]({{< link path="setup/reverse-proxy#proxy-shapes" >}}). + ## Check Agent Substrate capacity The **Substrate** page shows whether there is capacity for an agent to run. It reads WorkerPools and ActorTemplates from Kubernetes, and live Actors and Worker assignments from the Agent Substrate API. diff --git a/docs-site/content/kagent/1.x/observability/metrics.md b/docs-site/content/kagent/1.x/observability/metrics.md index 7f8733ee..083cd61b 100644 --- a/docs-site/content/kagent/1.x/observability/metrics.md +++ b/docs-site/content/kagent/1.x/observability/metrics.md @@ -40,6 +40,8 @@ Besides the standard Go runtime and process metrics, the controller reports the | `workqueue_depth`, `workqueue_queue_duration_seconds`, `workqueue_retries_total` | Gauge, histogram, counter | Work waiting for a reconciler, how long it waits, and how often it is retried. | | `leader_election_master_status` | Gauge | `1` on the controller replica that holds the leader lease. With several replicas, exactly one reports `1`. | | `rest_client_requests_total` | Counter | Requests from the controller to the Kubernetes API server, by status code. | +| `kagent_runtime_revision_gc_pending` | Gauge | Runtime revisions that the last successful discovery found eligible for cleanup. The controller reports a cached count, so a scrape costs no database or network call. The metric is absent until a discovery succeeds, and `0` reports a discovery that matched nothing. A failed discovery holds the previous value rather than clearing it. | +| `kagent_runtime_revision_gc_duration_seconds` | Histogram | Time that one revision cleanup attempt takes, by the `kagent_gc_stage` label: `discovery` or `collection`. A `collection` attempt covers the database claim, the Agent Substrate read and deletion, and the database finalization. A failed attempt carries an `error_type` label holding a gRPC status code name, or `_OTHER` for every other failure, so the series that carry the label give both the failure rate and the reason. | The Agent Substrate `atecontroller` component reports the same `controller_runtime_*` and `workqueue_*` metrics for its own reconcilers. To keep the two apart in a query, filter by the scrape job, such as `job="kagent-controller-metrics"` in the OTel stack. diff --git a/docs-site/content/kagent/1.x/setup/reverse-proxy.md b/docs-site/content/kagent/1.x/setup/reverse-proxy.md index fed3756f..31118677 100644 --- a/docs-site/content/kagent/1.x/setup/reverse-proxy.md +++ b/docs-site/content/kagent/1.x/setup/reverse-proxy.md @@ -34,6 +34,8 @@ helm upgrade --install kagent \ Both of the following proxy configurations work. Choose the one that matches your infrastructure. If you enable oauth2-proxy for SSO, the proxy must strip the prefix: with the prefix forwarded, oauth2-proxy cannot match its own sign-in and skip-authentication paths, and sign-in fails. +Both examples set `client_max_body_size`. A default nginx allows `1m`, so a larger attachment is rejected with a `413` before it reaches the UI pod. Keep the limit above the 10 MB that one chat message can carry. For the attachment limits, see [Attach files to a message]({{< link path="observability/launch-ui#attach-files-to-a-message" >}}). + ### Proxy strips the prefix The proxy removes the `/ui` prefix before forwarding to the UI service on port `8080`. The UI then sees requests at `/` and serves them normally. @@ -44,6 +46,7 @@ Example nginx configuration: location /ui/ { proxy_pass http://{{< reuse "kagent-docs/snippets/name-ui.md" >}}.kagent:8080/; proxy_http_version 1.1; + client_max_body_size 20m; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -62,6 +65,7 @@ Example nginx configuration: location /ui/ { proxy_pass http://{{< reuse "kagent-docs/snippets/name-ui.md" >}}.kagent:8080; proxy_http_version 1.1; + client_max_body_size 20m; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;