mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-29 16:19:43 +08:00
chore: update config template (#15344)
This commit is contained in:
@@ -1,23 +0,0 @@
|
|||||||
# select a revision to deploy, available values: stable, beta, canary
|
|
||||||
AFFINE_REVISION=stable
|
|
||||||
|
|
||||||
# set the port for the server container it will expose the server on
|
|
||||||
PORT=3010
|
|
||||||
|
|
||||||
# set the host for the server for outgoing links
|
|
||||||
# AFFINE_SERVER_HTTPS=true
|
|
||||||
# AFFINE_SERVER_HOST=affine.yourdomain.com
|
|
||||||
# or
|
|
||||||
# AFFINE_SERVER_EXTERNAL_URL=https://affine.yourdomain.com
|
|
||||||
|
|
||||||
# position of the database data to persist
|
|
||||||
DB_DATA_LOCATION=~/.affine/self-host/postgres/pgdata
|
|
||||||
# position of the upload data(images, files, etc.) to persist
|
|
||||||
UPLOAD_LOCATION=~/.affine/self-host/storage
|
|
||||||
# position of the configuration files to persist
|
|
||||||
CONFIG_LOCATION=~/.affine/self-host/config
|
|
||||||
|
|
||||||
# database credentials
|
|
||||||
DB_USERNAME=affine
|
|
||||||
DB_PASSWORD=
|
|
||||||
DB_DATABASE=affine
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
name: affine
|
name: affine
|
||||||
services:
|
services:
|
||||||
affine:
|
affine:
|
||||||
image: ghcr.io/toeverything/affine:${AFFINE_REVISION:-stable}
|
image: ghcr.io/toeverything/affine:stable
|
||||||
container_name: affine_server
|
container_name: affine_server
|
||||||
ports:
|
ports:
|
||||||
- '${PORT:-3010}:3010'
|
- '3010:3010'
|
||||||
depends_on:
|
depends_on:
|
||||||
redis:
|
redis:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
@@ -13,30 +13,24 @@ services:
|
|||||||
affine_migration:
|
affine_migration:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
volumes:
|
volumes:
|
||||||
# custom configurations
|
- ./data/storage:/root/.affine/storage
|
||||||
- ${UPLOAD_LOCATION}:/root/.affine/storage
|
- ./config:/root/.affine/config
|
||||||
- ${CONFIG_LOCATION}:/root/.affine/config
|
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
environment:
|
environment:
|
||||||
- REDIS_SERVER_HOST=redis
|
- REDIS_SERVER_HOST=redis
|
||||||
- DATABASE_URL=postgresql://${DB_USERNAME}:${DB_PASSWORD}@postgres:5432/${DB_DATABASE:-affine}
|
- DATABASE_URL=postgresql://affine@postgres:5432/affine
|
||||||
- AFFINE_INDEXER_ENABLED=false
|
- AFFINE_INDEXER_ENABLED=false
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
affine_migration:
|
affine_migration:
|
||||||
image: ghcr.io/toeverything/affine:${AFFINE_REVISION:-stable}
|
image: ghcr.io/toeverything/affine:stable
|
||||||
container_name: affine_migration_job
|
container_name: affine_migration_job
|
||||||
volumes:
|
volumes:
|
||||||
# custom configurations
|
- ./data/storage:/root/.affine/storage
|
||||||
- ${UPLOAD_LOCATION}:/root/.affine/storage
|
- ./config:/root/.affine/config
|
||||||
- ${CONFIG_LOCATION}:/root/.affine/config
|
|
||||||
command: ['sh', '-c', 'node ./scripts/self-host-predeploy.js']
|
command: ['sh', '-c', 'node ./scripts/self-host-predeploy.js']
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
environment:
|
environment:
|
||||||
- REDIS_SERVER_HOST=redis
|
- REDIS_SERVER_HOST=redis
|
||||||
- DATABASE_URL=postgresql://${DB_USERNAME}:${DB_PASSWORD}@postgres:5432/${DB_DATABASE:-affine}
|
- DATABASE_URL=postgresql://affine@postgres:5432/affine
|
||||||
- AFFINE_INDEXER_ENABLED=false
|
- AFFINE_INDEXER_ENABLED=false
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
@@ -58,18 +52,14 @@ services:
|
|||||||
image: pgvector/pgvector:pg16
|
image: pgvector/pgvector:pg16
|
||||||
container_name: affine_postgres
|
container_name: affine_postgres
|
||||||
volumes:
|
volumes:
|
||||||
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
|
- ./data/postgres:/var/lib/postgresql/data
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: ${DB_USERNAME}
|
POSTGRES_USER: affine
|
||||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
POSTGRES_DB: affine
|
||||||
POSTGRES_DB: ${DB_DATABASE:-affine}
|
|
||||||
POSTGRES_INITDB_ARGS: '--data-checksums'
|
POSTGRES_INITDB_ARGS: '--data-checksums'
|
||||||
# you better set a password for you database
|
|
||||||
# or you may add 'POSTGRES_HOST_AUTH_METHOD=trust' to ignore postgres security policy
|
|
||||||
POSTGRES_HOST_AUTH_METHOD: trust
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test:
|
test: ['CMD', 'pg_isready', '-U', 'affine', '-d', 'affine']
|
||||||
['CMD', 'pg_isready', '-U', "${DB_USERNAME}", '-d', "${DB_DATABASE:-affine}"]
|
|
||||||
interval: 10s
|
interval: 10s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 5
|
retries: 5
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://github.com/toeverything/affine/releases/latest/download/config.schema.json",
|
||||||
|
"server": {
|
||||||
|
"name": "AFFiNE Self-hosted",
|
||||||
|
"externalUrl": "http://localhost:3010"
|
||||||
|
},
|
||||||
|
"copilot": {
|
||||||
|
"enabled": true,
|
||||||
|
"byok": {
|
||||||
|
"enabled": true,
|
||||||
|
"allowCustomEndpoint": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1140,17 +1140,17 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"enabled": {
|
"enabled": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Whether to enable the copilot plugin. <br> Document: <a href=\"https://docs.affine.pro/self-host-affine/administer/ai\" target=\"_blank\">https://docs.affine.pro/self-host-affine/administer/ai</a>\n@default false",
|
"description": "Enable AI features. Workspace owners configure provider keys in Workspace Settings → Integrations → AI BYOK.\n@default false",
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"byok.enabled": {
|
"byok.enabled": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Whether to enable workspace BYOK.\n@default true",
|
"description": "Allow workspace owners and admins to configure AI provider keys through AI BYOK.\n@default true",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
"byok.allowedProviders": {
|
"byok.allowedProviders": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"description": "The allowlist for workspace BYOK providers.\n@default [\"openai\",\"anthropic\",\"gemini\",\"fal\"]",
|
"description": "AI providers that workspace owners and admins may add through AI BYOK.\n@default [\"openai\",\"anthropic\",\"gemini\",\"fal\"]",
|
||||||
"default": [
|
"default": [
|
||||||
"openai",
|
"openai",
|
||||||
"anthropic",
|
"anthropic",
|
||||||
@@ -1160,7 +1160,7 @@
|
|||||||
},
|
},
|
||||||
"byok.allowCustomEndpoint": {
|
"byok.allowCustomEndpoint": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Whether workspace BYOK custom endpoints are accepted.\n@default false",
|
"description": "Allow AI BYOK keys to use a custom provider endpoint.\n@default false",
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"byok.allowPrivateEndpoint": {
|
"byok.allowPrivateEndpoint": {
|
||||||
|
|||||||
@@ -413,7 +413,7 @@ jobs:
|
|||||||
- name: Copy Selfhost Release Files
|
- name: Copy Selfhost Release Files
|
||||||
run: |
|
run: |
|
||||||
cp ./.docker/selfhost/compose.yml ./release/docker-compose.yml
|
cp ./.docker/selfhost/compose.yml ./release/docker-compose.yml
|
||||||
cp ./.docker/selfhost/.env.example ./release/.env.example
|
cp ./.docker/selfhost/config.json.example ./release/config.json.example
|
||||||
cp ./.docker/selfhost/schema.json ./release/config.schema.json
|
cp ./.docker/selfhost/schema.json ./release/config.schema.json
|
||||||
- name: Generate Release yml
|
- name: Generate Release yml
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -217,21 +217,21 @@ declare global {
|
|||||||
|
|
||||||
defineModuleConfig('copilot', {
|
defineModuleConfig('copilot', {
|
||||||
enabled: {
|
enabled: {
|
||||||
desc: 'Whether to enable the copilot plugin. <br> Document: <a href="https://docs.affine.pro/self-host-affine/administer/ai" target="_blank">https://docs.affine.pro/self-host-affine/administer/ai</a>',
|
desc: 'Enable AI features. Workspace owners configure provider keys in Workspace Settings → Integrations → AI BYOK.',
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
'byok.enabled': {
|
'byok.enabled': {
|
||||||
desc: 'Whether to enable workspace BYOK.',
|
desc: 'Allow workspace owners and admins to configure AI provider keys through AI BYOK.',
|
||||||
default: true,
|
default: true,
|
||||||
shape: z.boolean(),
|
shape: z.boolean(),
|
||||||
},
|
},
|
||||||
'byok.allowedProviders': {
|
'byok.allowedProviders': {
|
||||||
desc: 'The allowlist for workspace BYOK providers.',
|
desc: 'AI providers that workspace owners and admins may add through AI BYOK.',
|
||||||
default: ['openai', 'anthropic', 'gemini', 'fal'],
|
default: ['openai', 'anthropic', 'gemini', 'fal'],
|
||||||
shape: z.array(z.enum(['openai', 'anthropic', 'gemini', 'fal'])),
|
shape: z.array(z.enum(['openai', 'anthropic', 'gemini', 'fal'])),
|
||||||
},
|
},
|
||||||
'byok.allowCustomEndpoint': {
|
'byok.allowCustomEndpoint': {
|
||||||
desc: 'Whether workspace BYOK custom endpoints are accepted.',
|
desc: 'Allow AI BYOK keys to use a custom provider endpoint.',
|
||||||
default: false,
|
default: false,
|
||||||
shape: z.boolean(),
|
shape: z.boolean(),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -33,9 +33,6 @@ export const Workspaces = lazy(
|
|||||||
export const Queue = lazy(
|
export const Queue = lazy(
|
||||||
() => import(/* webpackChunkName: "queue" */ './modules/queue')
|
() => import(/* webpackChunkName: "queue" */ './modules/queue')
|
||||||
);
|
);
|
||||||
export const AI = lazy(
|
|
||||||
() => import(/* webpackChunkName: "ai" */ './modules/ai')
|
|
||||||
);
|
|
||||||
export const About = lazy(
|
export const About = lazy(
|
||||||
() => import(/* webpackChunkName: "about" */ './modules/about')
|
() => import(/* webpackChunkName: "about" */ './modules/about')
|
||||||
);
|
);
|
||||||
@@ -131,7 +128,12 @@ export const App = () => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Route path={`${ROUTES.admin.queue}/*`} element={<Queue />} />
|
<Route path={`${ROUTES.admin.queue}/*`} element={<Queue />} />
|
||||||
<Route path={ROUTES.admin.ai} element={<AI />} />
|
<Route
|
||||||
|
path={ROUTES.admin.ai}
|
||||||
|
element={
|
||||||
|
<Navigate to={ROUTES.admin.settings.index} replace />
|
||||||
|
}
|
||||||
|
/>
|
||||||
<Route path={ROUTES.admin.about} element={<About />} />
|
<Route path={ROUTES.admin.about} element={<About />} />
|
||||||
<Route
|
<Route
|
||||||
path={ROUTES.admin.settings.index}
|
path={ROUTES.admin.settings.index}
|
||||||
|
|||||||
@@ -367,19 +367,19 @@
|
|||||||
"copilot": {
|
"copilot": {
|
||||||
"enabled": {
|
"enabled": {
|
||||||
"type": "Boolean",
|
"type": "Boolean",
|
||||||
"desc": "Whether to enable the copilot plugin. <br> Document: <a href=\"https://docs.affine.pro/self-host-affine/administer/ai\" target=\"_blank\">https://docs.affine.pro/self-host-affine/administer/ai</a>"
|
"desc": "Enable AI features. Workspace owners configure provider keys in Workspace Settings → Integrations → AI BYOK."
|
||||||
},
|
},
|
||||||
"byok.enabled": {
|
"byok.enabled": {
|
||||||
"type": "Boolean",
|
"type": "Boolean",
|
||||||
"desc": "Whether to enable workspace BYOK."
|
"desc": "Allow workspace owners and admins to configure AI provider keys through AI BYOK."
|
||||||
},
|
},
|
||||||
"byok.allowedProviders": {
|
"byok.allowedProviders": {
|
||||||
"type": "Array",
|
"type": "Array",
|
||||||
"desc": "The allowlist for workspace BYOK providers."
|
"desc": "AI providers that workspace owners and admins may add through AI BYOK."
|
||||||
},
|
},
|
||||||
"byok.allowCustomEndpoint": {
|
"byok.allowCustomEndpoint": {
|
||||||
"type": "Boolean",
|
"type": "Boolean",
|
||||||
"desc": "Whether workspace BYOK custom endpoints are accepted."
|
"desc": "Allow AI BYOK keys to use a custom provider endpoint."
|
||||||
},
|
},
|
||||||
"byok.allowPrivateEndpoint": {
|
"byok.allowPrivateEndpoint": {
|
||||||
"type": "Boolean",
|
"type": "Boolean",
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
import { Switch } from '@affine/admin/components/ui/switch';
|
|
||||||
import { cn } from '@affine/admin/utils';
|
|
||||||
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
|
|
||||||
import { useState } from 'react';
|
|
||||||
|
|
||||||
import { Header } from '../header';
|
|
||||||
|
|
||||||
function AiPage() {
|
|
||||||
const [enableAi, setEnableAi] = useState(false);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="h-dvh flex-1 flex-col flex">
|
|
||||||
<Header title="AI" />
|
|
||||||
<ScrollAreaPrimitive.Root
|
|
||||||
className={cn('relative overflow-hidden w-full')}
|
|
||||||
>
|
|
||||||
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit] [&>div]:!block">
|
|
||||||
<div className="p-6 max-w-3xl mx-auto">
|
|
||||||
<div className="text-[20px]">AI</div>
|
|
||||||
<div className="flex justify-between items-center">
|
|
||||||
<div>
|
|
||||||
<p className="text-sm font-medium mt-6">Enable AI</p>
|
|
||||||
<p className="text-sm text-muted-foreground mt-1">
|
|
||||||
AI functionality is not currently supported. Self-hosted AI
|
|
||||||
support is in progress.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Switch
|
|
||||||
checked={enableAi}
|
|
||||||
onCheckedChange={setEnableAi}
|
|
||||||
disabled={true}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ScrollAreaPrimitive.Viewport>
|
|
||||||
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
|
||||||
className={cn(
|
|
||||||
'flex touch-none select-none transition-colors',
|
|
||||||
'h-full w-2.5 border-l border-l-transparent p-[1px]'
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
|
|
||||||
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
||||||
<ScrollAreaPrimitive.Corner />
|
|
||||||
</ScrollAreaPrimitive.Root>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export { AiPage as Component };
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
import { Button } from '@affine/admin/components/ui/button';
|
|
||||||
import { Input } from '@affine/admin/components/ui/input';
|
|
||||||
import { Label } from '@affine/admin/components/ui/label';
|
|
||||||
import { Separator } from '@affine/admin/components/ui/separator';
|
|
||||||
import { useState } from 'react';
|
|
||||||
|
|
||||||
export function Keys() {
|
|
||||||
const [openAIKey, setOpenAIKey] = useState('');
|
|
||||||
const [falAIKey, setFalAIKey] = useState('');
|
|
||||||
const [unsplashKey, setUnsplashKey] = useState('');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col h-full gap-3 py-5 px-6 w-full">
|
|
||||||
<div className="flex items-center">
|
|
||||||
<span className="text-xl font-semibold">Keys</span>
|
|
||||||
</div>
|
|
||||||
<div className="flex-grow overflow-y-auto space-y-[10px]">
|
|
||||||
<div className="flex flex-col rounded-md border py-4 gap-4">
|
|
||||||
<div className="px-5 space-y-3">
|
|
||||||
<Label className="text-sm font-medium">OpenAI Key</Label>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Input
|
|
||||||
type="text"
|
|
||||||
className="py-2 px-3 text-base font-normal placeholder:opacity-50"
|
|
||||||
value={openAIKey}
|
|
||||||
placeholder="sk-xxxxxxxxxxxxx-xxxxxxxxxxxxxx"
|
|
||||||
onChange={e => setOpenAIKey(e.target.value)}
|
|
||||||
/>
|
|
||||||
<Button disabled>Save</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Separator />
|
|
||||||
<div className="px-5 space-y-3">
|
|
||||||
<Label className="text-sm font-medium">Fal.AI Key</Label>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Input
|
|
||||||
type="email"
|
|
||||||
className="py-2 px-3 ext-base font-normal placeholder:opacity-50"
|
|
||||||
value={falAIKey}
|
|
||||||
placeholder="00000000-0000-0000-00000000:xxxxxxxxxxxxxxxxx"
|
|
||||||
onChange={e => setFalAIKey(e.target.value)}
|
|
||||||
/>
|
|
||||||
<Button disabled>Save</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Separator />
|
|
||||||
<div className="px-5 space-y-3">
|
|
||||||
<Label className="text-sm font-medium">Unsplash Key</Label>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<Input
|
|
||||||
type="password"
|
|
||||||
className="py-2 px-3 ext-base font-normal placeholder:opacity-50"
|
|
||||||
value={unsplashKey}
|
|
||||||
placeholder="00000000-0000-0000-00000000:xxxxxxxxxxxxxxxxx"
|
|
||||||
onChange={e => setUnsplashKey(e.target.value)}
|
|
||||||
/>
|
|
||||||
<Button disabled>Save</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Separator />
|
|
||||||
<div className="px-5 space-y-3 text-sm font-normal text-muted-foreground">
|
|
||||||
Custom API keys may not perform as expected. AFFiNE does not
|
|
||||||
guarantee results when using custom API keys.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -58,12 +58,6 @@ export function Nav({ isCollapsed = false }: NavProps) {
|
|||||||
label="Queue"
|
label="Queue"
|
||||||
isCollapsed={isCollapsed}
|
isCollapsed={isCollapsed}
|
||||||
/>
|
/>
|
||||||
{/* <NavItem
|
|
||||||
to="/admin/ai"
|
|
||||||
icon={<AiOutlineIcon fontSize={20} />}
|
|
||||||
label="AI"
|
|
||||||
isCollapsed={isCollapsed}
|
|
||||||
/> */}
|
|
||||||
<SettingsItem isCollapsed={isCollapsed} />
|
<SettingsItem isCollapsed={isCollapsed} />
|
||||||
<NavItem
|
<NavItem
|
||||||
to={ROUTES.admin.about}
|
to={ROUTES.admin.about}
|
||||||
|
|||||||
@@ -147,34 +147,19 @@ export const KNOWN_CONFIG_GROUPS = [
|
|||||||
fields: ['providers.google', 'providers.github', 'providers.oidc'],
|
fields: ['providers.google', 'providers.github', 'providers.oidc'],
|
||||||
} as ConfigGroup<'oauth'>,
|
} as ConfigGroup<'oauth'>,
|
||||||
{
|
{
|
||||||
name: 'AI',
|
name: 'AI BYOK',
|
||||||
module: 'copilot',
|
module: 'copilot',
|
||||||
fields: [
|
fields: [
|
||||||
'enabled',
|
|
||||||
'providers.openai',
|
|
||||||
'providers.gemini',
|
|
||||||
'providers.anthropic',
|
|
||||||
'providers.fal',
|
|
||||||
'unsplash',
|
|
||||||
'exa',
|
|
||||||
{
|
{
|
||||||
key: 'storage',
|
key: 'enabled',
|
||||||
desc: 'The storage provider for copilot blobs',
|
desc: 'Enable AI features. Workspace owners configure provider keys in Workspace Settings → Integrations → AI BYOK.',
|
||||||
sub: 'provider',
|
|
||||||
type: 'Enum',
|
|
||||||
options: ['fs', 'aws-s3', 'cloudflare-r2'],
|
|
||||||
},
|
},
|
||||||
|
'byok.enabled',
|
||||||
|
'byok.allowedProviders',
|
||||||
|
'byok.allowCustomEndpoint',
|
||||||
{
|
{
|
||||||
key: 'storage',
|
key: 'byok.allowPrivateEndpoint',
|
||||||
sub: 'bucket',
|
desc: 'Allow workspace owners and admins to connect BYOK providers on private network endpoints. Only enable this for trusted workspaces.',
|
||||||
type: 'String',
|
|
||||||
desc: 'The bucket name for copilot blobs storage',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'storage',
|
|
||||||
sub: 'config',
|
|
||||||
type: 'JSON',
|
|
||||||
desc: 'The S3 compatible config for the storage provider (endpoint/region/credentials).',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} as ConfigGroup<'copilot'>,
|
} as ConfigGroup<'copilot'>,
|
||||||
|
|||||||
Reference in New Issue
Block a user