proposal

package
v0.0.1-dev.20260520 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 20, 2026 License: Apache-2.0 Imports: 32 Imported by: 0

Documentation

Index

Constants

View Source
const (
	LabelManaged      = "agentic.openshift.io/managed"
	LabelBaseTemplate = "agentic.openshift.io/base-template"
	LabelStep         = "agentic.openshift.io/step"
	LabelAgent        = "agentic.openshift.io/agent"
	LabelProposal     = "agentic.openshift.io/proposal"
	LabelComponent    = "agentic.openshift.io/component"
)

Variables

View Source
var AnalysisOutputSchema = json.RawMessage(`{
  "type": "object",
  "properties": {
    "options": {
      "type": "array",
      "description": "One or more remediation options, ordered by recommendation. Provide at least one.",
      "minItems": 1,
      "items": {
        "type": "object",
        "properties": {
          "title": { "type": "string", "description": "Short human-readable title for this option (e.g., 'Increase memory limit', 'Scale horizontally')" },
          "summary": { "type": "string", "description": "Brief one-paragraph summary of this remediation approach" },
          "diagnosis": {
            "type": "object",
            "properties": {
              "summary": { "type": "string", "description": "Markdown-formatted root cause analysis explaining the problem, symptoms, and findings" },
              "confidence": { "type": "string", "enum": ["Low", "Medium", "High"], "description": "Your confidence in this diagnosis. Low: ambiguous symptoms. Medium: likely cause identified. High: clear, deterministic root cause" },
              "rootCause": { "type": "string", "description": "Concise one-line root cause (e.g., 'OOMKilled due to memory limit of 256Mi')" }
            },
            "required": ["summary", "confidence", "rootCause"]
          },
          "proposal": {
            "type": "object",
            "properties": {
              "description": { "type": "string", "description": "Markdown-formatted summary of the overall remediation approach" },
              "actions": {
                "type": "array",
                "description": "Ordered list of discrete actions to perform",
                "items": {
                  "type": "object",
                  "properties": {
                    "type": { "type": "string", "description": "Action category (e.g., 'patch', 'scale', 'restart', 'create', 'delete', 'rollout')" },
                    "description": { "type": "string", "description": "What this action does (e.g., 'Increase memory limit from 256Mi to 512Mi')" }
                  },
                  "required": ["type", "description"]
                }
              },
              "risk": { "type": "string", "enum": ["Low", "Medium", "High", "Critical"], "description": "Risk assessment. Low: safe to apply. Medium: review recommended. High: careful review required. Critical: manual approval strongly recommended" },
              "reversible": { "type": "string", "enum": ["Reversible", "Irreversible", "Partial"], "description": "Whether this remediation can be rolled back. Reversible: fully undoable. Irreversible: cannot undo. Partial: some actions undoable" },
              "estimatedImpact": { "type": "string", "description": "Expected impact on the system (e.g., 'Brief pod restart, ~30s downtime')" },
              "rollbackPlan": {
                "type": "object",
                "description": "How to undo the remediation if it fails or causes issues. Required when reversible is Reversible or Partial.",
                "properties": {
                  "description": { "type": "string", "description": "How to undo the remediation if it fails or causes issues" },
                  "command": { "type": "string", "description": "The rollback command or steps to execute" }
                },
                "required": ["description", "command"]
              }
            },
            "required": ["description", "actions", "risk", "reversible"]
          },
          "verification": {
            "type": "object",
            "properties": {
              "description": { "type": "string", "description": "Summary of how to verify the remediation worked" },
              "steps": {
                "type": "array",
                "description": "Ordered verification checks for the verification agent to run after execution",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": { "type": "string", "description": "Short check identifier (e.g., 'pod-running', 'memory-usage-normal')" },
                    "command": { "type": "string", "description": "Command or API call to run (e.g., 'oc get pod -n production -l app=web -o jsonpath={.status.phase}')" },
                    "expected": { "type": "string", "description": "Expected output or condition (e.g., 'Running', 'ready=true')" },
                    "type": { "type": "string", "description": "Check category (e.g., 'command', 'metric', 'condition')" }
                  }
                }
              }
            }
          },
          "rbac": {
            "type": "object",
            "properties": {
              "namespaceScoped": {
                "type": "array",
                "description": "RBAC rules scoped to the proposal's target namespaces",
                "items": {
                  "type": "object",
                  "properties": {
                    "namespace": { "type": "string", "description": "Target namespace for this rule. Must match one of the proposal's targetNamespaces" },
                    "apiGroups": { "type": "array", "items": { "type": "string" }, "description": "API groups (e.g., '', 'apps', 'batch'). Use empty string '' for the core API group (pods, services, configmaps, etc.)" },
                    "resources": { "type": "array", "items": { "type": "string" }, "description": "Resource types (e.g., 'pods', 'deployments', 'configmaps')" },
                    "resourceNames": { "type": "array", "items": { "type": "string" }, "description": "Restrict to specific named resources. Omit to allow all resources of the given type" },
                    "verbs": { "type": "array", "items": { "type": "string" }, "description": "Allowed operations (e.g., 'get', 'list', 'patch', 'delete')" },
                    "justification": { "type": "string", "description": "Why this permission is needed (e.g., 'Need to patch deployment to increase memory limit')" }
                  },
                  "required": ["apiGroups", "resources", "verbs", "justification"]
                }
              },
              "clusterScoped": {
                "type": "array",
                "description": "RBAC rules for cluster-wide or non-namespaced resources (e.g., nodes, CRDs)",
                "items": {
                  "type": "object",
                  "properties": {
                    "apiGroups": { "type": "array", "items": { "type": "string" }, "description": "API groups (e.g., '', 'apps', 'batch'). Use empty string '' for the core API group (pods, services, configmaps, etc.)" },
                    "resources": { "type": "array", "items": { "type": "string" }, "description": "Resource types (e.g., 'nodes', 'clusterroles')" },
                    "resourceNames": { "type": "array", "items": { "type": "string" }, "description": "Restrict to specific named resources. Omit to allow all resources of the given type" },
                    "verbs": { "type": "array", "items": { "type": "string" }, "description": "Allowed operations (e.g., 'get', 'list', 'patch', 'delete')" },
                    "justification": { "type": "string", "description": "Why this permission is needed" }
                  },
                  "required": ["apiGroups", "resources", "verbs", "justification"]
                }
              }
            }
          }
        },
        "required": ["title", "diagnosis", "proposal", "verification"]
      }
    }
  },
  "required": ["options"]
}`)
View Source
var EscalationOutputSchema = json.RawMessage(`{
  "type": "object",
  "properties": {
    "success": { "type": "boolean", "description": "Whether the escalation analysis completed successfully" },
    "summary": { "type": "string", "description": "Markdown summary of the escalation analysis and recommendations" },
    "content": { "type": "string", "description": "Detailed escalation content: root cause analysis across all failed attempts, recommended next steps, and any information for the escalation target" }
  },
  "required": ["success", "summary", "content"]
}`)
View Source
var ExecutionOutputSchema = json.RawMessage(`{
  "type": "object",
  "properties": {
    "success": { "type": "boolean", "description": "Whether all execution actions completed successfully" },
    "actionsTaken": {
      "type": "array",
      "description": "List of actions actually performed, in order",
      "items": {
        "type": "object",
        "properties": {
          "type": { "type": "string", "description": "Action category (e.g., 'patch', 'scale', 'restart')" },
          "description": { "type": "string", "description": "What was done (e.g., 'Patched deployment/web to set memory limit to 512Mi')" },
          "outcome": { "type": "string", "enum": ["Succeeded", "Failed"], "description": "Whether this individual action succeeded or failed" },
          "output": { "type": "string", "description": "Command output or API response from the action" },
          "error": { "type": "string", "description": "Error message if the action failed" }
        },
        "required": ["type", "description", "outcome"]
      }
    },
    "verification": {
      "type": "object",
      "description": "Lightweight inline verification performed immediately after execution",
      "properties": {
        "conditionOutcome": { "type": "string", "enum": ["Improved", "Unchanged", "Degraded"], "description": "Whether the target condition improved after remediation" },
        "summary": { "type": "string", "description": "Brief inline verification summary of what you observed after applying the fix" }
      }
    }
  },
  "required": ["success", "actionsTaken"]
}`)
View Source
var MinimalAnalysisOutputSchema = json.RawMessage(`{
  "type": "object",
  "properties": {
    "options": {
      "type": "array",
      "description": "One or more output options, ordered by recommendation. Provide at least one.",
      "minItems": 1,
      "items": {
        "type": "object",
        "properties": {
          "title": { "type": "string", "description": "Short human-readable title for this option" }
        },
        "required": ["title"]
      }
    }
  },
  "required": ["options"]
}`)

