Add activity-core LLM endpoint support
Some checks failed
CI / test (3.10) (push) Has been cancelled
CI / test (3.11) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled

This commit is contained in:
2026-06-07 19:24:45 +02:00
parent 1d9fc107ed
commit 14ba47c129
25 changed files with 2082 additions and 18 deletions

View File

@@ -0,0 +1,49 @@
# activity-core llm-connect Service
This overlay deploys `llm-connect` as an internal `activity-core` namespace
service for daily WSJF triage.
Stable in-cluster URL after apply:
```text
http://llm-connect.activity-core.svc.cluster.local:8080
```
Create provider credentials outside Git before applying the Deployment. For the
default OpenRouter config:
```bash
kubectl -n activity-core create secret generic llm-connect-provider-secrets \
--from-literal=OPENROUTER_API_KEY="$OPENROUTER_API_KEY"
```
Apply:
```bash
docker build -t docker.io/library/llm-connect:latest .
docker save docker.io/library/llm-connect:latest | ssh coulombcore sudo k3s ctr -n k8s.io images import -
kubectl apply -k deploy/k8s/activity-core-llm-connect
kubectl -n activity-core rollout status deployment/llm-connect
```
Smoke from inside the namespace, using an image that includes this repo's
fixtures and `scripts/smoke_activity_core_endpoint.py`:
```bash
kubectl -n activity-core run llm-connect-smoke \
--rm -i --restart=Never \
--image=llm-connect:latest \
--env=LLM_CONNECT_URL=http://llm-connect.activity-core.svc.cluster.local:8080 \
--env=LLM_CONNECT_TIMEOUT_SECONDS=300 \
-- python scripts/smoke_activity_core_endpoint.py
```
Then set activity-core's runtime config:
```text
LLM_CONNECT_URL=http://llm-connect.activity-core.svc.cluster.local:8080
LLM_CONNECT_TIMEOUT_SECONDS=300
```
Do not commit provider keys, live prompt payloads, or smoke response bodies that
contain operational State Hub data.

View File

@@ -0,0 +1,21 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: llm-connect-config
namespace: activity-core
labels:
app.kubernetes.io/name: llm-connect
app.kubernetes.io/part-of: activity-core
data:
LLM_CONNECT_HOST: "0.0.0.0"
LLM_CONNECT_PORT: "8080"
LLM_CONNECT_PROVIDER: "openrouter"
LLM_CONNECT_MODEL: "anthropic/claude-sonnet-4"
LLM_CONNECT_CUSTODIAN_TRIAGE_PROVIDER: "openrouter"
LLM_CONNECT_CUSTODIAN_TRIAGE_MODEL: "anthropic/claude-sonnet-4"
LLM_CONNECT_CUSTODIAN_TRIAGE_TEMPERATURE: "0.2"
LLM_CONNECT_CUSTODIAN_TRIAGE_MAX_TOKENS: "1800"
LLM_CONNECT_CUSTODIAN_TRIAGE_MAX_DEPTH: "2"
LLM_CONNECT_CUSTODIAN_TRIAGE_TIMEOUT_SECONDS: "300"
LLM_CONNECT_CUSTODIAN_TRIAGE_REASONING_EFFORT: "medium"
LLM_CONNECT_STRICT_PROFILES: "false"

View File

@@ -0,0 +1,64 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: llm-connect
namespace: activity-core
labels:
app.kubernetes.io/name: llm-connect
app.kubernetes.io/part-of: activity-core
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: llm-connect
template:
metadata:
labels:
app.kubernetes.io/name: llm-connect
app.kubernetes.io/part-of: activity-core
spec:
containers:
- name: llm-connect
image: docker.io/library/llm-connect:latest
imagePullPolicy: Never
envFrom:
- configMapRef:
name: llm-connect-config
- secretRef:
name: llm-connect-provider-secrets
optional: false
ports:
- name: http
containerPort: 8080
readinessProbe:
httpGet:
path: /health
port: http
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
livenessProbe:
httpGet:
path: /health
port: http
periodSeconds: 30
timeoutSeconds: 3
failureThreshold: 3
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
securityContext:
fsGroup: 10001

View File

@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- configmap.yaml
- deployment.yaml
- service.yaml
- networkpolicy.yaml

View File

@@ -0,0 +1,39 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: llm-connect-activity-core-only
namespace: activity-core
labels:
app.kubernetes.io/name: llm-connect
app.kubernetes.io/part-of: activity-core
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: llm-connect
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: activity-core
ports:
- protocol: TCP
port: 8080
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 443

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: llm-connect
namespace: activity-core
labels:
app.kubernetes.io/name: llm-connect
app.kubernetes.io/part-of: activity-core
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: llm-connect
ports:
- name: http
port: 8080
targetPort: http