> ## Documentation Index
> Fetch the complete documentation index at: https://flokoa.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# How Flokoa Works: Components and Architecture Guide

> Understand how the Flokoa operator, Custom Resource Definitions, and runtime backends work together to manage AI agents on Kubernetes.

Flokoa follows the standard Kubernetes operator pattern: a controller process runs inside your cluster, watches a set of Custom Resource Definitions, and continuously reconciles the cluster's actual state against the desired state you've declared in YAML. Understanding this pattern will help you reason about what happens when you apply, update, or delete a Flokoa resource — and what to look at when something goes wrong.

## The Flokoa operator

The Flokoa operator is a Kubernetes controller deployed into the `flokoa-system` namespace. It is the single component responsible for translating your Flokoa CRDs into runnable workloads.

**The operator:**

* Watches all six Flokoa CRDs (`Agent`, `ModelProvider`, `Model`, `AgentTool`, `Instruction`, `AgentWorkflow`) for create, update, and delete events across every namespace in the cluster.
* Runs a reconciliation loop for each resource — validating the spec, resolving cross-resource references, and computing what Kubernetes-native resources need to be created or updated.
* Creates and manages Kubernetes `Deployments` and `Services` to back each `Agent`.
* Updates the `status` subresource of each CRD to reflect the current phase, conditions, and any error details.
* Detects the AI framework running inside agent containers (pydantic-ai, LangChain, CrewAI, AutoGen, Marvin, Google ADK, A2A) and surfaces that information in the Agent status for observability.

<Note>
  The operator uses admission webhooks for structured validation at apply time, which means malformed specs are rejected before they ever reach the reconciler. Run `kubectl describe agent <name>` to see detailed condition messages when a resource fails to reconcile.
</Note>

## Custom Resource Definitions

Flokoa installs six CRDs under the `agent.flokoa.ai/v1alpha1` API group. Each CRD represents a distinct concern in the agent deployment pipeline.

<CardGroup cols={2}>
  <Card title="Agent" icon="robot">
    The primary resource. Declares the agent runtime mode, the Model it uses, the AgentTools it can call, scaling configuration, and lifecycle settings. The operator creates a Deployment and Service for each Agent.
  </Card>

  <Card title="ModelProvider" icon="plug">
    Stores LLM provider connection configuration and a reference to a Kubernetes Secret that holds the API key. A single ModelProvider can be shared across many Model resources — even across namespaces.
  </Card>

  <Card title="Model" icon="microchip">
    Selects a specific model name (e.g. `gpt-4o`, `claude-sonnet-4-20250514`) and sets inference parameters such as temperature, max tokens, and top-p. References a ModelProvider for the underlying connection.
  </Card>

  <Card title="AgentTool" icon="wrench">
    Defines an external HTTP API or internal Kubernetes service that an agent can invoke at runtime. You supply an OpenAPI schema; the operator injects the tool definition into the agent container's environment.
  </Card>

  <Card title="Instruction" icon="file-lines">
    Holds reusable system-level prompt instructions that can be attached to one or more agents, keeping prompt logic decoupled from the deployment spec.
  </Card>

  <Card title="AgentWorkflow" icon="diagram-project">
    Composes multiple agents into conditional, multi-step workflows. The operator compiles each AgentWorkflow into an Argo `WorkflowTemplate` and deploys an A2A executor sidecar for inter-agent calls.
  </Card>
</CardGroup>

## Resource relationships

Flokoa resources form a directed reference graph. Understanding this graph tells you what must exist before a given resource can become ready.

```
Secret (API key)
    └── referenced by ──► ModelProvider
                              └── referenced by ──► Model
                                                        └── referenced by ──► Agent ──► Deployment
AgentTool ─────────────────────────────────────────────────► Agent          └──► Service
```

* An **Agent** references a **Model** by name (and optionally namespace). The model must exist and be resolvable before the Agent can reach `Running`.
* A **Model** references a **ModelProvider** by name. The provider must exist and its Secret must be present.
* A **ModelProvider** references a Kubernetes **Secret** for its API key. The Secret must exist in the same namespace as the ModelProvider.
* An **Agent** may reference one or more **AgentTool** resources. Tools are resolved at reconcile time and injected into the agent's environment.

Cross-namespace references are supported for `Model` and `ModelProvider`, which lets you maintain shared provider and model resources in a central namespace (e.g. `shared-resources`) and reference them from any team or application namespace.

## Agent lifecycle

When you apply an Agent manifest, the operator moves it through a well-defined lifecycle. Use `kubectl describe agent <name>` to see the current phase and conditions at any point.

