New features: Route Stickness, Handoff, Clarification, Read-Only/Transactional, Long Term Memory

This commit is contained in:
2026-08-03 08:57:02 -03:00
parent e684b0ecc3
commit 8e414e4e26
604 changed files with 38978 additions and 402 deletions

10
deploy/oke/.dockerignore Normal file
View File

@@ -0,0 +1,10 @@
.git
.idea
__MACOSX
**/.DS_Store
**/__pycache__
**/*.pyc
.venv
venv
.env
data/*.db

View File

@@ -0,0 +1,476 @@
# Deployment do Agent Platform OCI em OCI OKE
Este pacote adiciona os artefatos necessários para publicar o `agent_platform_oci` em um cluster **OCI OKE / Kubernetes**.
O objetivo é atender a três pontos principais:
1. Publicar o `agent_framework` como biblioteca dentro das imagens Python, permitindo imports como:
```python
from agent_framework import ...
```
2. Implantar o `agent_template_backend` com múltiplos pods, `Service` interno e `HorizontalPodAutoscaler`, permitindo escalabilidade horizontal.
3. Implantar os componentes externos da plataforma:
- `agent_gateway`
- `channel_gateway`
- `mcp_gateway`
- `agent_frontend`
O desenho recomendado em OKE é:
```text
Usuário / Canal
|
| HTTP/S
v
OCI Load Balancer
|
+--> agent_frontend Serviço LoadBalancer
+--> agent_gateway Serviço LoadBalancer
+--> channel_gateway Serviço LoadBalancer
+--> mcp_gateway Serviço LoadBalancer
Dentro do cluster:
agent_gateway ---> agent_template_backend Service ---> vários pods do agente
agent_backend ---> mcp_gateway Service
mcp_gateway ---> MCP servers internos ou externos
```
> Observação: este pacote deixa os gateways como serviços externos `LoadBalancer`, conforme solicitado. Em produção, é comum expor apenas o `channel_gateway`, `agent_gateway` ou um Ingress/API Gateway corporativo, mantendo `mcp_gateway` interno.
---
## Estrutura criada
```text
deploy/oke/
README_OKE_DEPLOYMENT.md
.dockerignore
dockerfiles/
Dockerfile.agent-template-backend
Dockerfile.agent-gateway
Dockerfile.channel-gateway
Dockerfile.mcp-gateway
Dockerfile.agent-frontend
nginx/
default.conf
k8s/base/
00-namespace.yaml
01-configmap.yaml
02-secret-template.yaml
03-agent-template-backend.yaml
04-agent-gateway.yaml
05-channel-gateway.yaml
06-mcp-gateway.yaml
07-frontend.yaml
kustomization.yaml
scripts/
build_images.sh
push_images.sh
create_runtime_secret.sh
deploy_oke.sh
status.sh
examples/
oke.env.example
```
---
## Por que foram criados novos Dockerfiles
Os Dockerfiles existentes usam caminhos relativos ao diretório da aplicação, por exemplo:
```dockerfile
COPY agent_framework /agent_framework
COPY agent_template_backend /app
```
No repositório atual, o framework está em:
```text
libs/agent_framework
```
E o backend está em:
```text
templates/agent_template_backend
```
Por isso, os Dockerfiles de OKE usam a **raiz do repositório como build context** e fazem:
```dockerfile
COPY libs/agent_framework /opt/agent_framework
RUN pip install -e /opt/agent_framework
```
Assim, o `agent_framework` fica instalado como biblioteca Python dentro das imagens dos componentes que precisam dele.
---
## Pré-requisitos
Na máquina de build/deploy:
- Docker
- `kubectl`
- OCI CLI configurado
- Acesso ao cluster OKE
- Acesso ao OCIR
- Usuário OCI com permissões para push no OCIR
- Token de autenticação OCI para login no Docker Registry
Login no OCIR:
```bash
docker login <region-key>.ocir.io
```
Exemplo para São Paulo:
```bash
docker login gru.ocir.io
```
O usuário normalmente segue o formato:
```text
<tenancy-namespace>/<user>
```
---
## 1. Configurar o arquivo de ambiente
Copie o exemplo:
```bash
cp deploy/oke/examples/oke.env.example deploy/oke/oke.env
```
Edite:
```bash
vi deploy/oke/oke.env
```
Campos principais:
```bash
OCI_REGION=sa-saopaulo-1
OCI_REGION_KEY=gru
OCI_TENANCY_NAMESPACE=your_tenancy_namespace
OCIR_REPOSITORY_PREFIX=agent-platform-oci
IMAGE_TAG=1.0.0
K8S_NAMESPACE=agent-platform
OKE_CLUSTER_OCID=ocid1.cluster.oc1..example
```
Para usar OCI Generative AI em vez de mock:
```bash
LLM_PROVIDER=oci_openai
OCI_GENAI_BASE_URL=https://inference.generativeai.sa-saopaulo-1.oci.oraclecloud.com/openai/v1
OCI_GENAI_MODEL=<modelo>
OCI_GENAI_API_KEY=<api-key>
OCI_COMPARTMENT_ID=<compartment-ocid>
```
Para primeiro teste sem custo de LLM, deixe:
```bash
LLM_PROVIDER=mock
```
---
## 2. Build das imagens
Execute a partir da raiz do projeto:
```bash
./deploy/oke/scripts/build_images.sh deploy/oke/oke.env
```
Imagens geradas:
```text
agent-template-backend
agent-gateway
channel-gateway
mcp-gateway
agent-frontend
```
Todas serão tagueadas no padrão:
```text
<region-key>.ocir.io/<tenancy-namespace>/<prefix>/<image>:<tag>
```
Exemplo:
```text
gru.ocir.io/mytenancy/agent-platform-oci/agent-template-backend:1.0.0
```
---
## 3. Push para OCIR
```bash
./deploy/oke/scripts/push_images.sh deploy/oke/oke.env
```
---
## 4. Criar secrets de runtime
O script abaixo cria ou atualiza o secret `agent-platform-secrets` no namespace configurado:
```bash
./deploy/oke/scripts/create_runtime_secret.sh deploy/oke/oke.env
```
O arquivo `02-secret-template.yaml` existe apenas como referência. Não coloque credenciais reais no Git.
---
## 5. Fazer deploy no OKE
```bash
./deploy/oke/scripts/deploy_oke.sh deploy/oke/oke.env
```
O script:
1. Opcionalmente atualiza o kubeconfig via OCI CLI, se `OKE_CLUSTER_OCID` estiver preenchido.
2. Cria/atualiza o namespace.
3. Cria/atualiza os secrets.
4. Aplica os manifests com Kustomize.
5. Aguarda o rollout dos deployments.
6. Lista os serviços e IPs externos.
---
## 6. Verificar status
```bash
./deploy/oke/scripts/status.sh
```
Ou manualmente:
```bash
kubectl -n agent-platform get pods -o wide
kubectl -n agent-platform get svc
kubectl -n agent-platform get hpa
```
Quando o Load Balancer estiver provisionado, os serviços externos aparecerão com `EXTERNAL-IP`:
```bash
kubectl -n agent-platform get svc agent-gateway
kubectl -n agent-platform get svc channel-gateway
kubectl -n agent-platform get svc mcp-gateway
kubectl -n agent-platform get svc agent-frontend
```
---
## 7. Testes rápidos
Health do backend interno:
```bash
kubectl -n agent-platform port-forward svc/agent-template-backend 8000:8000
curl http://localhost:8000/health
```
Health do Agent Gateway:
```bash
kubectl -n agent-platform port-forward svc/agent-gateway 8010:8010
curl http://localhost:8010/health
```
Envio de mensagem pelo Agent Gateway:
```bash
curl -X POST http://localhost:8010/gateway/message \
-H 'Content-Type: application/json' \
-d '{
"channel": "web",
"tenant_id": "default",
"payload": {
"message": "quero consultar minha fatura",
"metadata": {
"customer_key": "11999999999"
}
}
}'
```
---
## Escalabilidade
O `agent_template_backend` foi configurado com:
```yaml
replicas: 3
```
E com HPA:
```yaml
minReplicas: 3
maxReplicas: 10
averageUtilization: 70
```
Ajuste em:
```text
deploy/oke/k8s/base/03-agent-template-backend.yaml
```
O Load Balancer externo fica nos gateways e no frontend. O backend do agente é `ClusterIP`, porque o acesso deve ocorrer via gateway.
---
## Sobre estado, sessão e persistência
O manifesto usa `emptyDir` para `/data`, suficiente para smoke test e validação inicial.
Para produção, substitua SQLite por um provider externo:
- Autonomous Database
- MongoDB
- Redis para cache distribuído
- Object Storage ou banco para artefatos persistentes
Não use SQLite local com múltiplos pods em produção para sessão, memória, checkpoints e usage, porque cada pod teria seu próprio estado.
Configurações relevantes no `ConfigMap`:
```yaml
SESSION_REPOSITORY_PROVIDER: "sqlite"
MEMORY_REPOSITORY_PROVIDER: "sqlite"
CHECKPOINT_REPOSITORY_PROVIDER: "sqlite"
USAGE_REPOSITORY_PROVIDER: "sqlite"
```
Para produção, altere esses providers e injete as credenciais por `Secret`.
---
## Ajuste do Agent Gateway para vários agentes
O arquivo:
```text
deploy/oke/k8s/base/01-configmap.yaml
```
cria o `ConfigMap` `agent-gateway-backends` com:
```yaml
backends:
contas:
url: http://agent-template-backend.agent-platform.svc.cluster.local:8000
```
Para adicionar novos agentes, crie novos deployments e serviços, depois adicione novas entradas:
```yaml
backends:
contas:
url: http://agent-contas.agent-platform.svc.cluster.local:8000
ofertas:
url: http://agent-ofertas.agent-platform.svc.cluster.local:8000
suporte:
url: http://agent-suporte.agent-platform.svc.cluster.local:8000
```
---
## Ajuste do MCP Gateway
O `mcp_gateway` é implantado com configuração vazia por padrão:
```yaml
servers: {}
tools: {}
```
Edite o `ConfigMap` `mcp-gateway-config` em:
```text
deploy/oke/k8s/base/01-configmap.yaml
```
Exemplo:
```yaml
servers:
telecom:
enabled: true
discover: true
protocol: legacy_http
transport: http
url: http://telecom-mcp.agent-platform.svc.cluster.local:8100/mcp
timeout_seconds: 30
```
---
## Frontend
O frontend foi empacotado em Nginx e exposto com `Service LoadBalancer`.
Como o frontend atual é estático, o endereço do gateway pode ser informado na própria interface, caso ela já tenha campo de backend/gateway. Caso você queira fixar o endpoint em build/runtime, o próximo ajuste recomendado é adicionar um arquivo `/config.js` gerado por `ConfigMap` com a URL pública do `agent_gateway`.
---
## Segurança recomendada para produção
Para produção, recomenda-se:
1. Usar `ClusterIP` para `mcp_gateway` e expor apenas via rede privada.
2. Usar OCI API Gateway ou Ingress Controller com TLS.
3. Criar `NetworkPolicy` restringindo tráfego entre namespaces.
4. Usar OCI Vault/External Secrets para credenciais.
5. Usar Workload Identity ou Instance Principal quando aplicável.
6. Usar Autonomous Database ou MongoDB externo para estado.
7. Configurar observabilidade com OTel/Langfuse.
8. Separar namespaces por ambiente: `dev`, `test`, `prod`.
9. Não versionar `.env` nem secrets reais.
---
## Comandos principais
```bash
cp deploy/oke/examples/oke.env.example deploy/oke/oke.env
vi deploy/oke/oke.env
./deploy/oke/scripts/build_images.sh deploy/oke/oke.env
./deploy/oke/scripts/push_images.sh deploy/oke/oke.env
./deploy/oke/scripts/deploy_oke.sh deploy/oke/oke.env
./deploy/oke/scripts/status.sh
```
---
## Próximos passos recomendados
1. Criar manifests separados por ambiente com overlays Kustomize: `dev`, `hml`, `prod`.
2. Criar pipeline OCI DevOps ou GitHub Actions para build/push/deploy.
3. Adicionar Ingress/API Gateway com TLS.
4. Migrar estado de SQLite para Autonomous/MongoDB antes de produção.
5. Criar manifests específicos para cada agente real derivado do `agent_template_backend`.

View File

@@ -0,0 +1,4 @@
FROM nginx:1.27-alpine
COPY deploy/oke/nginx/default.conf /etc/nginx/conf.d/default.conf
COPY apps/agent_frontend /usr/share/nginx/html
EXPOSE 8080

View File

@@ -0,0 +1,23 @@
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
PYTHONPATH=/app
WORKDIR /app
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl \
&& rm -rf /var/lib/apt/lists/*
COPY libs/agent_framework /opt/agent_framework
COPY apps/agent_gateway/requirements.txt /tmp/requirements.txt
RUN pip install --upgrade pip \
&& pip install -e /opt/agent_framework \
&& pip install -r /tmp/requirements.txt
COPY apps/agent_gateway /app
EXPOSE 8010
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8010"]

View File

@@ -0,0 +1,23 @@
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
PYTHONPATH=/app
WORKDIR /app
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl \
&& rm -rf /var/lib/apt/lists/*
COPY libs/agent_framework /opt/agent_framework
COPY templates/agent_template_backend/requirements.txt /tmp/requirements.txt
RUN pip install --upgrade pip \
&& pip install -e /opt/agent_framework \
&& pip install -r /tmp/requirements.txt
COPY templates/agent_template_backend /app
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

View File

@@ -0,0 +1,21 @@
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
PYTHONPATH=/app
WORKDIR /app
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl \
&& rm -rf /var/lib/apt/lists/*
COPY apps/channel_gateway/requirements.txt /tmp/requirements.txt
RUN pip install --upgrade pip \
&& pip install -r /tmp/requirements.txt
COPY apps/channel_gateway /app
EXPOSE 7000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7000"]

View File

@@ -0,0 +1,22 @@
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
PYTHONPATH=/app \
MCP_GATEWAY_CONFIG_PATH=/app/config/mcp_gateway.yaml
WORKDIR /app
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl \
&& rm -rf /var/lib/apt/lists/*
COPY apps/mcp_gateway/requirements.txt /tmp/requirements.txt
RUN pip install --upgrade pip \
&& pip install -r /tmp/requirements.txt
COPY apps/mcp_gateway /app
EXPOSE 8300
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8300"]

View File

@@ -0,0 +1,25 @@
# OCI / OKE / OCIR
OCI_REGION=sa-saopaulo-1
OCI_REGION_KEY=gru
OCI_TENANCY_NAMESPACE=your_tenancy_namespace
OCIR_REPOSITORY_PREFIX=agent-platform-oci
IMAGE_TAG=1.0.0
# Kubernetes
K8S_NAMESPACE=agent-platform
OKE_CLUSTER_OCID=ocid1.cluster.oc1..example
# Optional: configure kubeconfig automatically with OCI CLI
OCI_CLI_PROFILE=DEFAULT
# Runtime config
LLM_PROVIDER=oci_openai
OCI_GENAI_BASE_URL=https://inference.generativeai.sa-saopaulo-1.oci.oraclecloud.com/openai/v1
OCI_GENAI_MODEL=cohere.command-r-plus
OCI_GENAI_API_KEY=replace-me
OCI_GENAI_PROJECT_OCID=
OCI_COMPARTMENT_ID=ocid1.compartment.oc1..example
LANGFUSE_HOST=
LANGFUSE_PUBLIC_KEY=
LANGFUSE_SECRET_KEY=
MCP_GATEWAY_TOKEN=

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: agent-platform

View File

@@ -0,0 +1,91 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: agent-platform-config
namespace: agent-platform
data:
APP_ENV: "oke"
LOG_LEVEL: "INFO"
CORS_ORIGINS: "*"
LLM_PROVIDER: "mock"
LLM_TEMPERATURE: "0.2"
LLM_MAX_TOKENS: "2048"
SESSION_REPOSITORY_PROVIDER: "sqlite"
MEMORY_REPOSITORY_PROVIDER: "sqlite"
CHECKPOINT_REPOSITORY_PROVIDER: "sqlite"
SQLITE_DB_PATH: "/data/agent_framework.db"
USAGE_REPOSITORY_PROVIDER: "sqlite"
VECTOR_STORE_PROVIDER: "sqlite"
GRAPH_STORE_PROVIDER: "sqlite"
EMBEDDING_PROVIDER: "mock"
ENABLE_LANGFUSE: "false"
ENABLE_OTEL: "false"
ENABLE_ANALYTICS: "false"
ENABLE_INPUT_GUARDRAILS: "true"
ENABLE_OUTPUT_GUARDRAILS: "true"
ENABLE_JUDGES: "true"
ENABLE_SUPERVISOR: "true"
ENABLE_OUTPUT_SUPERVISOR: "true"
ENABLE_PARALLEL_GUARDRAILS: "true"
FRAMEWORK_CHANNEL_INPUT_MODE: "embedded"
ENABLE_MCP_TOOLS: "true"
MCP_GATEWAY_ENABLED: "true"
MCP_GATEWAY_URL: "http://mcp-gateway.agent-platform.svc.cluster.local:8300"
AGENTS_CONFIG_PATH: "./config/agents.yaml"
ROUTING_CONFIG_PATH: "./config/routing.yaml"
GUARDRAILS_CONFIG_PATH: "./config/guardrails.yaml"
JUDGES_CONFIG_PATH: "./config/judges.yaml"
PROMPT_POLICY_PATH: "./config/prompt_policy.yaml"
IDENTITY_CONFIG_PATH: "./config/identity.yaml"
MCP_PARAMETER_MAPPING_PATH: "./config/mcp_parameter_mapping.yaml"
BACKENDS_CONFIG_PATH: "/app/config/backends.yaml"
CHANNEL_GATEWAY_RUNTIME_MODE: "proxy"
DEFAULT_AGENT_BACKEND_URL: "http://agent-template-backend.agent-platform.svc.cluster.local:8000"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: agent-gateway-backends
namespace: agent-platform
data:
backends.yaml: |
default_backend: contas
backends:
contas:
url: http://agent-template-backend.agent-platform.svc.cluster.local:8000
description: Backend principal do template de agentes.
domains: [contas, fatura, pagamento, consumo, contestacao]
keywords: [fatura, conta, boleto, pagamento, consumo, segunda via, contestar, contestação, valor, cobrança]
examples:
- Quero consultar minha fatura
- Minha conta veio alta
priority: 10
default_agent_id: telecom_contas
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mcp-gateway-config
namespace: agent-platform
data:
mcp_gateway.yaml: |
discovery:
enabled: true
sync_on_startup: true
timeout_seconds: 10
default_catalog_endpoints: [/.well-known/mcp-server.json, /manifest, /mcp/tools, /tools/list, /tools, /v1/tools]
tool_defaults:
version: 1.0.0
protocol: legacy_http
enabled: true
idempotent: true
cache_ttl_seconds: 300
timeout_seconds: 30
retry: {enabled: true, max_attempts: 2, backoff_ms: 250}
allowed_agents: []
allowed_channels: []
required_business_keys: []
servers: {}
tools: {}
mcp_servers.yaml: |
servers: {}

View File

@@ -0,0 +1,17 @@
apiVersion: v1
kind: Secret
metadata:
name: agent-platform-secrets
namespace: agent-platform
type: Opaque
stringData:
OCI_GENAI_BASE_URL: ""
OCI_GENAI_API_KEY: ""
OCI_GENAI_MODEL: ""
OCI_GENAI_PROJECT_OCID: ""
OCI_COMPARTMENT_ID: ""
OCI_REGION: ""
LANGFUSE_PUBLIC_KEY: ""
LANGFUSE_SECRET_KEY: ""
LANGFUSE_HOST: ""
MCP_GATEWAY_TOKEN: ""

View File

@@ -0,0 +1,72 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: agent-template-backend
namespace: agent-platform
spec:
replicas: 3
selector:
matchLabels: {app: agent-template-backend}
template:
metadata:
labels: {app: agent-template-backend}
spec:
containers:
- name: agent-template-backend
image: agent-template-backend:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8000
envFrom:
- configMapRef: {name: agent-platform-config}
- secretRef: {name: agent-platform-secrets}
readinessProbe:
httpGet: {path: /health, port: 8000}
initialDelaySeconds: 20
periodSeconds: 10
livenessProbe:
httpGet: {path: /health, port: 8000}
initialDelaySeconds: 40
periodSeconds: 20
resources:
requests: {cpu: "250m", memory: "512Mi"}
limits: {cpu: "1000m", memory: "1Gi"}
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: agent-template-backend
namespace: agent-platform
spec:
type: ClusterIP
selector: {app: agent-template-backend}
ports:
- name: http
port: 8000
targetPort: 8000
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: agent-template-backend
namespace: agent-platform
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: agent-template-backend
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70

View File

@@ -0,0 +1,57 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: agent-gateway
namespace: agent-platform
spec:
replicas: 2
selector:
matchLabels: {app: agent-gateway}
template:
metadata:
labels: {app: agent-gateway}
spec:
containers:
- name: agent-gateway
image: agent-gateway:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8010
envFrom:
- configMapRef: {name: agent-platform-config}
- secretRef: {name: agent-platform-secrets}
volumeMounts:
- name: backends
mountPath: /app/config/backends.yaml
subPath: backends.yaml
readinessProbe:
httpGet: {path: /health, port: 8010}
initialDelaySeconds: 15
periodSeconds: 10
livenessProbe:
httpGet: {path: /health, port: 8010}
initialDelaySeconds: 30
periodSeconds: 20
resources:
requests: {cpu: "200m", memory: "256Mi"}
limits: {cpu: "1000m", memory: "768Mi"}
volumes:
- name: backends
configMap: {name: agent-gateway-backends}
---
apiVersion: v1
kind: Service
metadata:
name: agent-gateway
namespace: agent-platform
annotations:
service.beta.kubernetes.io/oci-load-balancer-shape: "flexible"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: "10"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: "100"
spec:
type: LoadBalancer
selector: {app: agent-gateway}
ports:
- name: http
port: 80
targetPort: 8010

View File

@@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: channel-gateway
namespace: agent-platform
spec:
replicas: 2
selector:
matchLabels: {app: channel-gateway}
template:
metadata:
labels: {app: channel-gateway}
spec:
containers:
- name: channel-gateway
image: channel-gateway:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 7000
envFrom:
- configMapRef: {name: agent-platform-config}
readinessProbe:
httpGet: {path: /health, port: 7000}
initialDelaySeconds: 15
periodSeconds: 10
livenessProbe:
httpGet: {path: /health, port: 7000}
initialDelaySeconds: 30
periodSeconds: 20
resources:
requests: {cpu: "100m", memory: "128Mi"}
limits: {cpu: "500m", memory: "512Mi"}
---
apiVersion: v1
kind: Service
metadata:
name: channel-gateway
namespace: agent-platform
annotations:
service.beta.kubernetes.io/oci-load-balancer-shape: "flexible"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: "10"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: "100"
spec:
type: LoadBalancer
selector: {app: channel-gateway}
ports:
- name: http
port: 80
targetPort: 7000

View File

@@ -0,0 +1,62 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mcp-gateway
namespace: agent-platform
spec:
replicas: 2
selector:
matchLabels: {app: mcp-gateway}
template:
metadata:
labels: {app: mcp-gateway}
spec:
containers:
- name: mcp-gateway
image: mcp-gateway:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8300
envFrom:
- secretRef: {name: agent-platform-secrets}
env:
- name: MCP_GATEWAY_CONFIG_PATH
value: /app/config/mcp_gateway.yaml
volumeMounts:
- name: config
mountPath: /app/config/mcp_gateway.yaml
subPath: mcp_gateway.yaml
- name: config
mountPath: /app/config/mcp_servers.yaml
subPath: mcp_servers.yaml
readinessProbe:
httpGet: {path: /health, port: 8300}
initialDelaySeconds: 15
periodSeconds: 10
livenessProbe:
httpGet: {path: /health, port: 8300}
initialDelaySeconds: 30
periodSeconds: 20
resources:
requests: {cpu: "100m", memory: "128Mi"}
limits: {cpu: "500m", memory: "512Mi"}
volumes:
- name: config
configMap: {name: mcp-gateway-config}
---
apiVersion: v1
kind: Service
metadata:
name: mcp-gateway
namespace: agent-platform
annotations:
service.beta.kubernetes.io/oci-load-balancer-shape: "flexible"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: "10"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: "100"
spec:
type: LoadBalancer
selector: {app: mcp-gateway}
ports:
- name: http
port: 80
targetPort: 8300

View File

@@ -0,0 +1,47 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: agent-frontend
namespace: agent-platform
spec:
replicas: 2
selector:
matchLabels: {app: agent-frontend}
template:
metadata:
labels: {app: agent-frontend}
spec:
containers:
- name: agent-frontend
image: agent-frontend:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
readinessProbe:
httpGet: {path: /health, port: 8080}
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet: {path: /health, port: 8080}
initialDelaySeconds: 15
periodSeconds: 20
resources:
requests: {cpu: "50m", memory: "64Mi"}
limits: {cpu: "250m", memory: "256Mi"}
---
apiVersion: v1
kind: Service
metadata:
name: agent-frontend
namespace: agent-platform
annotations:
service.beta.kubernetes.io/oci-load-balancer-shape: "flexible"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: "10"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: "100"
spec:
type: LoadBalancer
selector: {app: agent-frontend}
ports:
- name: http
port: 80
targetPort: 8080

View File

@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- 00-namespace.yaml
- 01-configmap.yaml
- 02-secret-template.yaml
- 03-agent-template-backend.yaml
- 04-agent-gateway.yaml
- 05-channel-gateway.yaml
- 06-mcp-gateway.yaml
- 07-frontend.yaml

View File

@@ -0,0 +1,16 @@
server {
listen 8080;
server_name _;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /health {
access_log off;
return 200 "ok\n";
}
}

View File

@@ -0,0 +1,35 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
ENV_FILE="${1:-$ROOT_DIR/deploy/oke/examples/oke.env.example}"
if [[ -f "$ENV_FILE" ]]; then
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
fi
: "${OCI_REGION_KEY:?Set OCI_REGION_KEY, for example gru, iad, phx}"
: "${OCI_TENANCY_NAMESPACE:?Set OCI_TENANCY_NAMESPACE}"
: "${OCIR_REPOSITORY_PREFIX:=agent-platform-oci}"
: "${IMAGE_TAG:=latest}"
REGISTRY="${OCI_REGION_KEY}.ocir.io/${OCI_TENANCY_NAMESPACE}/${OCIR_REPOSITORY_PREFIX}"
echo "Building images with root context: $ROOT_DIR"
echo "Registry prefix: $REGISTRY"
docker build -f "$ROOT_DIR/deploy/oke/dockerfiles/Dockerfile.agent-template-backend" -t "$REGISTRY/agent-template-backend:$IMAGE_TAG" "$ROOT_DIR"
docker build -f "$ROOT_DIR/deploy/oke/dockerfiles/Dockerfile.agent-gateway" -t "$REGISTRY/agent-gateway:$IMAGE_TAG" "$ROOT_DIR"
docker build -f "$ROOT_DIR/deploy/oke/dockerfiles/Dockerfile.channel-gateway" -t "$REGISTRY/channel-gateway:$IMAGE_TAG" "$ROOT_DIR"
docker build -f "$ROOT_DIR/deploy/oke/dockerfiles/Dockerfile.mcp-gateway" -t "$REGISTRY/mcp-gateway:$IMAGE_TAG" "$ROOT_DIR"
docker build -f "$ROOT_DIR/deploy/oke/dockerfiles/Dockerfile.agent-frontend" -t "$REGISTRY/agent-frontend:$IMAGE_TAG" "$ROOT_DIR"
echo "Images built:"
echo "$REGISTRY/agent-template-backend:$IMAGE_TAG"
echo "$REGISTRY/agent-gateway:$IMAGE_TAG"
echo "$REGISTRY/channel-gateway:$IMAGE_TAG"
echo "$REGISTRY/mcp-gateway:$IMAGE_TAG"
echo "$REGISTRY/agent-frontend:$IMAGE_TAG"

View File

@@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
ENV_FILE="${1:-$ROOT_DIR/deploy/oke/examples/oke.env.example}"
if [[ -f "$ENV_FILE" ]]; then
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
fi
NS="${K8S_NAMESPACE:-agent-platform}"
kubectl create namespace "$NS" --dry-run=client -o yaml | kubectl apply -f -
kubectl -n "$NS" create secret generic agent-platform-secrets \
--from-literal=OCI_GENAI_BASE_URL="${OCI_GENAI_BASE_URL:-}" \
--from-literal=OCI_GENAI_API_KEY="${OCI_GENAI_API_KEY:-}" \
--from-literal=OCI_GENAI_MODEL="${OCI_GENAI_MODEL:-}" \
--from-literal=OCI_GENAI_PROJECT_OCID="${OCI_GENAI_PROJECT_OCID:-}" \
--from-literal=OCI_COMPARTMENT_ID="${OCI_COMPARTMENT_ID:-}" \
--from-literal=OCI_REGION="${OCI_REGION:-}" \
--from-literal=LANGFUSE_PUBLIC_KEY="${LANGFUSE_PUBLIC_KEY:-}" \
--from-literal=LANGFUSE_SECRET_KEY="${LANGFUSE_SECRET_KEY:-}" \
--from-literal=LANGFUSE_HOST="${LANGFUSE_HOST:-}" \
--from-literal=MCP_GATEWAY_TOKEN="${MCP_GATEWAY_TOKEN:-}" \
--dry-run=client -o yaml | kubectl apply -f -

View File

@@ -0,0 +1,75 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
ENV_FILE="${1:-$ROOT_DIR/deploy/oke/examples/oke.env.example}"
if [[ -f "$ENV_FILE" ]]; then
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
fi
: "${OCI_REGION_KEY:?Set OCI_REGION_KEY}"
: "${OCI_TENANCY_NAMESPACE:?Set OCI_TENANCY_NAMESPACE}"
: "${OCIR_REPOSITORY_PREFIX:=agent-platform-oci}"
: "${IMAGE_TAG:=latest}"
NS="${K8S_NAMESPACE:-agent-platform}"
REGISTRY="${OCI_REGION_KEY}.ocir.io/${OCI_TENANCY_NAMESPACE}/${OCIR_REPOSITORY_PREFIX}"
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT
if [[ -n "${OKE_CLUSTER_OCID:-}" && -n "${OCI_REGION:-}" ]]; then
echo "Updating kubeconfig for OKE cluster $OKE_CLUSTER_OCID"
oci ce cluster create-kubeconfig \
--cluster-id "$OKE_CLUSTER_OCID" \
--file "$HOME/.kube/config" \
--region "$OCI_REGION" \
--token-version 2.0.0 \
--kube-endpoint PUBLIC_ENDPOINT \
${OCI_CLI_PROFILE:+--profile "$OCI_CLI_PROFILE"} || true
fi
"$ROOT_DIR/deploy/oke/scripts/create_runtime_secret.sh" "$ENV_FILE"
cp -R "$ROOT_DIR/deploy/oke/k8s/base"/* "$TMP_DIR/"
cat > "$TMP_DIR/kustomization.yaml" <<EOF2
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- 00-namespace.yaml
- 01-configmap.yaml
- 03-agent-template-backend.yaml
- 04-agent-gateway.yaml
- 05-channel-gateway.yaml
- 06-mcp-gateway.yaml
- 07-frontend.yaml
images:
- name: agent-template-backend
newName: $REGISTRY/agent-template-backend
newTag: $IMAGE_TAG
- name: agent-gateway
newName: $REGISTRY/agent-gateway
newTag: $IMAGE_TAG
- name: channel-gateway
newName: $REGISTRY/channel-gateway
newTag: $IMAGE_TAG
- name: mcp-gateway
newName: $REGISTRY/mcp-gateway
newTag: $IMAGE_TAG
- name: agent-frontend
newName: $REGISTRY/agent-frontend
newTag: $IMAGE_TAG
EOF2
kubectl apply -k "$TMP_DIR"
kubectl -n "$NS" rollout status deploy/agent-template-backend --timeout=180s
kubectl -n "$NS" rollout status deploy/agent-gateway --timeout=180s
kubectl -n "$NS" rollout status deploy/channel-gateway --timeout=180s
kubectl -n "$NS" rollout status deploy/mcp-gateway --timeout=180s
kubectl -n "$NS" rollout status deploy/agent-frontend --timeout=180s
kubectl -n "$NS" get svc

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
ENV_FILE="${1:-$ROOT_DIR/deploy/oke/examples/oke.env.example}"
if [[ -f "$ENV_FILE" ]]; then
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
fi
: "${OCI_REGION_KEY:?Set OCI_REGION_KEY}"
: "${OCI_TENANCY_NAMESPACE:?Set OCI_TENANCY_NAMESPACE}"
: "${OCIR_REPOSITORY_PREFIX:=agent-platform-oci}"
: "${IMAGE_TAG:=latest}"
REGISTRY="${OCI_REGION_KEY}.ocir.io/${OCI_TENANCY_NAMESPACE}/${OCIR_REPOSITORY_PREFIX}"
for image in agent-template-backend agent-gateway channel-gateway mcp-gateway agent-frontend; do
docker push "$REGISTRY/$image:$IMAGE_TAG"
done

View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -euo pipefail
NS="${K8S_NAMESPACE:-agent-platform}"
kubectl -n "$NS" get pods -o wide
kubectl -n "$NS" get hpa
kubectl -n "$NS" get svc