Skip to content

Commit

Permalink
Merge branch 'main' into feat/api-backend-load-model-info-590
Browse files Browse the repository at this point in the history
  • Loading branch information
jamestexas authored Aug 26, 2024
2 parents 547422c + 1a80646 commit cce96e0
Show file tree
Hide file tree
Showing 36 changed files with 673 additions and 286 deletions.
8 changes: 6 additions & 2 deletions .github/actions/uds-cluster/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@ runs:
using: composite
steps:
- name: Setup UDS Environment
uses: defenseunicorns/uds-common/.github/actions/setup@05f42bb3117b66ebef8c72ae050b34bce19385f5
uses: defenseunicorns/uds-common/.github/actions/setup@822dac4452e6815aadcf09f487406ff258756a0c # v0.14.0
with:
username: ${{ inputs.registry1Username }}
password: ${{ inputs.registry1Password }}
udsCliVersion: 0.14.0

- name: Checkout Repo
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Create UDS Cluster
shell: bash
run: |
make create-uds-cpu-cluster
UDS_CONFIG=.github/config/uds-config.yaml make create-uds-cpu-cluster
3 changes: 3 additions & 0 deletions .github/config/uds-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
variables:
core-slim-dev:
INSECURE_ADMIN_PASSWORD_GENERATION: "true"
57 changes: 57 additions & 0 deletions .github/scripts/createUser.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
KEYCLOAK_ADMIN_PASSWORD=$(uds zarf tools kubectl get secret -n keycloak keycloak-admin-password -o jsonpath={.data.password} | base64 -d)
echo "::add-mask::$KEYCLOAK_ADMIN_PASSWORD"

KEYCLOAK_ADMIN_TOKEN=$(curl --location "https://keycloak.admin.uds.dev/realms/master/protocol/openid-connect/token" \
--http1.1 \
--header "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "username=admin" \
--data-urlencode "password=${KEYCLOAK_ADMIN_PASSWORD}" \
--data-urlencode "client_id=admin-cli" \
--data-urlencode "grant_type=password" | uds zarf tools yq .access_token)
echo "::add-mask::$KEYCLOAK_ADMIN_TOKEN"


curl --location "https://keycloak.admin.uds.dev/admin/realms/uds/users" \
--http1.1 \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${KEYCLOAK_ADMIN_TOKEN}" \
--data "{
\"username\": \"doug\",
\"firstName\": \"Doug\",
\"lastName\": \"Unicorn\",
\"email\": \"[email protected]\",
\"attributes\": {
\"mattermostid\": \"1\"
},
\"emailVerified\": true,
\"enabled\": true,
\"requiredActions\": [],
\"credentials\": [
{
\"type\": \"password\",
\"value\": \"${FAKE_E2E_USER_PASSWORD}\",
\"temporary\": false
}
]
}"

CONDITIONAL_OTP_ID=$(curl --location "https://keycloak.admin.uds.dev/admin/realms/uds/authentication/flows/Authentication/executions" \
--http1.1 \
--header "Authorization: Bearer ${KEYCLOAK_ADMIN_TOKEN}" | uds zarf tools yq '.[] | select(.displayName == "Conditional OTP") | .id')

curl --location --request PUT "https://keycloak.admin.uds.dev/admin/realms/uds/authentication/flows/Authentication/executions" \
--http1.1 \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${KEYCLOAK_ADMIN_TOKEN}" \
--data "{
\"id\": \"${CONDITIONAL_OTP_ID}\",
\"requirement\": \"DISABLED\"
}"