<Steps>
  <Step title="Create the Custom Resource">
    You apply an `Agent` manifest with `kubectl apply`. The admission webhook validates the spec structure before the resource is persisted to the Kubernetes API server.
  </Step>

  <Step title="Operator validates and resolves references">
    The operator's reconciler picks up the new Agent. It checks that the referenced `Model` exists, resolves the `Model` → `ModelProvider` → `Secret` chain, and verifies that any referenced `AgentTool` resources are present. If any reference is missing, the Agent phase is set to `Pending` and the condition message explains what is unresolved.
  </Step>

  <Step title="Operator creates the Deployment">
    Once all references resolve, the operator creates a Kubernetes `Deployment` in the same namespace as the Agent. The Deployment spec is constructed from the `runtime.spec` in your Agent manifest, with model credentials and tool definitions injected as environment variables or mounted configuration.
  </Step>

  <Step title="Operator creates the Service">
    The operator creates a `ClusterIP` Service that selects the agent's pods using the label `flokoa.ai/agent: <agent-name>`. This gives the agent a stable in-cluster DNS name: `<agent-name>.<namespace>.svc.cluster.local`.
  </Step>

  <Step title="Status updated to Running">
    Once the Deployment reports its pods as ready, the operator updates the Agent's `status.phase` to `Running` and sets the `Ready` condition to `True`. The agent is now reachable via its Service endpoint.
  </Step>
</Steps>

When you delete an Agent, the operator removes the Deployment and Service, terminates pods gracefully, and then removes the Agent resource itself after finalizers are cleared.

## Runtime backends

Every Agent spec declares a `runtime.type`. The type determines what Kubernetes resources the operator creates and how much of the agent's logic lives in your container vs. the operator.

### Standard runtime

The standard runtime is the default. You supply a container image; the operator creates a Kubernetes Deployment that runs it, along with a ClusterIP Service.

```yaml theme={null}
spec:
  runtime:
    type: standard
    spec:
      container:
        name: agent
        image: your-registry/your-agent:v1.0.0
        ports:
        - containerPort: 8080
          name: http
```

**What the operator creates:**

| Resource               | Purpose                                                         |
| ---------------------- | --------------------------------------------------------------- |
| `Deployment`           | Manages agent pod replicas, rolling updates, and restart policy |
| `Service` (ClusterIP)  | Provides a stable in-cluster endpoint for the agent pods        |
| `ConfigMap` (optional) | Mounts additional configuration data into the container         |

Standard mode gives you full control over the runtime. Use it when your agent has custom code, framework dependencies, or needs a specialized base image.

### Template runtime

In template mode, the operator uses the managed runtime image `ghcr.io/danielnyari/flokoa-cli:0.1.0`. The agent's behavior — what it does, how it responds — is defined entirely through the CRD spec via `Instruction` resources and an output schema. You don't build or maintain a container image.

<Note>
  Template mode is powered by pydantic-ai under the hood. It is best suited for agents whose logic is fully expressible through declarative instructions and a structured output schema. Choose standard mode when you need custom code, external Python packages, or a different AI framework.
</Note>

## Tool integration

`AgentTool` resources give agents the ability to call external HTTP APIs and internal Kubernetes services at runtime. Each AgentTool uses an OpenAPI specification to describe the API surface the agent can call.

**How an agent uses a tool at runtime:**

1. The operator resolves the AgentTool reference and injects the tool definition into the agent container's environment at startup.
2. The agent's LLM reasoning loop determines when a tool call is appropriate and generates the required parameters.
3. The agent container constructs the HTTP request using the endpoint URL or Kubernetes service reference from the tool spec, along with the LLM-generated parameters.
4. The agent parses the HTTP response using the tool's output schema and returns the result to the LLM for further reasoning.

**Internal tools** use a `serviceRef` to target a Kubernetes service — no external network access required, and no authentication is typically needed:

```yaml theme={null}
openApi:
  serviceRef:
    name: inventory-service
    namespace: backend
    port: 8080
  openApiSchema:
    endpointPath: "/openapi.json"
```

**External tools** use a `url` to target a public or private HTTP API:

```yaml theme={null}
openApi:
  url: "https://api.example.com"
  openApiSchema:
    endpointPath: "/openapi.json"
```

<Tip>
  Use internal `serviceRef` tools wherever possible for lower latency, simpler authentication, and stronger network isolation. Reserve external `url` tools for third-party APIs that live outside your cluster.
</Tip>
