@r8s/open-webui 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,144 @@
1
+ import type { SecretRef } from '@r8s/recipes';
2
+ export interface OpenWebuiProps {
3
+ /** Resource name (defaults to 'open-webui') */
4
+ name?: string;
5
+ /** Kubernetes namespace (defaults to 'default') */
6
+ namespace?: string;
7
+ /** Container image tag (defaults to 'latest' — pin a version in production) */
8
+ version?: string;
9
+ /** Public hostname for the chat UI (required) */
10
+ host: string;
11
+ /**
12
+ * Number of replicas (defaults to 1). Multiple replicas need a shared
13
+ * object store for uploads/RAG (this recipe errors when `storage` is
14
+ * set with replicas > 1 — its PVC is ReadWriteOnce) and Redis-backed
15
+ * websocket coordination (WEBSOCKET_MANAGER=redis + REDIS_URL).
16
+ */
17
+ replicas?: number;
18
+ /**
19
+ * PVC size for uploads and RAG document storage (e.g. '10Gi'). When set,
20
+ * a `${name}-uploads` PersistentVolumeClaim is rendered and mounted at
21
+ * /app/backend/data. WebService cannot express volume mounts, which is
22
+ * why this component composes a raw Deployment (probes /health:8080).
23
+ * The PVC is ReadWriteOnce — combining this with replicas > 1 throws
24
+ * (single-node attach); multi-replica installs must move files/RAG to
25
+ * an S3-compatible store and set WEBSOCKET_MANAGER=redis.
26
+ */
27
+ storage?: string;
28
+ /**
29
+ * OpenAI-compatible API base URL for the model backend (defaults to
30
+ * 'https://api.berget.ai/v1'). The key itself is never passed as a
31
+ * prop — it arrives via secretKeyRef from the secrets bundle below.
32
+ */
33
+ backend?: string;
34
+ /**
35
+ * Name of an existing Secret holding `modelApiKey` (the key used to
36
+ * call `backend`) and `secretKey` (the WEBUI_SECRET_KEY used to sign
37
+ * auth tokens). Required unless a secrets backend (openbao/vault) is
38
+ * configured on the surrounding Platform — the backend then provisions
39
+ * both keys automatically. Plaintext keys are not supported.
40
+ */
41
+ secretsName?: string;
42
+ /**
43
+ * OAuth/OIDC SSO client — register Open WebUI as a client in Keycloak
44
+ * (the Auth recipe) and reference the client secret through the backend.
45
+ * Uses the upstream OAUTH_* env names; OPENID_PROVIDER_URL carries the
46
+ * issuer (Open WebUI appends /.well-known/openid-configuration itself).
47
+ */
48
+ sso?: {
49
+ /** OIDC discovery issuer, e.g. https://keycloak.example.com/realms/platform */
50
+ issuer: string;
51
+ /** Client id registered at the issuer (non-sensitive) */
52
+ clientId: string;
53
+ /** Reference to the Kubernetes Secret holding the client secret */
54
+ clientSecretRef: SecretRef;
55
+ /** Scope list (defaults to 'openid email profile') */
56
+ scopes?: string;
57
+ };
58
+ /** Provision a redis-backed replication group for caching/events (default: false) */
59
+ cache?: boolean;
60
+ /**
61
+ * Air-gapped installs: sets OFFLINE_MODE (disable runtime model/param
62
+ * fetches), removes the update checks and disables the native Ollama
63
+ * API — only OpenAI-compatible backends are served (default: false).
64
+ */
65
+ offline?: boolean;
66
+ /** Requested resources */
67
+ resources?: {
68
+ requests?: {
69
+ cpu?: string;
70
+ memory?: string;
71
+ };
72
+ limits?: {
73
+ cpu?: string;
74
+ memory?: string;
75
+ };
76
+ };
77
+ /** TLS configuration (defaults to letsencrypt-prod cluster issuer) */
78
+ tls?: {
79
+ secretName: string;
80
+ clusterIssuer: string;
81
+ };
82
+ }
83
+ /**
84
+ * Open WebUI — self-hosted chat frontend for OpenAI-compatible backends.
85
+ *
86
+ * @title OpenWebui
87
+ * @category AI & Chat
88
+ *
89
+ * Composes:
90
+ * - CNPG Postgres cluster (users, chats, presets) via the Database recipe
91
+ * - Open WebUI Deployment + Service + Endpoint (websocket-friendly
92
+ * proxy annotations; works through Ingress or Envoy Gateway)
93
+ * - Optional PVC for uploaded files and RAG documents
94
+ * (`${name}-uploads` mounted at /app/backend/data)
95
+ * - Optional redis replication group for caching (`cache`,
96
+ * service ${name}-redis)
97
+ * - Model API key + WEBUI_SECRET_KEY provisioned through the Platform
98
+ * secrets backend (openbao / vault), or referenced from an existing
99
+ * Secret
100
+ * - OAuth/OIDC SSO against the Keycloak `Auth` recipe
101
+ *
102
+ * Wrap the component in `<Platform secrets={{ backend: 'openbao' }}>` and
103
+ * the OPENAI_API_KEY / WEBUI_SECRET_KEY pair is provisioned for you.
104
+ * Without a backend you must point `secretsName` at a pre-created Secret.
105
+ * The Perplexity-style "search the web" extras are not wired — only
106
+ * OPENAI-models via the OpenAI-compatible `backend`.
107
+ *
108
+ * @example
109
+ * import { Platform } from '@r8s/recipes'
110
+ * import { OpenWebui } from '@r8s/open-webui'
111
+ *
112
+ * export default (
113
+ * <Platform secrets={{ backend: 'openbao', mount: 'kv', path: 'apps' }}>
114
+ * <OpenWebui
115
+ * name="chat"
116
+ * host="chat.example.com"
117
+ * version="v0.6.5"
118
+ * storage="10Gi"
119
+ * />
120
+ * </Platform>
121
+ * )
122
+ *
123
+ * @example
124
+ * import { Platform } from '@r8s/recipes'
125
+ * import { OpenWebui } from '@r8s/open-webui'
126
+ *
127
+ * export default (
128
+ * <Platform secrets={{ backend: 'openbao', mount: 'kv', path: 'apps' }}>
129
+ * <OpenWebui
130
+ * name="chat"
131
+ * host="chat.example.com"
132
+ * storage="10Gi"
133
+ * cache
134
+ * sso={{
135
+ * issuer: 'https://keycloak.example.com/realms/platform',
136
+ * clientId: 'open-webui',
137
+ * clientSecretRef: { secret: 'chat-sso', key: 'clientSecret' },
138
+ * }}
139
+ * />
140
+ * </Platform>
141
+ * )
142
+ */
143
+ export declare function OpenWebui(props: OpenWebuiProps): import("@r8s/core").r8sElement;
144
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAK7C,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;OAKG;IACH,GAAG,CAAC,EAAE;QACJ,+EAA+E;QAC/E,MAAM,EAAE,MAAM,CAAA;QACd,yDAAyD;QACzD,QAAQ,EAAE,MAAM,CAAA;QAChB,mEAAmE;QACnE,eAAe,EAAE,SAAS,CAAA;QAC1B,sDAAsD;QACtD,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;IACD,qFAAqF;IACrF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0BAA0B;IAC1B,SAAS,CAAC,EAAE;QACV,QAAQ,CAAC,EAAE;YAAE,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;QAC5C,MAAM,CAAC,EAAE;YAAE,GAAG,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAC3C,CAAA;IACD,sEAAsE;IACtE,GAAG,CAAC,EAAE;QACJ,UAAU,EAAE,MAAM,CAAA;QAClB,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,kCA6R9C"}
package/dist/index.js ADDED
@@ -0,0 +1,304 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenWebui = OpenWebui;
4
+ const jsx_runtime_1 = require("@r8s/core/jsx-runtime");
5
+ const core_1 = require("@r8s/core");
6
+ const defaults_1 = require("@r8s/core/defaults");
7
+ const recipes_1 = require("@r8s/recipes");
8
+ const redis_1 = require("@r8s/crds/redis");
9
+ const operator_redis_1 = require("@r8s/operator-redis");
10
+ /**
11
+ * Open WebUI — self-hosted chat frontend for OpenAI-compatible backends.
12
+ *
13
+ * @title OpenWebui
14
+ * @category AI & Chat
15
+ *
16
+ * Composes:
17
+ * - CNPG Postgres cluster (users, chats, presets) via the Database recipe
18
+ * - Open WebUI Deployment + Service + Endpoint (websocket-friendly
19
+ * proxy annotations; works through Ingress or Envoy Gateway)
20
+ * - Optional PVC for uploaded files and RAG documents
21
+ * (`${name}-uploads` mounted at /app/backend/data)
22
+ * - Optional redis replication group for caching (`cache`,
23
+ * service ${name}-redis)
24
+ * - Model API key + WEBUI_SECRET_KEY provisioned through the Platform
25
+ * secrets backend (openbao / vault), or referenced from an existing
26
+ * Secret
27
+ * - OAuth/OIDC SSO against the Keycloak `Auth` recipe
28
+ *
29
+ * Wrap the component in `<Platform secrets={{ backend: 'openbao' }}>` and
30
+ * the OPENAI_API_KEY / WEBUI_SECRET_KEY pair is provisioned for you.
31
+ * Without a backend you must point `secretsName` at a pre-created Secret.
32
+ * The Perplexity-style "search the web" extras are not wired — only
33
+ * OPENAI-models via the OpenAI-compatible `backend`.
34
+ *
35
+ * @example
36
+ * import { Platform } from '@r8s/recipes'
37
+ * import { OpenWebui } from '@r8s/open-webui'
38
+ *
39
+ * export default (
40
+ * <Platform secrets={{ backend: 'openbao', mount: 'kv', path: 'apps' }}>
41
+ * <OpenWebui
42
+ * name="chat"
43
+ * host="chat.example.com"
44
+ * version="v0.6.5"
45
+ * storage="10Gi"
46
+ * />
47
+ * </Platform>
48
+ * )
49
+ *
50
+ * @example
51
+ * import { Platform } from '@r8s/recipes'
52
+ * import { OpenWebui } from '@r8s/open-webui'
53
+ *
54
+ * export default (
55
+ * <Platform secrets={{ backend: 'openbao', mount: 'kv', path: 'apps' }}>
56
+ * <OpenWebui
57
+ * name="chat"
58
+ * host="chat.example.com"
59
+ * storage="10Gi"
60
+ * cache
61
+ * sso={{
62
+ * issuer: 'https://keycloak.example.com/realms/platform',
63
+ * clientId: 'open-webui',
64
+ * clientSecretRef: { secret: 'chat-sso', key: 'clientSecret' },
65
+ * }}
66
+ * />
67
+ * </Platform>
68
+ * )
69
+ */
70
+ function OpenWebui(props) {
71
+ const { name = 'open-webui', namespace = 'default', version = 'latest', host, replicas = 1, storage, backend = 'https://api.berget.ai/v1', secretsName, sso, cache = false, offline = false, resources = {
72
+ requests: { memory: '1Gi', cpu: '500m' },
73
+ limits: { memory: '4Gi', cpu: '2000m' },
74
+ }, tls = { secretName: `${name}-tls`, clusterIssuer: 'letsencrypt-prod' }, } = props;
75
+ const sharedOperators = (0, core_1.useContext)(defaults_1.OperatorContext);
76
+ const secretProvider = (0, core_1.useContext)(defaults_1.SecretContext);
77
+ const resources_ = [];
78
+ // --- Validation -----------------------------------------------------------
79
+ // The uploads PVC is ReadWriteOnce: a single volume can only be attached
80
+ // to one node at a time, so extra replicas with `storage` set would
81
+ // crash-loop. Multi-replica installs are viable only with a shared
82
+ // S3-compatible object store and WEBSOCKET_MANAGER=redis for socket
83
+ // fan-out.
84
+ if (storage && replicas > 1) {
85
+ throw new Error(`OpenWebui "${name}" cannot combine storage with replicas > 1.\n` +
86
+ `\n` +
87
+ `The ${name}-uploads PVC is ReadWriteOnce and Open WebUI keeps ` +
88
+ `uploads/RAG on it — mounting it on multiple nodes is impossible, ` +
89
+ `so extra replicas would stay Unschedulable or crash-loop. ` +
90
+ `Multi-replica deployments also need WEBSOCKET_MANAGER=redis plus a ` +
91
+ `REDIS_URL for socket coordination.\n` +
92
+ `\n` +
93
+ `Fix: either run a single replica alongside the PVC:\n` +
94
+ ` <OpenWebui name="${name}" host="${host}" storage="${storage}" replicas={1} />\n` +
95
+ `\n` +
96
+ `Or drop the storage prop and move uploads to S3-compatible storage ` +
97
+ `with a Redis instance (cache) before scaling out:\n` +
98
+ ` <OpenWebui name="${name}" host="${host}" replicas={3} cache />`);
99
+ }
100
+ const dbHost = `${name}-rw`;
101
+ const dbCredentialsName = `${name}-db-credentials`;
102
+ const appSecretsName = secretsName ?? `${name}-secrets`;
103
+ // --- Secret provisioning -------------------------------------------------
104
+ // The model API key and the WEBUI_SECRET_KEY are the crown jewels of an
105
+ // Open WebUI install — never render them as plaintext. With a secrets
106
+ // backend they are provisioned through the backend (keys `modelApiKey`
107
+ // and `secretKey`); otherwise reference a pre-created Secret.
108
+ if (!secretsName) {
109
+ if (!secretProvider ||
110
+ (secretProvider.backend !== 'vault' && secretProvider.backend !== 'openbao')) {
111
+ throw new Error(`OpenWebui "${name}" requires application secrets (OPENAI_API_KEY, WEBUI_SECRET_KEY).\n` +
112
+ `\n` +
113
+ `The model API key for "${backend}" and the auth-token signing key must ` +
114
+ `not be rendered as plaintext.\n` +
115
+ `\n` +
116
+ `Fix: configure a secrets backend on the Platform:\n` +
117
+ ` <Platform secrets={{ backend: 'openbao', mount: 'kv', path: 'apps' }}>\n` +
118
+ ` <OpenWebui name="${name}" host="${host}" />\n` +
119
+ ` </Platform>\n` +
120
+ `\n` +
121
+ `Or reference a pre-created Secret (keys: modelApiKey, secretKey):\n` +
122
+ ` <OpenWebui name="${name}" host="${host}" secretsName="${name}-secrets" />`);
123
+ }
124
+ const spec = {
125
+ ...(secretProvider.backend === 'vault'
126
+ ? { vaultAuthRef: secretProvider.authRef }
127
+ : { openbaoAuthRef: secretProvider.authRef }),
128
+ mount: secretProvider.mount,
129
+ type: 'kv-v2',
130
+ path: `${secretProvider.path ?? name}/${name}/secrets`,
131
+ destination: { create: true, name: appSecretsName },
132
+ };
133
+ resources_.push(secretProvider.backend === 'vault'
134
+ ? (0, core_1.jsx)('VaultStaticSecret', {
135
+ apiVersion: 'secrets.hashicorp.com/v1beta1',
136
+ kind: 'VaultStaticSecret',
137
+ metadata: { name: `${name}-secrets`, namespace },
138
+ spec,
139
+ })
140
+ : (0, core_1.jsx)('OpenBaoStaticSecret', {
141
+ apiVersion: 'secrets.openbao.org/v1beta1',
142
+ kind: 'OpenBaoStaticSecret',
143
+ metadata: { name: `${name}-secrets`, namespace },
144
+ spec,
145
+ }));
146
+ }
147
+ // --- Operators ------------------------------------------------------------
148
+ if (cache) {
149
+ resources_.push(...(0, operator_redis_1.declareIfMissing)(sharedOperators));
150
+ }
151
+ // Redis — caching (OT-Container-Kit operator). A replication group so
152
+ // the single ${name}-redis master service fronts a 3-node replication
153
+ // set (1 master + 2 replicas) instead of a lone stateful pod.
154
+ if (cache) {
155
+ resources_.push((0, redis_1.RedisReplicationComponent)({
156
+ metadata: { name: `${name}-redis`, namespace },
157
+ spec: {
158
+ clusterSize: 3,
159
+ kubernetesConfig: { image: 'redis:7.2-alpine' },
160
+ },
161
+ }));
162
+ }
163
+ // --- Uploads/RAG PVC --------------------------------------------------------
164
+ // WebService cannot mount volumes, so the app controller below is a raw
165
+ // Deployment. The PVC is rendered alongside and bound when `storage` is
166
+ // set. Without it, uploaded files and RAG documents are lost on restart.
167
+ if (storage) {
168
+ const pvc = {
169
+ apiVersion: 'v1',
170
+ kind: 'PersistentVolumeClaim',
171
+ metadata: { name: `${name}-uploads`, namespace },
172
+ spec: {
173
+ accessModes: ['ReadWriteOnce'],
174
+ resources: { requests: { storage } },
175
+ },
176
+ };
177
+ resources_.push((0, core_1.jsx)('PersistentVolumeClaim', pvc));
178
+ }
179
+ // --- Env wiring --------------------------------------------------------------
180
+ // Every credential arrives via secretKeyRef — declared BEFORE plain env
181
+ // vars in the container env array, so Kubernetes dependent-variable
182
+ // expansion resolves the $(VAR) templates below at runtime.
183
+ const secretRefs = {
184
+ PGPASSWORD: { secret: dbCredentialsName, key: 'password' },
185
+ OPENAI_API_KEY: { secret: appSecretsName, key: 'modelApiKey' },
186
+ WEBUI_SECRET_KEY: { secret: appSecretsName, key: 'secretKey' },
187
+ ...(sso ? { OAUTH_CLIENT_SECRET: sso.clientSecretRef } : {}),
188
+ };
189
+ const envVars = [];
190
+ for (const [envName, ref] of Object.entries(secretRefs)) {
191
+ const typed = typeof ref === 'string' ? { secret: ref } : ref;
192
+ envVars.push({
193
+ name: envName,
194
+ valueFrom: { secretKeyRef: { name: typed.secret, key: typed.key ?? envName } },
195
+ });
196
+ }
197
+ const env = {
198
+ WEBUI_URL: `https://${host}`,
199
+ ENABLE_OPENAI_API: 'true',
200
+ // This recipe targets OpenAI-compatible backends only — the native
201
+ // Ollama API discovery stays off (offline mode forces the same).
202
+ ENABLE_OLLAMA_API: 'false',
203
+ OPENAI_API_BASE_URL: backend,
204
+ // Deterministic parts inlined; the password arrives via $(PGPASSWORD)
205
+ // (secret-backed var declared first in the env array).
206
+ DATABASE_URL: `postgresql://${name}:$(PGPASSWORD)@${dbHost}:5432/${name}`,
207
+ ...(cache ? { REDIS_URL: `redis://${name}-redis:6379` } : {}),
208
+ // Upstream OAUTH_* names; ENABLE_OAUTH_SIGNUP (default true) governs
209
+ // whether local-password login is offered alongside the SSO flow.
210
+ ...(sso
211
+ ? {
212
+ ENABLE_OAUTH_SIGNUP: 'true',
213
+ OPENID_PROVIDER_URL: sso.issuer,
214
+ OAUTH_CLIENT_ID: sso.clientId,
215
+ OPENID_REDIRECT_URI: `https://${host}/oauth/oidc/callback`,
216
+ OAUTH_SCOPES: sso.scopes ?? 'openid email profile',
217
+ }
218
+ : {}),
219
+ ...(offline
220
+ ? {
221
+ OFFLINE_MODE: 'true',
222
+ ENABLE_UPDATE_CHECK: 'false',
223
+ }
224
+ : {}),
225
+ };
226
+ for (const [key, value] of Object.entries(env)) {
227
+ envVars.push({ name: key, value });
228
+ }
229
+ // --- App controller (raw Deployment — WebService cannot mount volumes) -----
230
+ // Generous probe delays/failures: first-boot runs Alembic migrations
231
+ // against Postgres before /health starts answering.
232
+ const deployment = {
233
+ apiVersion: 'apps/v1',
234
+ kind: 'Deployment',
235
+ metadata: { name, namespace, labels: { app: name } },
236
+ spec: {
237
+ replicas,
238
+ selector: { matchLabels: { app: name } },
239
+ template: {
240
+ metadata: { labels: { app: name } },
241
+ spec: {
242
+ containers: [
243
+ {
244
+ name: 'open-webui',
245
+ image: `ghcr.io/open-webui/open-webui:${version}`,
246
+ imagePullPolicy: 'Always',
247
+ ports: [{ containerPort: 8080 }],
248
+ env: envVars,
249
+ resources,
250
+ livenessProbe: {
251
+ httpGet: { path: '/health', port: 8080 },
252
+ initialDelaySeconds: 30,
253
+ periodSeconds: 10,
254
+ failureThreshold: 6,
255
+ },
256
+ readinessProbe: {
257
+ httpGet: { path: '/health', port: 8080 },
258
+ initialDelaySeconds: 30,
259
+ periodSeconds: 5,
260
+ failureThreshold: 6,
261
+ },
262
+ ...(storage && {
263
+ volumeMounts: [{ name: 'uploads', mountPath: '/app/backend/data' }],
264
+ }),
265
+ },
266
+ ],
267
+ ...(storage && {
268
+ volumes: [{ name: 'uploads', persistentVolumeClaim: { claimName: `${name}-uploads` } }],
269
+ }),
270
+ },
271
+ },
272
+ },
273
+ };
274
+ // Database parent wraps the app so the CNPG cluster, its credentials
275
+ // secret (${name}-db-credentials) and connection conventions stay
276
+ // consistent with the r8s Database recipe. The raw Deployment sets
277
+ // DATABASE_URL statically (the WebService auto-PG block does not apply).
278
+ resources_.push((0, core_1.jsx)(recipes_1.Database, {
279
+ backup: false,
280
+ name,
281
+ namespace,
282
+ storage: '10Gi',
283
+ children: (0, core_1.jsx)('Deployment', deployment),
284
+ }));
285
+ // --- Service -----------------------------------------------------------------
286
+ const service = {
287
+ apiVersion: 'v1',
288
+ kind: 'Service',
289
+ metadata: { name, namespace },
290
+ spec: {
291
+ type: 'ClusterIP',
292
+ selector: { app: name },
293
+ ports: [{ port: 8080, targetPort: 8080 }],
294
+ },
295
+ };
296
+ resources_.push((0, core_1.jsx)('Service', service));
297
+ // --- Endpoint — websocket-friendly proxy timeouts ------------------------------
298
+ resources_.push((0, jsx_runtime_1.jsx)(recipes_1.Endpoint, { name: `${name}-endpoint`, namespace: namespace, host: host, serviceName: name, servicePort: 8080, tls: tls, annotations: {
299
+ 'nginx.ingress.kubernetes.io/proxy-read-timeout': '300',
300
+ 'nginx.ingress.kubernetes.io/proxy-send-timeout': '300',
301
+ } }));
302
+ return (0, core_1.jsx)(core_1.Fragment, { children: resources_ });
303
+ }
304
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@r8s/open-webui",
3
- "version": "0.2.0",
4
- "description": "Open WebUI chat frontend for OpenAI-compatible backends, Postgres persistence, uploads/RAG storage, OIDC SSO, optional Redis cache",
3
+ "version": "0.3.0",
4
+ "description": "Open WebUI \u2014 chat frontend for OpenAI-compatible backends, Postgres persistence, uploads/RAG storage, OIDC SSO, optional Redis cache",
5
5
  "license": "MIT",
6
6
  "author": "Berget AI AB",
7
7
  "homepage": "https://r8s.berget.ai",
@@ -29,13 +29,20 @@
29
29
  },
30
30
  "category": "AI & Assistants",
31
31
  "dependencies": {
32
- "@r8s/core": "^0.2.0",
33
- "@r8s/crds": "^0.2.0",
34
- "@r8s/k8s-types": "^0.2.0",
35
- "@r8s/recipes": "^0.2.0"
32
+ "@r8s/core": "^0.3.0",
33
+ "@r8s/crds": "^0.3.0",
34
+ "@r8s/k8s-types": "^0.3.0",
35
+ "@r8s/recipes": "^0.3.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "typescript": "^5.3.0",
39
- "vitest": "^1.0.0"
39
+ "vitest": "^1.0.0",
40
+ "@r8s/operator-redis": "^0.22.0"
41
+ },
42
+ "files": [
43
+ "dist"
44
+ ],
45
+ "peerDependencies": {
46
+ "@r8s/operator-redis": "^0.22.0"
40
47
  }
41
48
  }