USER=$(curl --location "https://keycloak.admin.uds.dev/admin/realms/uds/users?user=doug" \
--http1.1 \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${KEYCLOAK_ADMIN_TOKEN}" \
)

echo "User: $USER"
33 changes: 26 additions & 7 deletions .github/workflows/e2e-playwright.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ on:
- "!.github/**"
- ".github/workflows/e2e-playwright.yaml"
- ".github/actions/uds-cluster/action.yaml"
- ".github/actions/scripts/createUser.sh"
- ".github/actions/config/uds-config.yaml"

# Ignore docs and website things
- "!**.md"
Expand Down Expand Up @@ -64,20 +66,27 @@ jobs:
with:
node-version-file: 'src/leapfrogai_ui/package.json'

- name: Install UI/Playwright Dependencies
run: |
npm --prefix src/leapfrogai_ui ci
npx --prefix src/leapfrogai_ui playwright install
- name: Setup Python
uses: ./.github/actions/python

- name: Generate Fake Playwright User Password
id: generate-password
run: |
PASSWORD=$(cat <(openssl rand -base64 32 | tr -dc 'a-zA-Z0-9!@#$%^&*()_+-=[]{}|;:,.<>?' | head -c 20) <(echo '!@1Aa') | fold -w1 | shuf | tr -d '\n')
echo "::add-mask::$PASSWORD"
echo "FAKE_E2E_USER_PASSWORD=$PASSWORD" >> $GITHUB_ENV
- name: Setup UDS Cluster
uses: ./.github/actions/uds-cluster
with:
registry1Username: ${{ secrets.IRON_BANK_ROBOT_USERNAME }}
registry1Password: ${{ secrets.IRON_BANK_ROBOT_PASSWORD }}

- name: Create Test User
run: |
chmod +x ./.github/scripts/createUser.sh
./.github/scripts/createUser.sh
- name: Setup LFAI-API and Supabase
uses: ./.github/actions/lfai-core

Expand All @@ -89,21 +98,31 @@ jobs:
run: |
python -m pytest ./tests/e2e/test_api.py -v
##########
# UI
##########
- name: Install UI/Playwright Dependencies
run: |
npm --prefix src/leapfrogai_ui ci
npx --prefix src/leapfrogai_ui playwright install
- name: Deploy LFAI-UI
run: |
make build-ui LOCAL_VERSION=e2e-test
docker image prune -af
uds zarf package deploy packages/ui/zarf-package-leapfrogai-ui-amd64-e2e-test.tar.zst --confirm
uds zarf package deploy packages/ui/zarf-package-leapfrogai-ui-amd64-e2e-test.tar.zst --set DISABLE_KEYCLOAK=false --confirm
rm packages/ui/zarf-package-leapfrogai-ui-amd64-e2e-test.tar.zst
# Run the playwright UI tests using the deployed Supabase endpoint and upload report as an artifact
- name: UI/API/Supabase E2E Playwright Tests
run: |
cp src/leapfrogai_ui/.env.example src/leapfrogai_ui/.env
TEST_ENV=CI PUBLIC_DISABLE_KEYCLOAK=true PUBLIC_SUPABASE_ANON_KEY=$ANON_KEY npm --prefix src/leapfrogai_ui run test:integration:ci
mkdir -p playwright/auth
touch playwright/auth.user.json
SERVICE_ROLE_KEY=$(uds zarf tools kubectl get secret -n leapfrogai supabase-bootstrap-jwt -o jsonpath={.data.service-key} | base64 -d)
echo "::add-mask::$SERVICE_ROLE_KEY"
SERVICE_ROLE_KEY=$SERVICE_ROLE_KEY TEST_ENV=CI USERNAME=doug PASSWORD=$FAKE_E2E_USER_PASSWORD PUBLIC_SUPABASE_ANON_KEY=$ANON_KEY npm --prefix src/leapfrogai_ui run test:integration:ci
# Upload the Playwright report as an artifact
- name: Archive Playwright Report
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

## Table of Contents

- [Table of Contents](#table-of-contents)
- [Overview](#overview)
- [Why Host Your Own LLM?](#why-host-your-own-llm)
- [Demo Video](#demo-video)
- [Structure](#structure)
- [Getting Started](#getting-started)
- [Components](#components)
Expand Down Expand Up @@ -39,14 +39,15 @@ Large Language Models (LLMs) are a powerful resource for AI-driven decision maki
## Demo Video

<a href="https://www.youtube.com/watch?v=BowOJttHyPU" target="_blank">
<img src="website/assets/img/walkthrough_thumbnail.jpg" alt="2 minute demo of features of LeapfrogAI" width="540"/>
<img src="docs/imgs/walkthrough_thumbnail.jpg" alt="2 minute demo of features of LeapfrogAI" width="540"/>
</a>

LeapfrogAI, built on top of [Unicorn Delivery Service (UDS)](https://github.com/defenseunicorns/uds-core), which includes several features including:
LeapfrogAI is built on top of [Unicorn Delivery Service (UDS)](https://github.com/defenseunicorns/uds-core), Defense Unicorns' secure runtime environment, and includes several features such as:

- **Single Sign-On**
- **Non-proprietary API Compatible with OpenAI's API**
- **Retrieval Augmented Generation (RAG)**
- **Transcription and Translation**
- **And More!**

## Structure
Expand Down
File renamed without changes
2 changes: 1 addition & 1 deletion packages/k3d-gpu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ create-uds-gpu-cluster: build-k3d-gpu
--set K3D_EXTRA_ARGS="--gpus=all \
--image=ghcr.io/defenseunicorns/leapfrogai/k3d-gpu:${LOCAL_VERSION}" --confirm

create-uds-cpu-cluster: build-k3d-gpu
create-uds-cpu-cluster:
@uds deploy k3d-core-slim-dev:${UDS_VERSION} \
${ZARF_FLAGS} \
--confirm
Expand Down
24 changes: 21 additions & 3 deletions packages/supabase/bitnami-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,22 @@ realtime:
resourcesPreset: "none"
podLabels:
sidecar.istio.io/inject: "false"
extraEnvVars:
- name: APP_NAME
value: "supabase-realtime"
- name: DB_AFTER_CONNECT_QUERY
value: "DO $body$ BEGIN CREATE SCHEMA IF NOT EXISTS _realtime; ALTER SCHEMA _realtime OWNER TO postgres; SET search_path TO _realtime; END $body$;"
- name: DB_ENC_KEY
valueFrom:
secretKeyRef:
name: supabase-realtime-extra
key: dbEncKey
- name: DNS_NODES
value: "supabase-realtime"
args:
- -ec
- |
realtime eval Realtime.Release.migrate && realtime eval 'Realtime.Release.seeds(Realtime.Repo)' && realtime start
rest:
enabled: ###ZARF_VAR_ENABLE_REST###
Expand Down Expand Up @@ -107,7 +123,7 @@ volumePermissions:
resourcesPreset: "none"

psqlImage:
tag: 15.1.1-debian-12-r69
tag: 15.6.1-debian-12-r2

kong:
enabled: ###ZARF_VAR_ENABLE_KONG###
Expand Down Expand Up @@ -172,9 +188,11 @@ kong:
postgresql:
enabled: ###ZARF_VAR_ENABLE_POSTGRES###
image:
tag: 15.1.1-debian-12-r69
tag: 15.6.1-debian-12-r2
debug: true
primary:
extendedConfiguration: |
wal_level = logical
resourcesPreset: "none"
podLabels:
sidecar.istio.io/inject: "false"
Expand All @@ -184,4 +202,4 @@ postgresql:
## @param postgresql.postgresqlSharedPreloadLibraries Set the shared_preload_libraries parameter in postgresql.conf
## Setting an empty value in order to force the default extensions of supabase-postgres
##
postgresqlSharedPreloadLibraries: "pg_stat_statements, pg_stat_monitor, pgaudit, plpgsql, plpgsql_check, pg_cron, pg_net, pgsodium, timescaledb, auto_explain, vector"
postgresqlSharedPreloadLibraries: "pg_stat_statements, pg_stat_monitor, pgaudit, plpgsql, plpgsql_check, pg_cron, pg_net, pgsodium, timescaledb, auto_explain, vector"
18 changes: 18 additions & 0 deletions packages/supabase/chart/templates/supabase-realtime-secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{{- $dbEncKey := randAlphaNum 16 }} # This needs to be exactly 16 characters
{{- $existingSecret := (lookup "v1" "Secret" .Release.Namespace "supabase-realtime-extra") }}
apiVersion: v1
kind: Secret
metadata:
name: supabase-realtime-extra
namespace: {{ .Release.Namespace }}
{{- if $existingSecret }}
annotations:
"helm.sh/resource-policy": keep
{{- end }}
type: Opaque
data:
{{- if $existingSecret }}
dbEncKey: {{ $existingSecret.data.dbEncKey }}
{{- else }}
dbEncKey: {{ $dbEncKey | b64enc | quote }}
{{- end }}
28 changes: 24 additions & 4 deletions packages/supabase/manifests/declarative-conf-configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,31 @@ data:
- admin
- anon
- name: realtime-v1
_comment: "Realtime: /realtime/v1/* -> ws://supabase-realtime:80/socket/*"
url: http://supabase-realtime:80/socket
- name: realtime-v1-ws
_comment: "Realtime: /realtime/v1/* -> ws://supabase-realtime:80/socket/websocket/*"
url: http://supabase-realtime:80/socket/websocket
routes:
- name: realtime-v1-all
- name: realtime-v1-ws
strip_path: true
paths:
- /realtime/v1/websocket
plugins:
- name: cors
- name: key-auth
config:
hide_credentials: false
- name: acl
config:
hide_groups_header: true
allow:
- admin
- anon
- name: realtime-v1-api
_comment: "Realtime: /realtime/v1/* -> http://supabase-realtime:80/*"
url: http://supabase-realtime:80
routes:
- name: realtime-v1-api
strip_path: true
paths:
- /realtime/v1/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-- Disable the foreign key constraint
ALTER TABLE _realtime.extensions
DROP CONSTRAINT extensions_tenant_external_id_fkey;

-- Update the external_id and name for the realtime tenant
UPDATE _realtime.tenants
SET external_id = 'supabase-realtime',
name = 'supabase-realtime'
WHERE external_id = 'realtime-dev'
AND name = 'realtime-dev';

-- Update the tenant_external_id for the realtime extension
UPDATE _realtime.extensions
SET tenant_external_id = 'supabase-realtime'
WHERE tenant_external_id = 'realtime-dev';

-- Re-enable the foreign key constraint
ALTER TABLE _realtime.extensions
ADD CONSTRAINT extensions_tenant_external_id_fkey
FOREIGN KEY (tenant_external_id)
REFERENCES _realtime.tenants(external_id)
ON DELETE CASCADE;
26 changes: 13 additions & 13 deletions packages/supabase/zarf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ components:
namespace: leapfrogai
url: oci://registry-1.docker.io/bitnamicharts/supabase
releaseName: supabase-bootstrap
version: 4.0.5
version: 5.3.3
valuesFiles:
- "bitnami-values.yaml"
- "bitnami-values-bootstrap.yaml"
Expand All @@ -81,21 +81,21 @@ components:
namespace: leapfrogai
url: oci://registry-1.docker.io/bitnamicharts/supabase
releaseName: supabase
version: 4.0.5
version: 5.3.3
valuesFiles:
- "bitnami-values.yaml"
images:
- docker.io/bitnami/gotrue:2.150.1-debian-12-r1
- docker.io/bitnami/jwt-cli:6.0.0-debian-12-r20
- docker.io/bitnami/kubectl:1.30.0-debian-12-r0
- docker.io/bitnami/os-shell:12-debian-12-r19
- docker.io/bitnami/postgrest:11.2.2-debian-12-r15
- docker.io/bitnami/supabase-postgres:15.1.1-debian-12-r69
- docker.io/bitnami/supabase-postgres-meta:0.80.0-debian-12-r3
- docker.io/bitnami/supabase-realtime:2.28.32-debian-12-r2
- docker.io/bitnami/supabase-storage:0.48.4-debian-12-r2
- docker.io/bitnami/supabase-studio:0.24.3-debian-12-r3
- docker.io/bitnami/kong:3.6.1-debian-12-r18
- docker.io/bitnami/gotrue:2.155.6-debian-12-r3
- docker.io/bitnami/jwt-cli:6.1.0-debian-12-r5
- docker.io/bitnami/kubectl:1.30.3-debian-12-r4
- docker.io/bitnami/os-shell:12-debian-12-r27
- docker.io/bitnami/postgrest:11.2.2-debian-12-r31
- docker.io/bitnami/supabase-postgres:15.6.1-debian-12-r2
- docker.io/bitnami/supabase-postgres-meta:0.83.2-debian-12-r3
- docker.io/bitnami/supabase-realtime:2.30.14-debian-12-r2
- docker.io/bitnami/supabase-storage:1.8.2-debian-12-r2
- docker.io/bitnami/supabase-studio:1.24.5-debian-12-r4
- docker.io/bitnami/kong:3.7.1-debian-12-r5
- name: supabase-post-process
description: "Perform necessary post processing here"
required: true
Expand Down
1 change: 1 addition & 0 deletions src/leapfrogai_ui/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ zarf-sbom/

playwright/.auth
test-results/
e2e-report/
3 changes: 3 additions & 0 deletions src/leapfrogai_ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ Notes:
1. Playwright tests are End-To-End tests and use the "real" full stack app. If you run these tests, they will use the configuration indicated by your
.env file. See the "Configuration Options" section above to configure which database Playwright is using.
2. If you run the tests in headless mode (`npm run test:integration`) you do not need the app running, it will build the app and run on port 4173.
3. If using Keycloak, you cannot login twice within 30 seconds. If you global.setup.ts step fails, this is likely why. The setup file also tests logout, but
this can take a long time because of the 30 second wait in between log ins. You can disable this test by setting the environment
variable SKIP_LOGOUT_TEST=true

### Supabase and Keycloak Integration

Expand Down
2 changes: 1 addition & 1 deletion src/leapfrogai_ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"format": "prettier --write . && eslint . --fix",
"test:integration": "playwright test",
"test:integration:ui": "playwright test --ui",
"test:integration:ci": "playwright test tests/global.setup.ts tests/api.test.ts tests/api-keys.test.ts tests/header.test.ts tests/logout.test.ts",
"test:integration:ci": "playwright test tests/global.setup.ts tests/api.test.ts tests/api-keys.test.ts tests/header.test.ts",
"test:unit": "vitest run",
"test:unit:watch": "vitest",
"supabase:start": "supabase start",
Expand Down
Loading

0 comments on commit cce96e0

Please sign in to comment.