MinimalAnalysisOutputSchema is the base analysis output schema used when AnalysisOutputMode is Minimal. It contains only the options array with title per option. Built-in properties (diagnosis, proposal, rbac, verification, summary) are omitted. If execution or verification steps exist, those specific property definitions are added back dynamically.

View Source
var VerificationOutputSchema = json.RawMessage(`{
  "type": "object",
  "properties": {
    "success": { "type": "boolean", "description": "Whether all verification checks passed" },
    "checks": {
      "type": "array",
      "description": "Individual verification check results",
      "items": {
        "type": "object",
        "properties": {
          "name": { "type": "string", "description": "Check identifier matching the analysis verification plan (e.g., 'pod-running')" },
          "source": { "type": "string", "description": "The full command that was run (e.g., 'oc get pod -n production -o jsonpath={.status.phase}', 'promql: rate(container_cpu_usage_seconds_total[5m])')" },
          "value": { "type": "string", "description": "Actual observed value (e.g., 'Running', '3 replicas')" },
          "result": { "type": "string", "enum": ["Passed", "Failed"], "description": "Whether the observed value matches expectations" }
        },
        "required": ["name", "result"]
      }
    },
    "summary": { "type": "string", "description": "Overall verification summary in Markdown" }
  },
  "required": ["success", "checks", "summary"]
}`)

