Skip to content

Commit

Permalink
Add ai-agent and success helm chart (#89)
Browse files Browse the repository at this point in the history
* Add ai-agent helm chart

* lint: library and spacer

* chore: fix ai-agent

* chore: ai config

* line: ai agent

* fix: jupyter test

* fix: test

* fix: test

* fix: test

* fix: test

* fix: test

* chore: add success

* Update charts/datalayer-success/tests/deployment_test.yaml

Co-authored-by: Frédéric Collonval <[email protected]>

---------

Co-authored-by: Frédéric Collonval <[email protected]>
Co-authored-by: Eric Charles <[email protected]>
  • Loading branch information
3 people authored Jan 20, 2025
1 parent 6ad82f0 commit 3b6cb0b
Show file tree
Hide file tree
Showing 28 changed files with 843 additions and 5 deletions.
13 changes: 13 additions & 0 deletions charts/datalayer-ai-agent/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: v1
description: Datalayer AI Agent
name: datalayer-ai-agent
version: 0.0.1
appVersion: 0.0.1
home: https://datalayer.tech
sources:
- https://github.com/datalayer/helm-charts/tree/main/charts/datalayer-ai-agent
icon: https://assets.datalayer.tech/datalayer-square.png
maintainers:
- name: Datalayer
email: [email protected]
url: https://datalayer.io
35 changes: 35 additions & 0 deletions charts/datalayer-ai-agent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[![Datalayer](https://assets.datalayer.tech/datalayer-25.svg)](https://datalayer.io)

# datalayer-ai-agent

Datalayer AI Agent

![Version: 0.0.1](https://img.shields.io/badge/Version-0.0.1-informational?style=flat-square) ![AppVersion: 0.0.1](https://img.shields.io/badge/AppVersion-0.0.1-informational?style=flat-square)

## Documentation

For full documentation please checkout [Datalayer Tech](https://datalayer.tech).

## Values

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| ai-agent.env.DATALAYER_AUTHZ_ENGINE | string | `""` | |
| ai-agent.env.DATALAYER_CDN_URL | string | `""` | |
| ai-agent.env.DATALAYER_JWT_ALGORITHM | string | `""` | |
| ai-agent.env.DATALAYER_JWT_CACHE_VALIDATE | string | `"false"` | |
| ai-agent.env.DATALAYER_JWT_ISSUER | string | `""` | |
| ai-agent.env.DATALAYER_JWT_SECRET | string | `""` | |
| ai-agent.env.DATALAYER_OPENFGA_AUTHZ_MODEL_ID | string | `""` | |
| ai-agent.env.DATALAYER_OPENFGA_REST_URL | string | `"http://datalayer-openfga.datalayer-openfga.svc.cluster.local:8080"` | |
| ai-agent.env.DATALAYER_OPENFGA_STORE_ID | string | `""` | |
| ai-agent.env.DATALAYER_RUNTIME_ENV | string | `"prod"` | |
| ai-agent.env.DATALAYER_RUN_URL | string | `""` | |
| ai-agent.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | string | `""` | |
| ai-agent.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT | string | `""` | |
| ai-agent.env.OTEL_SDK_DISABLED | string | `"false"` | |
| ai-agent.image | string | `"datalayer/ai-agent:0.0.1"` | |
| ai-agent.imagePullPolicy | string | `"Always"` | |
| ai-agent.port | int | `4400` | |
| ai-agent.sidecar.image | string | `"datalayer/whoami:0.0.6"` | |

16 changes: 16 additions & 0 deletions charts/datalayer-ai-agent/README.md.gotmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[![Datalayer](https://assets.datalayer.tech/datalayer-25.svg)](https://datalayer.io)

{{ template "chart.header" . }}
{{ template "chart.description" . }}

{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }}

## Documentation

For full documentation please checkout [Datalayer Tech](https://datalayer.tech).

{{ template "chart.requirementsSection" . }}

{{ template "chart.valuesSection" . }}

{{ template "helm-docs.versionFooter" . }}
25 changes: 25 additions & 0 deletions charts/datalayer-ai-agent/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Your aiagent server has now been installed, and can be accessed in the following ways:

1. Connect to the aiagent CLI pod:

kubectl exec -n {{ .Release.Namespace }} $(kubectl get pod -n {{ .Release.Namespace }} --selector=app={{ template "aiagent.name" . }} -o jsonpath='{.items...metadata.name}') -- sh

2. Connect with HTTP internally, within the kubernetes cluster on:

{{ template "aiagent.service-name" . }}.{{ .Release.Namespace }}:{{ .Values.aiagent.port }}

3. Connect with HTTP Node Port to the kubernetes cluster:

export NODE_IP=$(kubectl get nodes --namespace aiagent -o jsonpath="{.items[0].status.addresses[0].address}")
export NODE_PORT=$(kubectl get --namespace aiagent -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "aiagent.service-name" . }})
echo http://$NODE_IP:$NODE_PORT/aiagent/

4. Connect with HTTP external service to the kubernetes cluster:

export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "aiagent.name" . }}" -o jsonpath="{ .items[0].metadata.name }")
echo "Visit http://127.0.0.1:{{ .Values.aiagent.port }}/aiagent/ to access aiagent"
kubectl port-forward --namespace {{ .Release.Namespace }} $POD_NAME {{ .Values.aiagent.port }}:{{ .Values.aiagent.port }}

5. For Minikube:

open http://minikube.local/api/ai-agent
36 changes: 36 additions & 0 deletions charts/datalayer-ai-agent/templates/_helpers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "aiagent.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 24 | trimSuffix "-" -}}
{{- end -}}

{{/*
Create a default fully qualified app name.
We truncate at 24 chars because some kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "aiagent.fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 24 | trimSuffix "-" -}}
{{- end -}}

{{/*
Define the name of the client service for aiagent.
*/}}
{{- define "aiagent.service-name" -}}
{{- printf "%s-%s" (include "aiagent.fullname" .) "svc" | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Define the value for the app label.
*/}}
{{- define "aiagent.app-name" -}}
{{- printf "%s" .Chart.Name | replace "datalayer-" "" -}}
{{- end -}}

{{/*
Define the value for the datalayer run host.
*/}}
{{- define "aiagent.runHost" -}}
{{- printf "%s" .Values.aiagent.env.DATALAYER_RUN_URL | replace "https://" "" -}}
{{- end -}}
65 changes: 65 additions & 0 deletions charts/datalayer-ai-agent/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
namespace: {{ .Values.namespace }}
labels:
app: {{ template "aiagent.app-name" . }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ template "aiagent.app-name" . }}
strategy:
rollingUpdate:
maxUnavailable: 0
template:
metadata:
labels:
app: {{ template "aiagent.app-name" . }}
release: {{ .Release.Name }}
datalayer.io/app: {{ template "aiagent.app-name" . }}
annotations:
karpenter.sh/do-not-disrupt: "true"
spec:
terminationGracePeriodSeconds: 0
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: role.datalayer.io/api
operator: In
values:
- "true"
imagePullSecrets:
- name: reg-creds
containers:
- name: ai-agent
image: {{ .Values.aiagent.image }}
imagePullPolicy: {{ .Values.aiagent.imagePullPolicy }}
ports:
- containerPort: {{ .Values.aiagent.port }}
protocol: TCP
{{- if or .Values.aiagent.env .Values.aiagent.envValueFrom }}
env:
{{- range $key, $value := .Values.aiagent.envValueFrom }}
- name: {{ $key }}
valueFrom: {{- $value | toYaml | nindent 16 }}
{{- end }}
{{- range $key, $value := .Values.aiagent.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- end }}
readinessProbe:
httpGet:
path: /api/ai-agent/version
port: 4400
successThreshold: 1
failureThreshold: 5
initialDelaySeconds: 5
periodSeconds: 15
volumeMounts:
resources:
{{ toYaml .Values.aiagent.resources | indent 12 }}
49 changes: 49 additions & 0 deletions charts/datalayer-ai-agent/templates/ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ai-agent-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: 'true'
nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'
nginx.ingress.kubernetes.io/affinity: cookie
nginx.ingress.kubernetes.io/affinity-mode: persistent
nginx.ingress.kubernetes.io/session-cookie-expires: '172800'
nginx.ingress.kubernetes.io/session-cookie-max-age: '172800'
nginx.ingress.kubernetes.io/session-cookie-samesite: None
nginx.ingress.kubernetes.io/session-cookie-name: ai-agent-affinity
nginx.ingress.kubernetes.io/enable-modsecurity: 'true'
nginx.ingress.kubernetes.io/enable-owasp-core-rules: 'true'
nginx.ingress.kubernetes.io/proxy-body-size: '0'
nginx.ingress.kubernetes.io/proxy-read-timeout: '600'
nginx.ingress.kubernetes.io/proxy-send-timeout: '600'
# FIXME what is the best way to parametrize this - full url or composition?
# nginx.ingress.kubernetes.io/auth-url: 'http://datalayer-iam-svc.{{ .Release.Namespace }}.svc.cluster.local:9700/api/iam/v1/auth'
# nginx.ingress.kubernetes.io/auth-snippet: |
# proxy_set_header X-Forwarded-Method $request_method;
# proxy_set_header X-Forwarded-Proto $scheme;
# proxy_set_header X-Forwarded-Host $host;
# proxy_set_header X-Forwarded-Uri $scheme://$host$request_uri;
cert-manager.io/acme-challenge-type: http01
cert-manager.io/cluster-issuer: letsencrypt
acme.cert-manager.io/http01-ingress-class: datalayer-traefik
traefik.ingress.kubernetes.io/router.tls: 'true'
# traefik.ingress.kubernetes.io/router.middlewares: {{ .Release.Namespace }}-iam-auth@kubernetescrd
labels:
app: ai-agent
spec:
ingressClassName: datalayer-traefik
tls:
- hosts:
- {{ template "aiagent.runHost" . }}
secretName: {{ template "aiagent.runHost" . }}-datalayer-api-cert-secret
rules:
- host: {{ template "aiagent.runHost" . }}
http:
paths:
- path: /api/ai-agent
pathType: Prefix
backend:
service:
name: {{ .Release.Name }}-svc
port:
number: {{ .Values.aiagent.port }}
26 changes: 26 additions & 0 deletions charts/datalayer-ai-agent/templates/svc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-svc
labels:
app: {{ template "aiagent.app-name" . }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
annotations:
# Trick for CORS bug in starlette middleware
traefik.ingress.kubernetes.io/service.sticky.cookie: "true"
traefik.ingress.kubernetes.io/service.sticky.cookie.httponly: "false"
traefik.ingress.kubernetes.io/service.sticky.cookie.secure: "true"
traefik.ingress.kubernetes.io/service.sticky.cookie.samesite: "none"
spec:
type: ClusterIP
ports:
- port: {{ .Values.aiagent.port }}
name: ai-agent-http
protocol: TCP
targetPort: {{ .Values.aiagent.port }}
selector:
app: {{ template "aiagent.app-name" . }}
release: {{ .Release.Name }}
# externalTrafficPolicy: Local # Important?!
Empty file.
28 changes: 28 additions & 0 deletions charts/datalayer-ai-agent/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
aiagent:
image: datalayer/ai-agent:0.0.1
sidecar:
image: datalayer/whoami:0.0.6
imagePullPolicy: Always
port: 4400
# resources:
# limits:
# memory: "8192Mi"
# cpu: "3000m"
env:
DATALAYER_AUTHZ_ENGINE: ""
DATALAYER_AZURE_OPENAI_API_KEY: ""
DATALAYER_AZURE_OPENAI_ENDPOINT: ""
DATALAYER_CDN_URL: ""
DATALAYER_JWT_ALGORITHM: ""
DATALAYER_JWT_CACHE_VALIDATE: "false"
DATALAYER_JWT_ISSUER: ""
DATALAYER_JWT_SECRET: ""
DATALAYER_OPENAI_API_VERSION: ""
DATALAYER_OPENFGA_AUTHZ_MODEL_ID: ""
DATALAYER_OPENFGA_REST_URL: "http://datalayer-openfga.datalayer-openfga.svc.cluster.local:8080"
DATALAYER_OPENFGA_STORE_ID: ""
DATALAYER_RUNTIME_ENV: "prod"
DATALAYER_RUN_URL: ""
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: ""
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: ""
OTEL_SDK_DISABLED: "false"
4 changes: 3 additions & 1 deletion charts/datalayer-iam/tests/deployment_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ tests:
value: ""
- name: DATALAYER_JWT_SKIP_EXTERNAL_TOKEN_SIGNATURE_VERIFICATION
value: "false"
- name: DATALAYER_KAFKA_URL
value: datalayer-kafka-kafka-bootstrap.datalayer-kafka.svc.cluster.local:9092
- name: DATALAYER_LINKEDIN_CLIENT_ID
value: ""
- name: DATALAYER_LINKEDIN_CLIENT_SECRET
Expand Down Expand Up @@ -130,7 +132,7 @@ tests:
value: ""
- name: OTEL_SDK_DISABLED
value: "false"
image: datalayer/iam:1.0.6
image: datalayer/iam:1.0.7
imagePullPolicy: Always
name: iam
ports:
Expand Down
4 changes: 3 additions & 1 deletion charts/datalayer-jupyter/tests/deployment_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ tests:
value: https://id.datalayer.run
- name: DATALAYER_JWT_SECRET
value: ""
- name: DATALAYER_KAFKA_URL
value: datalayer-kafka-kafka-bootstrap.datalayer-kafka.svc.cluster.local:9092
- name: DATALAYER_OPENFGA_AUTHZ_MODEL_ID
value: ""
- name: DATALAYER_OPENFGA_REST_URL
Expand Down Expand Up @@ -86,7 +88,7 @@ tests:
value: ""
- name: OTEL_SDK_DISABLED
value: "false"
image: datalayer/jupyter:1.0.4
image: datalayer/jupyter:1.0.5
imagePullPolicy: Always
name: jupyter
ports:
Expand Down
1 change: 0 additions & 1 deletion charts/datalayer-library/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ spec:
failureThreshold: 5
initialDelaySeconds: 5
periodSeconds: 15
volumeMounts:
resources:
{{ toYaml .Values.library.resources | indent 12 }}
# - name: library-sidecar
Expand Down
18 changes: 17 additions & 1 deletion charts/datalayer-operator/tests/deployment_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,14 @@ tests:
value: datalayer-iam-svc.datalayer-api.svc.cluster.local:9700
- name: DATALAYER_INGRESS_CLASS_NAME
value: datalayer-traefik
- name: DATALAYER_KAFKA_URL
value: datalayer-kafka-kafka-bootstrap.datalayer-kafka.svc.cluster.local:9092
- name: DATALAYER_KERNELS_RUN_HOOKS
value: "false"
- name: DATALAYER_OPERATOR_API_KEY
value: ""
- name: DATALAYER_PUB_SUB_ENGINE
value: pulsar
value: kafka
- name: DATALAYER_PULSAR_URL
value: pulsar://datalayer-pulsar-broker.datalayer-pulsar.svc.cluster.local:6650
- name: DATALAYER_RUN_URL
Expand All @@ -78,3 +80,17 @@ tests:
value: ""
- name: OTEL_SDK_DISABLED
value: "false"
image: datalayer/operator:1.0.10
imagePullPolicy: Always
name: operator
ports:
- containerPort: 2111
protocol: TCP
readinessProbe:
failureThreshold: 5
httpGet:
path: /api/operator/version
port: 2111
initialDelaySeconds: 5
periodSeconds: 15
successThreshold: 1
1 change: 0 additions & 1 deletion charts/datalayer-spacer/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ spec:
failureThreshold: 5
initialDelaySeconds: 5
periodSeconds: 15
volumeMounts:
resources:
{{ toYaml .Values.spacer.resources | indent 12 }}
# - name: spacer-sidecar
Expand Down
Loading

0 comments on commit 3b6cb0b

Please sign in to comment.