From 801b6ea49d9921d067f8456301d3c9c46af38056 Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 17 Nov 2025 12:40:09 -0600 Subject: [PATCH] Remove copilot env overrides and add config placeholders --- BUILD.md | 13 ++---- CloudronManifest.json | 4 +- Dockerfile | 1 - config.example.json | 33 ++++++++++++++ copilot.env.example | 24 ---------- start.sh | 88 ------------------------------------- tmp_data/config/config.json | 33 ++++++++++++++ 7 files changed, 71 insertions(+), 125 deletions(-) delete mode 100644 copilot.env.example diff --git a/BUILD.md b/BUILD.md index 76ca4e5..7c02958 100644 --- a/BUILD.md +++ b/BUILD.md @@ -13,14 +13,14 @@ cloudron build \ --set-build-service builder.docker.due.ren \ --build-service-token e3265de06b1d0e7bb38400539012a8433a74c2c96a17955e \ --set-repository andreasdueren/affine-cloudron \ - --tag 0.25.5-5 + --tag 0.25.5-6 ``` ## Deployment Steps 1. Remove any previous dev install of AFFiNE on the Cloudron (always reinstall from scratch). 2. Install the freshly built image: ```bash -cloudron install --location affine.due.ren --image andreasdueren/affine-cloudron:0.25.5-5 +cloudron install --location affine.due.ren --image andreasdueren/affine-cloudron:0.25.5-6 ``` 3. When prompted, confirm the app info and wait for Cloudron to report success (abort after ~30 seconds if installation stalls or errors to avoid hanging sessions). 4. Visit `https://affine.due.ren` (or the chosen location) and sign in using Cloudron SSO. @@ -42,11 +42,4 @@ cloudron install --location affine.due.ren --image andreasdueren/affine-cloudron - Persistent config lives in `/app/data/config/config.json`. Modify values (e.g., Stripe, throttling) and restart the app; the file is backed up by Cloudron. - Uploaded files live in `/app/data/storage` and map to `~/.affine/storage` inside the runtime. - Default health check hits `/api/healthz`; customize via `CloudronManifest.json` if upstream changes. -- Copilot providers can be configured with environment variables instead of editing `config.json`. Set any of the following via `cloudron env set --app affine.due.ren KEY=value` and restart: - - `AFFINE_COPILOT_ENABLED` (`true`/`false`) - - `AFFINE_COPILOT_OPENAI_API_KEY`, `AFFINE_COPILOT_OPENAI_BASE_URL` - - `AFFINE_COPILOT_ANTHROPIC_API_KEY`, `AFFINE_COPILOT_ANTHROPIC_BASE_URL` - - `AFFINE_COPILOT_GEMINI_API_KEY`, `AFFINE_COPILOT_GEMINI_BASE_URL` - - `AFFINE_COPILOT_EXA_KEY` for web search - - `AFFINE_COPILOT_SCENARIOS_JSON` with a JSON payload such as `{"override_enabled":true,"scenarios":{"chat":"gpt-4o-mini"}}` -- A sample `.env` file is available at `/app/data/copilot.env.example` after install; download/edit it for reference before populating Cloudron env variables. +- Copilot API keys live in `/app/data/config/config.json`. The default file contains placeholders (`sk-provide-openai-key-here`, etc.); open it in the Cloudron File Manager or via `cloudron exec` to paste your own values, then restart the app so AFFiNE picks up the changes. diff --git a/CloudronManifest.json b/CloudronManifest.json index 4bdadeb..2058b81 100644 --- a/CloudronManifest.json +++ b/CloudronManifest.json @@ -5,9 +5,9 @@ "description": "Next-gen knowledge base that blends docs, whiteboards, and databases for self-hosted teams.", "website": "https://affine.pro", "contactEmail": "support@affine.pro", - "version": "0.25.5-5", + "version": "0.25.5-6", "upstreamVersion": "0.25.5", - "changelog": "Auto seed Manticore tables (without external morphology packs)", + "changelog": "Configure copilot via config.json placeholders; env overrides removed", "icon": "file://icon.png", "manifestVersion": 2, "minBoxVersion": "7.0.0", diff --git a/Dockerfile b/Dockerfile index 0cd36a9..4472473 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,7 +42,6 @@ COPY run-buddy.sh "$APP_CODE_DIR/run-buddy.sh" COPY nginx.conf "$APP_CODE_DIR/nginx.conf" COPY supervisord.conf "$APP_CODE_DIR/supervisord.conf" COPY config.example.json "$APP_CODE_DIR/config.example.json" -COPY copilot.env.example "$APP_CODE_DIR/copilot.env.example" COPY tmp_data/ "$APP_TMP_DIR/" COPY manticore/ "$APP_CODE_DIR/manticore/" diff --git a/config.example.json b/config.example.json index 7ce286e..7269319 100644 --- a/config.example.json +++ b/config.example.json @@ -2,5 +2,38 @@ "$schema": "https://github.com/toeverything/AFFiNE/releases/latest/download/config.schema.json", "server": { "name": "AFFiNE Self Hosted Server" + }, + "copilot": { + "enabled": true, + "scenarios": { + "override_enabled": true, + "scenarios": { + "audio_transcribing": "gemini-2.5-flash", + "chat": "gemini-2.5-flash", + "embedding": "gemini-embedding-001", + "image": "gpt-image-1", + "rerank": "gpt-4.1", + "coding": "claude-sonnet-4-5@20250929", + "complex_text_generation": "gpt-4o-2024-08-06", + "quick_decision_making": "gpt-5-mini", + "quick_text_generation": "gemini-2.5-flash", + "polish_and_summarize": "gemini-2.5-flash" + } + }, + "providers.openai": { + "apiKey": "sk-provide-openai-key-here", + "baseURL": "https://api.openai.com/v1" + }, + "providers.anthropic": { + "apiKey": "sk-ant-provide-anthropic-key-here", + "baseURL": "https://api.anthropic.com/v1" + }, + "providers.gemini": { + "apiKey": "provide-gemini-key-here", + "baseURL": "https://generativelanguage.googleapis.com/v1beta" + }, + "exa": { + "key": "provide-exa-key-or-leave-empty" + } } } diff --git a/copilot.env.example b/copilot.env.example deleted file mode 100644 index 89d4f4e..0000000 --- a/copilot.env.example +++ /dev/null @@ -1,24 +0,0 @@ -# AFFiNE Copilot sample environment overrides -# Copy this file to .env (or use Cloudron's env UI) and adjust values. - -# Toggle Copilot globally (true/false). -AFFINE_COPILOT_ENABLED=true - -# OpenAI-compatible provider (Official OpenAI, OpenRouter, local proxy, etc.). -AFFINE_COPILOT_OPENAI_API_KEY=sk-your-openai-key -AFFINE_COPILOT_OPENAI_BASE_URL=https://api.openai.com/v1 - -# Anthropic Claude provider. -AFFINE_COPILOT_ANTHROPIC_API_KEY=sk-ant-your-key -AFFINE_COPILOT_ANTHROPIC_BASE_URL=https://api.anthropic.com/v1 - -# Google Gemini provider (API key or reverse proxy). -AFFINE_COPILOT_GEMINI_API_KEY=your-gemini-key -AFFINE_COPILOT_GEMINI_BASE_URL=https://generativelanguage.googleapis.com/v1beta - -# Optional Exa web search key for Copilot browsing. -AFFINE_COPILOT_EXA_KEY=exa-key - -# Override the scenario/model mapping by providing JSON. -# Example keeps override_enabled true and customizes a few models. -AFFINE_COPILOT_SCENARIOS_JSON={"override_enabled":true,"scenarios":{"chat":"gpt-4o-mini","coding":"claude-3-5-sonnet-20241022","embedding":"text-embedding-3-large","quick_text_generation":"gpt-4o-mini"}} diff --git a/start.sh b/start.sh index e5e61a3..15a8cf9 100644 --- a/start.sh +++ b/start.sh @@ -46,13 +46,6 @@ prepare_data_dirs() { cp "$APP_TMP_DIR/config/config.json" "$APP_DATA_DIR/config/config.json" fi - local sample_env_src="$APP_CODE_DIR/copilot.env.example" - local sample_env_dest="$APP_DATA_DIR/copilot.env.example" - if [ -f "$sample_env_src" ] && [ ! -f "$sample_env_dest" ]; then - cp "$sample_env_src" "$sample_env_dest" - chown cloudron:cloudron "$sample_env_dest" - fi - local storage_contents="" if [ -d "$APP_DATA_DIR/storage" ]; then storage_contents=$(ls -A "$APP_DATA_DIR/storage" 2>/dev/null || true) @@ -360,86 +353,6 @@ PY fi } -configure_copilot_env_overrides() { - local config_path="$APP_DATA_DIR/config/config.json" - if [ ! -f "$config_path" ]; then - log "Copilot config file not found at ${config_path}, skipping env overrides" - return - fi - python3 - "$config_path" <<'PY' -import json -import os -import sys -from pathlib import Path - -path = Path(sys.argv[1]) -data = json.loads(path.read_text()) -copilot = data.setdefault('copilot', {}) -changed = False - -def set_nested(keys, value): - global changed - ref = copilot - for key in keys[:-1]: - ref = ref.setdefault(key, {}) - if ref.get(keys[-1]) != value: - ref[keys[-1]] = value - print(f"[copilot] Set {'.'.join(keys)} from environment") - changed = True - -def coerce_bool(value): - if isinstance(value, bool): - return value - v = value.strip().lower() - if v in ('1', 'true', 'yes', 'on'): - return True - if v in ('0', 'false', 'no', 'off'): - return False - raise ValueError(f"Invalid boolean value: {value}") - -mapping = [ - ('AFFINE_COPILOT_ENABLED', ('enabled',), coerce_bool), - ('AFFINE_COPILOT_OPENAI_API_KEY', ('providers.openai', 'apiKey'), str), - ('AFFINE_COPILOT_OPENAI_BASE_URL', ('providers.openai', 'baseURL'), str), - ('AFFINE_COPILOT_ANTHROPIC_API_KEY', ('providers.anthropic', 'apiKey'), str), - ('AFFINE_COPILOT_ANTHROPIC_BASE_URL', ('providers.anthropic', 'baseURL'), str), - ('AFFINE_COPILOT_GEMINI_API_KEY', ('providers.gemini', 'apiKey'), str), - ('AFFINE_COPILOT_GEMINI_BASE_URL', ('providers.gemini', 'baseURL'), str), - ('AFFINE_COPILOT_EXA_KEY', ('exa', 'key'), str), -] - -for env_name, path_keys, caster in mapping: - value = os.environ.get(env_name) - if not value: - continue - try: - coerced = caster(value) - except Exception as exc: - print(f"[copilot] Skipping {env_name}: {exc}", flush=True) - continue - set_nested(path_keys, coerced) - -scenarios_json = os.environ.get('AFFINE_COPILOT_SCENARIOS_JSON') -if scenarios_json: - try: - payload = json.loads(scenarios_json) - if not isinstance(payload, dict) or 'scenarios' not in payload: - raise ValueError("JSON must contain a 'scenarios' object") - except Exception as exc: - print(f"[copilot] Invalid AFFINE_COPILOT_SCENARIOS_JSON: {exc}", flush=True) - else: - copilot.setdefault('scenarios', {}) - copilot['scenarios']['override_enabled'] = payload.get('override_enabled', True) - copilot['scenarios']['scenarios'] = payload['scenarios'] - print("[copilot] Applied scenarios override from AFFINE_COPILOT_SCENARIOS_JSON") - changed = True - -if changed: - path.write_text(json.dumps(data, indent=2)) -PY - log "Applied copilot env configuration overrides (if any)" -} - update_server_config() { python3 - <<'PY' import json @@ -472,7 +385,6 @@ main() { configure_indexer update_server_config configure_auth - configure_copilot_env_overrides chown -R cloudron:cloudron "$APP_DATA_DIR" "$APP_HOME_DIR" log "Starting supervisor" exec /usr/bin/supervisord -c "$APP_CODE_DIR/supervisord.conf" diff --git a/tmp_data/config/config.json b/tmp_data/config/config.json index 7ce286e..7269319 100644 --- a/tmp_data/config/config.json +++ b/tmp_data/config/config.json @@ -2,5 +2,38 @@ "$schema": "https://github.com/toeverything/AFFiNE/releases/latest/download/config.schema.json", "server": { "name": "AFFiNE Self Hosted Server" + }, + "copilot": { + "enabled": true, + "scenarios": { + "override_enabled": true, + "scenarios": { + "audio_transcribing": "gemini-2.5-flash", + "chat": "gemini-2.5-flash", + "embedding": "gemini-embedding-001", + "image": "gpt-image-1", + "rerank": "gpt-4.1", + "coding": "claude-sonnet-4-5@20250929", + "complex_text_generation": "gpt-4o-2024-08-06", + "quick_decision_making": "gpt-5-mini", + "quick_text_generation": "gemini-2.5-flash", + "polish_and_summarize": "gemini-2.5-flash" + } + }, + "providers.openai": { + "apiKey": "sk-provide-openai-key-here", + "baseURL": "https://api.openai.com/v1" + }, + "providers.anthropic": { + "apiKey": "sk-ant-provide-anthropic-key-here", + "baseURL": "https://api.anthropic.com/v1" + }, + "providers.gemini": { + "apiKey": "provide-gemini-key-here", + "baseURL": "https://generativelanguage.googleapis.com/v1beta" + }, + "exa": { + "key": "provide-exa-key-or-leave-empty" + } } }