Functions

func EnsureAgentTemplate

func EnsureAgentTemplate(
	ctx context.Context,
	c client.Client,
	baseTemplateName string,
	namespace string,
	step string,
	agent *agenticv1alpha1.Agent,
	llm *agenticv1alpha1.LLMProvider,
	tools *agenticv1alpha1.ToolsSpec,
) (string, error)

EnsureAgentTemplate creates a SandboxTemplate derived from the base template with skills, LLM credentials, MCP servers, and required secrets from the CRD chain. Template name includes a config hash — same input = same template = no-op. Old templates for the same agent+phase are garbage-collected.

func SandboxTemplateServiceAccount

func SandboxTemplateServiceAccount(ctx context.Context, c client.Client, templateName, namespace string) (string, error)

SandboxTemplateServiceAccount reads the service account name from a SandboxTemplate.

Types

type AgentCaller

type AgentCaller interface {
	Analyze(ctx context.Context, proposal *agenticv1alpha1.Proposal, step resolvedStep, requestText string) (*AnalysisOutput, error)
	Execute(ctx context.Context, proposal *agenticv1alpha1.Proposal, step resolvedStep, option *agenticv1alpha1.RemediationOption) (*ExecutionOutput, error)
	Verify(ctx context.Context, proposal *agenticv1alpha1.Proposal, step resolvedStep, option *agenticv1alpha1.RemediationOption, exec *ExecutionOutput) (*VerificationOutput, error)
	Escalate(ctx context.Context, proposal *agenticv1alpha1.Proposal, step resolvedStep, requestText string) (*EscalationOutput, error)
	ReleaseSandboxes(ctx context.Context, proposal *agenticv1alpha1.Proposal) error
}

AgentCaller abstracts the agent invocation path. The reconciler passes structured data; the implementation decides how to format it for the LLM (text-only prompt vs multimodal with binary attachments). In production this manages sandbox lifecycle + HTTP calls; in tests a stub returns canned results.

HTTP implementations POST to /v1/agent/run — a step-agnostic endpoint where all workflow context is in the request payload.

type AgentHTTPClient

type AgentHTTPClient struct {
	// contains filtered or unexported fields
}

AgentHTTPClient communicates with the agentic-sandbox REST API.

func (*AgentHTTPClient) Run

func (c *AgentHTTPClient) Run(ctx context.Context, systemPrompt, query string, outputSchema json.RawMessage, agentCtx *agentContext) (*agentRunResponse, error)

type AgentHTTPClientInterface

type AgentHTTPClientInterface interface {
	Run(ctx context.Context, systemPrompt, query string, outputSchema json.RawMessage, agentCtx *agentContext) (*agentRunResponse, error)
}

AgentHTTPClientInterface abstracts HTTP calls to the agent service for testability.

func NewAgentHTTPClient

func NewAgentHTTPClient(endpoint string) AgentHTTPClientInterface

type AnalysisOutput

type AnalysisOutput struct {
	Success bool
	Options []agenticv1alpha1.RemediationOption
}

AnalysisOutput holds the analysis agent's output.

type EscalationOutput

type EscalationOutput struct {
	Success bool
	Summary string
	Content string
}

EscalationOutput holds the escalation agent's output.

type ExecutionOutput

