Compare commits
2 Commits
d53ed3d05c
...
0c3661e919
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c3661e919 | |||
| 8bd1dce63f |
@@ -7,80 +7,27 @@ on:
|
||||
workflow_dispatch: {}
|
||||
|
||||
env:
|
||||
REGISTRY_HOST: git.ivanch.me
|
||||
REGISTRY_USERNAME: ivanch
|
||||
IMAGE: ${{ env.REGISTRY_HOST }}/ivanch/recommender
|
||||
KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
|
||||
IMAGE: git.ivanch.me/ivanch/recommender
|
||||
|
||||
jobs:
|
||||
build_recommender:
|
||||
name: Build Recommender Image
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Log in to Container Registry
|
||||
run: |
|
||||
echo "${{ secrets.REGISTRY_PASSWORD }}" \
|
||||
| docker login "${{ env.REGISTRY_HOST }}" \
|
||||
-u "${{ env.REGISTRY_USERNAME }}" \
|
||||
--password-stdin
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build and Push Multi-Arch Image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
push: true
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
${{ env.IMAGE }}:latest
|
||||
|
||||
deploy_recommender:
|
||||
name: Deploy Recommender (internal)
|
||||
build:
|
||||
name: Build Image
|
||||
runs-on: ubuntu-amd64
|
||||
needs: build_recommender
|
||||
steps:
|
||||
- name: Check KUBE_CONFIG validity
|
||||
run: |
|
||||
if [ -z "${KUBE_CONFIG}" ] || [ "${KUBE_CONFIG}" = "" ] || [ "${KUBE_CONFIG// }" = "" ]; then
|
||||
echo "KUBE_CONFIG is not set or is empty."
|
||||
exit 1
|
||||
fi
|
||||
- uses: actions/checkout@v4
|
||||
- uses: https://git.ivanch.me/ivanch/pipeline-actions/build-and-push@main
|
||||
with:
|
||||
image: ${{ env.IMAGE }}
|
||||
registry_password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
ssh_key: ${{ secrets.SSH_KEY_DOCKERBUILD }}
|
||||
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Download and install dependencies
|
||||
run: |
|
||||
apt-get update -y
|
||||
apt-get install -y curl
|
||||
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
|
||||
install -m 0755 kubectl /usr/local/bin/kubectl
|
||||
kubectl version --client
|
||||
|
||||
- name: Set up kubeconfig
|
||||
run: |
|
||||
cd deploy
|
||||
echo "$KUBE_CONFIG" > kubeconfig.yaml
|
||||
env:
|
||||
KUBE_CONFIG: ${{ env.KUBE_CONFIG }}
|
||||
|
||||
- name: Check connection to cluster
|
||||
run: |
|
||||
cd deploy
|
||||
kubectl --kubeconfig=kubeconfig.yaml cluster-info
|
||||
|
||||
- name: Apply Recommender deployment
|
||||
run: |
|
||||
cd deploy
|
||||
kubectl --kubeconfig=kubeconfig.yaml apply -f recommender.yaml
|
||||
|
||||
- name: Rollout restart
|
||||
run: |
|
||||
cd deploy
|
||||
kubectl --kubeconfig=kubeconfig.yaml rollout restart deployment recommender -n media
|
||||
deploy:
|
||||
name: Deploy (internal)
|
||||
runs-on: ubuntu-amd64
|
||||
needs: build
|
||||
steps:
|
||||
- uses: https://git.ivanch.me/ivanch/pipeline-actions/deploy-restart@main
|
||||
with:
|
||||
kube_config: ${{ secrets.KUBE_CONFIG }}
|
||||
deployment_name: recommender
|
||||
namespace: media
|
||||
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -25,3 +25,10 @@ documents/
|
||||
|
||||
# OS
|
||||
Thumbs.db
|
||||
|
||||
# Deploy
|
||||
deploy/terraform/.terraform
|
||||
deploy/terraform/*.tfstate
|
||||
deploy/terraform/*.tfstate.*
|
||||
deploy/terraform/*.tfplan
|
||||
deploy/terraform/.terraform.lock.hcl
|
||||
@@ -1,83 +0,0 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: recommender
|
||||
namespace: media
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: recommender
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: recommender
|
||||
spec:
|
||||
containers:
|
||||
- name: recommender
|
||||
image: git.ivanch.me/ivanch/recommender:latest
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 80
|
||||
env:
|
||||
- name: OPENAI_API_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: recommender-secrets
|
||||
key: OPENAI_API_KEY
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: recommender-secrets
|
||||
key: DATABASE_URL
|
||||
- name: BEARER_TOKEN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: recommender-secrets
|
||||
key: BEARER_TOKEN
|
||||
- name: PROVIDER_URL
|
||||
value: "https://openrouter.ai/api/v1"
|
||||
- name: MODEL_NAME
|
||||
value: "openai/gpt-5.4"
|
||||
- name: AI_PROVIDER
|
||||
value: "GENERIC"
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "500m"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "1"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: recommender
|
||||
namespace: media
|
||||
spec:
|
||||
selector:
|
||||
app: recommender
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 80
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: recommender
|
||||
namespace: media
|
||||
labels:
|
||||
app.kubernetes.io/name: recommender
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: "recommender.haven"
|
||||
http:
|
||||
paths:
|
||||
- path: "/"
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: recommender
|
||||
port:
|
||||
number: 80
|
||||
@@ -4,13 +4,7 @@
|
||||
|
||||
DATABASE_URL=postgres://user:password@localhost:5432/recommender
|
||||
|
||||
# AI provider selection: OPENAI (default) or GENERIC
|
||||
AI_PROVIDER=OPENAI
|
||||
|
||||
# OpenAI provider settings (used when AI_PROVIDER=OPENAI)
|
||||
OPENAI_API_KEY=your-openai-api-key-here
|
||||
|
||||
# Generic provider settings (used when AI_PROVIDER=GENERIC)
|
||||
# provider settings
|
||||
PROVIDER_URL=https://your-provider.example.com/v1
|
||||
BEARER_TOKEN=your-bearer-token
|
||||
MODEL_NAME=your-model-name
|
||||
|
||||
@@ -2,26 +2,17 @@ import OpenAI from 'openai';
|
||||
import * as dotenv from 'dotenv';
|
||||
dotenv.config({ path: ['.env.local', '.env'] });
|
||||
|
||||
const AI_PROVIDER = process.env.AI_PROVIDER ?? 'OPENAI';
|
||||
const isGeneric = AI_PROVIDER === 'GENERIC';
|
||||
|
||||
export const openai = isGeneric
|
||||
? new OpenAI({
|
||||
export const openai = new OpenAI({
|
||||
apiKey: process.env.BEARER_TOKEN,
|
||||
baseURL: process.env.PROVIDER_URL,
|
||||
timeout: 600000, // 10 minutes
|
||||
maxRetries: 3,
|
||||
})
|
||||
: new OpenAI({
|
||||
apiKey: process.env.OPENAI_API_KEY,
|
||||
timeout: 600000, // 10 minutes
|
||||
maxRetries: 3,
|
||||
});
|
||||
|
||||
export const defaultModel = isGeneric ? (process.env.MODEL_NAME ?? 'default') : 'gpt-5.4';
|
||||
export const miniModel = isGeneric ? (process.env.MODEL_NAME ?? 'default') : 'gpt-5.4-mini';
|
||||
export const serviceOptions = isGeneric ? {} : { service_tier: 'flex' as const };
|
||||
export const supportsWebSearch = !isGeneric;
|
||||
export const defaultModel = process.env.MODEL_NAME ?? 'gpt-5.4';
|
||||
export const miniModel = process.env.MODEL_NAME ?? 'gpt-5.4-mini';
|
||||
export const serviceOptions = { service_tier: 'flex' as const };
|
||||
export const supportsWebSearch = true;
|
||||
|
||||
function isJsonParseError(err: unknown): boolean {
|
||||
if (err instanceof SyntaxError) return true;
|
||||
|
||||
Reference in New Issue
Block a user