feat: add built-in prompts and prompt templates for agents (#1401)#1405
feat: add built-in prompts and prompt templates for agents (#1401)#1405
Conversation
Add Go text/template support to the Agent CRD's systemMessage field,
enabling composable prompt fragments and variable interpolation. Templates
are resolved at reconciliation time by the controller.
- Add PromptSource type using inlined TypedLocalReference for extensibility
- Add promptSources field to DeclarativeAgentSpec
- Implement template resolution with {{include "source/key"}} syntax and
agent context variables (AgentName, AgentNamespace, Description,
ToolNames, SkillNames)
- Add ConfigMap watch to agent controller for automatic re-reconciliation
- Ship kagent-builtin-prompts Helm ConfigMap with 5 built-in templates
(skills-usage, tool-usage-best-practices, safety-guardrails,
kubernetes-context, a2a-communication)
- Add GetConfigMapData/GetSecretData utility functions
- Add architecture documentation in docs/architecture/prompt-templates.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Wrap the prompt sources list in a PromptTemplateSpec struct, changing the CRD field from `promptSources: []` to `promptTemplate.dataSources: []`. This groups template-related configuration under a single field and provides a natural extension point for future template settings. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
There was a problem hiding this comment.
Pull request overview
Adds a prompt-templating system for Agent declarative systemMessage, enabling composition from ConfigMap/Secret fragments via {{include "source/key"}} and interpolation of agent context variables at reconciliation time.
Changes:
- Extends the Agent CRD with
promptSources(PromptSource) and documents template behavior forsystemMessage/systemMessageFrom. - Implements template resolution (include + variable context) in the Go controller translator, with unit tests.
- Ships a Helm-installed
kagent-builtin-promptsConfigMap plus controller watch logic and utility helpers for fetching ConfigMap/Secret data.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| helm/kagent/templates/builtin-prompts-configmap.yaml | Adds Helm ConfigMap containing built-in prompt fragments. |
| go/internal/utils/secret.go | Adds helper to fetch all Secret data as strings. |
| go/internal/utils/config_map.go | Adds helper to fetch all ConfigMap data. |
| go/internal/controller/translator/agent/template.go | Implements prompt source resolution, template context building, and template execution. |
| go/internal/controller/translator/agent/template_test.go | Adds unit tests for include and interpolation behavior. |
| go/internal/controller/translator/agent/adk_api_translator.go | Integrates template resolution into system message translation. |
| go/internal/controller/agent_controller.go | Adds ConfigMap watch to re-reconcile affected agents. |
| go/api/v1alpha2/agent_types.go | Adds PromptSource type and promptSources to the declarative spec. |
| go/api/v1alpha2/zz_generated.deepcopy.go | Updates generated deepcopy logic for the new API fields/types. |
| docs/architecture/prompt-templates.md | Adds architecture/design documentation for prompt templates. |
Comments suppressed due to low confidence (1)
go/api/v1alpha2/agent_types.go:187
PromptSourceinlinesTypedLocalReference, which includes an optionalnamespacefield. Unless cross-namespace prompt sourcing is an explicit, access-controlled feature, this should be constrained (e.g., disallow settingnamespaceor require it to match the Agent namespace via XValidation). Otherwise, users can point agents at ConfigMaps/Secrets in other namespaces, and the controller’s broad RBAC will allow those reads.
Context *ContextConfig `json:"context,omitempty"`
}
// ContextConfig configures context management for an agent.
type ContextConfig struct {
// Compaction configures event history compaction.
// When enabled, older events in the conversation are compacted (compressed/summarized)
// to reduce context size while preserving key information.
// +optional
Compaction *ContextCompressionConfig `json:"compaction,omitempty"`
}
// ContextCompressionConfig configures event history compaction/compression.
type ContextCompressionConfig struct {
// The number of *new* user-initiated invocations that, once fully represented in the session's events, will trigger a compaction.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Tests the full flow: creating a ConfigMap with prompt fragments, creating an Agent with promptTemplate.dataSources referencing it, verifying the agent reaches Ready state, and confirming that a ConfigMap update triggers re-reconciliation while the agent remains functional. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Refactor all 10 agent helm charts to use the new promptTemplate feature, replacing repeated safety, operational, and tool-usage sections with includes from the kagent-builtin-prompts ConfigMap. Changes per agent: - k8s, helm: replaced Investigation Protocol, Safety Protocols, added tool-usage-best-practices - cilium-debug, cilium-manager: replaced Operational Protocol, Safety Guidelines - istio: replaced Operational Protocol, Safety Guidelines - kgateway: added safety-guardrails include - observability: replaced Operational Guidelines with kubernetes-context and tool-usage-best-practices - cilium-policy, argo-rollouts, promql: added minimal includes while preserving domain-specific reference material Also enhanced the built-in prompts ConfigMap with more substantive content based on patterns observed across all agents. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
- Replace sort.Strings with slices.Sort (sort package forbidden by depguard)
- Remove Go template syntax ({{ }}) from CRD doc comments to prevent
Helm from interpreting them as template directives during CRD installation
- Regenerate CRD manifests and copy to helm chart
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
1. Drop Secret support from prompt sources — only ConfigMaps are supported to avoid security risks of referencing Secrets. 2. Adapt to TypedLocalReference (no namespace field) for PromptSource since prompt sources must be in the same namespace as the agent. 3. Move template resolution after the tool translation loop so tool names come from the already-built AgentConfig rather than being recomputed from the spec. 4. Use existing ociSkillName()/gitSkillName() helpers for skill name extraction instead of duplicating parsing logic. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Fix k8s, helm, cilium-debug, cilium-manager, and cilium-policy agents that had the wrong YAML structure — using an array with configMapRef directly under promptTemplate instead of the correct dataSources object with kind: ConfigMap entries. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
supreme-gg-gg
left a comment
There was a problem hiding this comment.
Tried this out very cool
go/internal/utils/secret.go
Outdated
| ) | ||
|
|
||
| // GetSecretData fetches all data from a Secret, converting byte values to strings. | ||
| func GetSecretData(ctx context.Context, c client.Client, ref client.ObjectKey) (map[string]string, error) { |
There was a problem hiding this comment.
This does not seem to be used anywhere?
|
|
||
| // resolvePromptSources fetches all data from the referenced ConfigMaps and builds | ||
| // a lookup map keyed by "identifier/key" where identifier is the alias (if set) or resource name. | ||
| func resolvePromptSources(ctx context.Context, kube client.Client, namespace string, sources []v1alpha2.PromptSource) (map[string]string, error) { |
There was a problem hiding this comment.
nit: since we only support configmaps kind, should we validate the PromptSource.Kind and give an error if the user tries to provide a secret?
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Add Go text/template support to the Agent CRD's systemMessage field, enabling composable prompt fragments and variable interpolation. Templates are resolved at reconciliation time by the controller.