type ExecutionOutput struct {
	Success      bool
	ActionsTaken []agenticv1alpha1.ExecutionAction
	Verification agenticv1alpha1.ExecutionVerification
}

ExecutionOutput holds the execution agent's output.

type ProposalReconciler

type ProposalReconciler struct {
	client.Client
	Log       logr.Logger
	Agent     AgentCaller
	Namespace string
}

ProposalReconciler reconciles Proposal objects.

Agent must be set before calling SetupWithManager.

func (*ProposalReconciler) Reconcile

func (r *ProposalReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error)

func (*ProposalReconciler) SetupWithManager

func (r *ProposalReconciler) SetupWithManager(mgr ctrl.Manager) error

SetupWithManager sets up the controller with the Manager.

type SandboxAgentCaller

type SandboxAgentCaller struct {
	Sandbox       SandboxProvider
	K8sClient     client.Client
	ClientFactory func(endpoint string) AgentHTTPClientInterface
	Namespace     string
	Timeout       time.Duration
}

SandboxAgentCaller implements AgentCaller by claiming a sandbox pod, calling the agent HTTP service, and releasing the sandbox on completion.

func NewSandboxAgentCaller

func NewSandboxAgentCaller(
	sandbox SandboxProvider,
	k8sClient client.Client,
	clientFactory func(endpoint string) AgentHTTPClientInterface,
	namespace string,
) *SandboxAgentCaller

func (*SandboxAgentCaller) Analyze

func (s *SandboxAgentCaller) Analyze(ctx context.Context, proposal *agenticv1alpha1.Proposal, step resolvedStep, requestText string) (*AnalysisOutput, error)

func (*SandboxAgentCaller) Escalate

func (s *SandboxAgentCaller) Escalate(ctx context.Context, proposal *agenticv1alpha1.Proposal, step resolvedStep, requestText string) (*EscalationOutput, error)

func (*SandboxAgentCaller) Execute

func (s *SandboxAgentCaller) Execute(ctx context.Context, proposal *agenticv1alpha1.Proposal, step resolvedStep, option *agenticv1alpha1.RemediationOption) (*ExecutionOutput, error)

func (*SandboxAgentCaller) ReleaseSandboxes

func (s *SandboxAgentCaller) ReleaseSandboxes(ctx context.Context, proposal *agenticv1alpha1.Proposal) error

func (*SandboxAgentCaller) Verify

type SandboxManager

type SandboxManager struct {
	Client    client.Client
	Namespace string
}

SandboxManager handles SandboxClaim lifecycle for proposal execution.

func NewSandboxManager

func NewSandboxManager(c client.Client, namespace string) *SandboxManager

func (*SandboxManager) Claim

func (m *SandboxManager) Claim(ctx context.Context, proposalName, step, templateName string) (string, error)

func (*SandboxManager) Release

func (m *SandboxManager) Release(ctx context.Context, claimName string) error

func (*SandboxManager) WaitReady

func (m *SandboxManager) WaitReady(ctx context.Context, claimName string, timeout time.Duration) (string, error)

type SandboxProvider

type SandboxProvider interface {
	Claim(ctx context.Context, proposalName, step, templateName string) (claimName string, err error)
	WaitReady(ctx context.Context, claimName string, timeout time.Duration) (endpoint string, err error)
	Release(ctx context.Context, claimName string) error
}

SandboxProvider abstracts sandbox lifecycle for testability.

type StubAgentCaller

type StubAgentCaller struct{}

StubAgentCaller returns canned success results. Wire in a real implementation (sandbox + HTTP) when the agent infrastructure is ready.

func (*StubAgentCaller) Analyze

func (s *StubAgentCaller) Analyze(_ context.Context, _ *agenticv1alpha1.Proposal, _ resolvedStep, _ string) (*AnalysisOutput, error)

func (*StubAgentCaller) Escalate

func (s *StubAgentCaller) Escalate(_ context.Context, _ *agenticv1alpha1.Proposal, _ resolvedStep, _ string) (*EscalationOutput, error)

func (*StubAgentCaller) Execute

func (*StubAgentCaller) ReleaseSandboxes

func (s *StubAgentCaller) ReleaseSandboxes(_ context.Context, _ *agenticv1alpha1.Proposal) error

func (*StubAgentCaller) Verify

type VerificationOutput

type VerificationOutput struct {
	Success bool
	Checks  []agenticv1alpha1.VerifyCheck
	Summary string
}

VerificationOutput holds the verification agent's output.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL