AI Agents

  • Added

    • The three upstream lines at their decoupled releases: kagent 1.0.0, Substrate 1.0.0, agentgateway 2.0.0 under its nested names (giantswarm/agent-platform#608; epic giantswarm/giantswarm#37705). The lines release stable semver of their own, decoupled from the upstream versions their FORK.mds record, and publish nothing more under the former vX.Y.Z-gs.N scheme. components.kagent*.versionRange and components.substrate*.versionRange are >=1.0.0 <1.1.0; both charts name the agentgateway line’s 2.0.0 in full — agentgateway.controller.image giantswarm/agentgateway-upstream/controller:2.0.0, agentgateway.proxy.image giantswarm/agentgateway-upstream/agentgateway:2.0.0, substrate.images.agentgateway the same data plane for Substrate’s egress gateway — so the packaging chart’s defaults cannot move the images (a value wins over a chart default, and a default that moved alone to the nested names rendered a tag that existed only there); components.agentgateway.versionRange is >=2.2.2 <3.0.0, the packaging release that renders a bare tag as written. The range shape follows the scheme — a patch of a line never changes a runtime contract, a re-pin onto another upstream release is at least a minor — so agent-platform.substrate.validateRange admits an exact version or >=X.Y.Z <X.(Y+1).0 and refuses a -0 bound (Flux’s Masterminds semver skips prereleases while no bound of a range carries one and evaluates them all once one does, so <1.1.0-0 would have put every installation on the line’s newest dev build) and the former >=X.Y.Z-gs.N <X.Y.(Z+1)-0, agent-platform.substrate.workerPoolSpreadFloor is 1.0.0, examples/customer-bom.yaml pins 1.0.0 and 2.2.2, and the verify scripts’ fixtures move to the stable shapes. UPGRADE.md names the operator’s part.\n\n- The kagent line’s and the Substrate line’s charts come from gsoci; the lines move to v0.11.0-gs.22 and v0.0.30-gs.5 (giantswarm/agent-platform#580; epic giantswarm/giantswarm#37853). The two lines publish natively to the org’s registry from CircleCI — the multi-arch images and the charts, signed with the Giant Swarm identity, releases and dev builds alike — so components.kagent.repository and components.kagent-crds.repository are oci://gsoci.azurecr.io/giantswarm/kagent/helm, components.substrate.repository and components.substrate-crds.repository are oci://gsoci.azurecr.io/giantswarm/substrate/helm. The Substrate floor moves to 0.0.30-gs.5 — the line’s first release published there, the patches of gs.4 — in components.substrate*.versionRange (>=0.0.30-gs.5 <0.0.31-0), the BOM pin and, derived from it, the kagent WorkerPool’s worker image, so the atelet and the worker are one native, signed release and nothing of the line depends on a copy. The kagent floor moves to 0.11.0-gs.22 the same way (components.kagent*.versionRange >=0.11.0-gs.22 <0.11.1-0, the BOM pin): the chart paths on gsoci begin with each line’s first native release — the older releases exist there as retagger’s image copies only, no charts — and the kagent chart’s stamped digests of its Go ADK and Claude harness images resolve on gsoci from that release on. With the charts the last ghcr.io reference of the two lines goes: a default installation pulls everything of kagent and Substrate from gsoci, and the dev channel (a components.<name>.semverFilter on the lines’ -dev.giantswarm. builds) needs no registry override any more — kagent.registry and substrate.image.registry stay on their defaults (README “Dev channel”). make verify-images tolerates the two lines by name no longer; the upstream CloudNativePG chart is the one pending entry left, behind a Giant Swarm wrapper release on the same operator line. verify-components and verify-kagent-wiring assert the new sources; verify-target holds them on both sides of the golden comparison until origin/main carries them. UPGRADE.md.
    • An Overview board, the entry point of the platform’s Grafana folder (giantswarm/giantswarm#36711). dashboards in both charts renders one ConfigMap per JSON under the connectivity chart’s dashboards/ directory, discovered by observability-operator through app.giantswarm.io/kind: dashboard and placed by the organization and folder annotations (both values carry a space, so neither can be a label). It ships overview.json, uid agent-platform-overview, in Shared Org / Agent Platform: what the platform is and which board covers what; component health; what it is doing; and the Postgres and Valkey rows, which have no board of their own. Every health panel reads the same series as the alert that pages for it — gotk_resource_info, kube_deployment_status_replicas_available, muster_mcpserver_state, kube_cnpg_cluster_info, kube_pod_container_status_restarts_total, muster_session_store_backend, redis_memory_used_bytes — so a panel and a page cannot disagree. Today the six alerts of agent-platform.rules.yml hand on-call a runbook and no graph. The ConfigMaps render under the resolved global.observability.metrics.serviceMonitor.enabled: the operator that picks them up is part of the observability platform the monitors write to. A component’s own board still comes from its own chart. The Postgres and the Valkey row, and the six agentgateway panels of the “what it is doing” row, are gated on the series they read: each one repeats over a hidden label_values(<metric>, __name__) variable, which yields one value while the metric exists and none while it does not, so an installation that runs neither CloudNativePG nor Valkey nor the agentgateway data plane opens the board without a row of “No data”. A component that is on but not yet scraped is hidden the same way, which a Helm conditional on components.<name>.enabled could not do.

    Changed

    • The mcp-kubernetes chart’s own ServiceMonitor and its three Grafana boards are on (giantswarm/giantswarm#36711). The chart ships a ServiceMonitor over the dedicated metrics port and the boards administrator, security and cluster-operator, and this chart turned none of them on, so an installation that runs the Kubernetes MCP server collected nothing from it. mcp-kubernetes.mcpKubernetes.instrumentation.serviceMonitor.enabled and mcp-kubernetes.grafanaDashboards.enabled follow the resolved global.observability.metrics.serviceMonitor.enabled (auto | true | false), the monitor carries observability.giantswarm.io/tenant, and the boards land in Shared Org / Agent Platform beside the platform’s own. The chart’s prometheusRules stay off: its three alerts link to runbook pages that do not exist yet. The floor 1.1.1 already carries every key, so no range moves.
    • Every agent platform dashboard lands in one folder customers can reach: Shared Org / Agent Platform (giantswarm/giantswarm#36711). The muster board (Muster / MCP Gateway) was loaded into the staff-only Giant Swarm organization, in a folder named after the component, so the people who run agents on the platform could not see it: muster.observability.grafanaDashboard.folder is Agent Platform and .giantswarm.organization is Shared Org. Shared Org is the organization every logged-in customer reaches as a Viewer and it carries the observability data of Giant Swarm managed components, which is where these boards belong; the Giant Swarm organization is staff-only. The boards that follow — the agentgateway gateway board, the platform’s own overview — land in the same folder.
  • Added

    Full Changelog: https://github.com/giantswarm/agent-platform/compare/v4.51.0...v4.52.0

  • Added

    • (observability) Turn on the agentgateway chart’s own monitors and board in #616 by @QuentinBisson

    Full Changelog: https://github.com/giantswarm/agent-platform/compare/v4.50.0...v4.51.0

  • Added

    • (dashboards) Load the muster board into Shared Org / Agent Platform in #615 by @QuentinBisson

    Full Changelog: https://github.com/giantswarm/agent-platform/compare/v4.49.0...v4.50.0

  • Fixed

    • spec.headers reach a person’s session connection. An MCPServer’s spec.headers were sent by the server-level client only; the connection muster opens for a person’s session to an OAuth server (the person’s grant as bearer, a forwarded login token, a token exchanged for it) sent none of them. The hosted GitHub MCP server selects its toolsets per session from X-MCP-Toolsets, so with spec.headers: {X-MCP-Toolsets: default,git} on the github MCPServer the server-level probe saw the git toolset while every person’s session connected with the default 48 tools and x_github_get_repository_tree was “tool not found”. The headers now travel with the pending-auth registration into the aggregator’s registry, next to spec.meta and spec.timeout, and every session-scoped client sends them on the handshake and on every call; the session’s Authorization header stays its own, an entry of that name in the definition is left out. A change of spec.headers on a live definition closes the connections the sessions hold to the server the way an auth configuration change does (session_auth_reset, changed: headers), tools kept resolvable; a session’s next call reconnects with the grant it still holds, and that connection carries the new set. Scenario oauth-session-client-sends-definition-headers; the mock backend’s tools gained echo_headers and a pre-configured mock’s config a headers field for the definition. (#1304)
  • Added

    • Awaiting Session: a per-session server’s state says whether it works. An MCPServer whose callers bring their own identity (auth.forwardToken, auth.tokenExchange) holds no connection of its own and, with no session connected, read Auth Required – the same state as a server waiting for a person to sign in through muster, and the same state whether every exchange succeeded or none could. Such a server now reads Awaiting Session (service state awaiting_session, Normal event MCPServerAwaitingSession) wherever it read Auth Required before: after the probe, after the last session’s connection is lost, after an automatic recovery reached it; Auth Required keeps its one meaning. A tokenExchange server verifies its client credentials Secret at start and is Failed with the Secret named while it is missing, retried with the reconnect backoff so a Secret that arrives later heals it. Every per-user exchange the aggregator performs reaches the server’s state: a failure every caller shares (the credentials Secret, invalid_client, a token endpoint that does not answer or answers 5xx, an unknown connector) puts the server in Failed with the exchange error as lastError, and the next successful exchange, a restart or a spec change returns it to Awaiting Session; a failure of the caller’s own token stays that session’s. The reconciler writes a Ready condition for every server whose reason names the state (AwaitingSession, Connected, AuthRequired, Suspended, …) or the class of an exchange failure (TokenExchangeCredentials, TokenExchangeEndpoint, TokenExchangeConnector) and whose message explains it – for Awaiting Session the mechanism, the token endpoint and connector, and when the last exchange succeeded. muster list mcpserver, core_service_status, the CRDs of both charts and the reference docs carry the state; core_service_start and core_service_restart on such a server say what it waits for instead of pointing at a sign-in that does not exist. The scenario oauth-sso-token-exchange-state pins the states through a real RFC 8693 exchange against the harness’s authorization server. (#1300)
  • Changed

    Full Changelog: https://github.com/giantswarm/muster/compare/v5.27.10...v5.27.11

  • Fixed

    • Agentgateway controller at the line’s 2.0.0 under its nested name

    Full Changelog: https://github.com/giantswarm/agent-platform/compare/v3.23.1...v3.23.2

  • Changed

    Full Changelog: https://github.com/giantswarm/klaus/compare/v0.1.23...v0.1.24

  • Added

    • The three upstream lines at their decoupled releases — kagent 1.0.0, Substrate 1.0.0, agentgateway 2.0.0 in full (#608) in #609 by @teemow

    Full Changelog: https://github.com/giantswarm/agent-platform/compare/v4.48.2...v4.49.0