AI Agents

  • Fixed

    • Karpenter scales the Substrate worker pool again (giantswarm/agent-platform#798). The meta chart derived the workers’ affinity to the atelet on their node as a required term; Karpenter cannot see a DaemonSet’s pods on a node it has not launched, so a worker that fit no existing node stayed Pending for good (unsatisfiable topology constraint for pod affinity), the pool stayed below its desired size and the pool’s nodes were never consolidated. The derived term is now preferred (weight 100): a worker still goes where an atelet is bound whenever such a node has room, and Karpenter launches a node when none has.
  • Added

    • The data plane’s access log names the session of an agent’s model call: agent_instance_id (giantswarm/giantswarm#38023). The kagent line names the AgentInstance a turn runs in (a Dev Portal conversation, a Slack thread) in x-kagent-agent-instance-id on every model call of the turn (giantswarm/kagent-upstream#149). The connectivity chart renders a Gateway-scoped AgentgatewayPolicy <release>-access-log whose frontend.accessLog.attributes add that header as agent_instance_id, read behind the same Substrate egress predicate as the agent labels, so the cost of one conversation can be summed from the llm listener’s lines without one metric series per session. gateway.accessLog.attributes is a map of {expression, enabled} entries in both charts; make verify-access-log asserts it. Every installation with the agentgateway data plane gets one new object; no pod rolls.
  • Fixed

    • The Substrate snapshot store expires nothing (giantswarm/agent-platform#792). The connectivity chart gave the CAPA bucket a 30-day Expiration rule and the CAPZ container a 30-day ManagementPolicy, on the premise that an actor whose snapshot expired boots cold from the golden image. Neither Substrate nor kagent does that, and Substrate already deletes every snapshot it replaces and an actor’s prefix with the actor, so the rule only ever deleted live data: the golden snapshot of a template whose revision had not changed in 30 days (its new actors then fail to start) and the only snapshot of an actor suspended that long (it cannot resume). The bucket now only aborts incomplete multipart uploads after a day, the container has no lifecycle policy, and kagent.harness.snapshotStore.crossplane.{aws,capz}.lifecycleDays are gone (a left-over key fails the render, naming it). The README documents the store’s retention and capacity. make verify-substrate-store asserts both providers’ rules and the guard; the kagent-pg backup bucket keeps its expiry.
  • Fixed

    • Every progress notification of a downstream call reaches the caller. mcp-go’s streamable-http server could drop a notification its forwarder had already taken when the response was written first, and sent a call’s notifications on the standalone GET stream, where they could arrive after the call’s response and be dropped by the per-call progress router. muster builds with giantswarm/mcp-go, mcp-go v1.1.1 with both fixes, until an upstream release carries them; the progress tests no longer pace the backend on delivery.
  • Fixed

    • model-manager deletes only the ModelConfigs it created: components.model-manager.versionRange is >=1.9.1 <2.0.0 (giantswarm/model-manager#230). Before 1.9.1, any model-manager took every ModelConfig labelled app.kubernetes.io/managed-by: model-manager for its own. So an unload by a second model-manager writing into the same kagent namespace, or of a model whose ModelConfig was a copied manifest, deleted ModelConfigs that AgentTemplates reference. From 1.9.1 a ModelConfig records the instance that created it (model-manager.giantswarm.io/instance, which the model-manager chart sets to <release namespace>-<release name>), and only that instance deletes it; any other is left in place and named in the unload’s answer (modelConfigLeft). The customer BOM pins 1.9.1.
  • Added

    • README “Private skill repositories”: the credential contract of the kagent API v2 line (giantswarm/agent-platform#369). The credential is per source on the AgentTemplate (skills[].source.git.credentialRef), a Secret next to the template, never on the platform Harness: who provisions it, its shape (base64("<username>:<token>"), sent by the egress gateway as Authorization: Basic), rotation, the conditions a missing Secret or a wrong token leave, and where the token is visible (the Secret, Substrate’s credential provider and egress gateway; not the ActorTemplate, the actor or the snapshots). make verify-kagent-crds asserts the pinned AgentTemplate CRD serves skills[]/plugins[].source.git.credentialRef.

    Fixed

    • make verify-kagent-crds validates against the CRDs the platform installs, and kagent.modelConfigs[] takes the Mistral provider (giantswarm/agent-platform#369). The verify read the kagent line’s CRDs at a hard-coded v1.0.0 while components.kagent-crds installs >=1.2.0, so the re-pin onto 1.2 never met its sweep of the provider enum, and the 1.2 ModelConfig’s eleventh provider was refused by the render naming ten. The verify now reads its release from the floor of components.kagent-crds.versionRange; the chart accepts Mistral and renders its baseUrl under spec.mistral.
  • Added

    • Downstream progress reaches the caller. A tool call whose _meta carries a progressToken (on call_tool or a tool called directly) now gets the notifications/progress of the downstream tools it reaches, under its own token; before, muster sent no token downstream and relayed no progress, so a long-running tool showed nothing until its result. muster sends each downstream request a token of its own and routes the notifications by it, so a connection shared by several sessions hands each caller only its own progress; a notification for a token no call in flight carries, or one whose progress does not increase, is dropped and counted in muster_downstream_progress_notifications_total. (#974)
  • Added

    • A call_tool result names the tool it ran. The envelope has a new last field, tool: name (the tool asked for), and for a tool an MCP server serves, server (the MCPServer the aggregator dispatched it to) and serverTool (the server’s own name for it). The same object is the call_tool result’s _meta under muster.giantswarm.io/tool. A consumer that attributes a result (shows “ran list_pods on kubernetes”) no longer has to remember each call’s arguments by call ID. The agent client puts it into the unwrapped result’s _meta, read with metatools.DispatchedToolFromMeta. The wrapped result’s envelope bytes are unchanged before the new field. (#982)
  • Changed

    • (workflow) Pin allowFailure aliases on forEach sub-steps in #1401 by @teemow

    Full Changelog: https://github.com/giantswarm/muster/compare/v5.35.1...v5.35.2

  • Fixed

    • call_tool no longer loses images, audio, embedded resources, resource links, content annotations or result _meta of the tool it wraps. The envelope JSON keeps image and audio items size-only ({type, mimeType, dataSize}) so it stays small for a model reading it, and the items follow the envelope as native MCP content with their payload, in order. Content annotations and _meta are kept on every envelope item and the result’s _meta is a new _meta envelope field. The agent client restores every content type from the envelope, the image and audio payloads from the native items, and the result _meta; muster call renders the first text item instead of failing when a result starts with an image. A result that uses none of these keeps its envelope byte for byte.