openvibers/openvibe.search .env.example
.env.example
| 1 | # ═══════════════════════════════════════════════════════════════ |
| 2 | # OpenVibe.Search — Environment Configuration |
| 3 | # Copy to .env and fill in values. |
| 4 | # In production this lives at /etc/openvibe/search.env (0600); the systemd unit sets |
| 5 | # NODE_ENV and PORT itself. |
| 6 | # ═══════════════════════════════════════════════════════════════ |
| 7 | |
| 8 | # Server |
| 9 | PORT=4710 |
| 10 | HOST=127.0.0.1 |
| 11 | NODE_ENV=development |
| 12 | #BASE_URL=https://search.openvibe.network |
| 13 | |
| 14 | # Identity — OpenVibe.Network signs service tokens (client_credentials, audience |
| 15 | # openvibe.search) and user JWTs. The keys come from the SDK's JWKS client |
| 16 | # (openvibe-sdk/auth) at <OV_NETWORK_INTERNAL_URL>/api/.well-known/jwks: one |
| 17 | # refresher, last good keys through an outage, a rotation honoured at once. |
| 18 | OV_NETWORK_URL=https://openvibe.network |
| 19 | OV_NETWORK_INTERNAL_URL=http://127.0.0.1:4000 |
| 20 | #OV_NETWORK_ISSUER=https://openvibe.network |
| 21 | # A browser's user JWT is accepted when its aud contains one of these. |
| 22 | #SEARCH_USER_AUDIENCES=openvibe.search,openvibe.network |
| 23 | |
| 24 | # This service's own principal (svc:search) — publishes search.document.* to Events |
| 25 | # (events.event.publish) and creates its subscription (events.subscription.manage); with |
| 26 | # SEARCH_SAVED_NOTIFY=1 also resolves people and pushes notifications on Network. |
| 27 | OV_OAUTH_CLIENT_ID=search |
| 28 | OV_OAUTH_CLIENT_SECRET= |
| 29 | |
| 30 | # Store (PostgreSQL, ADR-035), written by OpenVibe.Host roles/data/add-service.sh search: the runtime role through |
| 31 | # PgBouncer, the owner on a direct connection (migrations), and Valkey (shared limit counters). |
| 32 | # Without DATABASE_URL, development uses an embedded PGlite database in data/pglite. |
| 33 | DATABASE_URL= |
| 34 | DATABASE_DIRECT_URL= |
| 35 | VALKEY_URL= |
| 36 | VALKEY_PREFIX= |
| 37 | |
| 38 | # OpenVibe.Events. The outbox relay runs only when EVENTS_URL is set. |
| 39 | #EVENTS_URL=http://127.0.0.1:4300 |
| 40 | #EVENTS_RELAY_INTERVAL_MS=2000 |
| 41 | # Signing secret(s) of the index-document subscription (comma-separated during rotation). |
| 42 | # Generate before `npm run subscribe`, e.g. `openssl rand -hex 32`. Unset = webhook off (503). |
| 43 | #SEARCH_EVENTS_SECRET= |
| 44 | # Sources whose <source>.index_document.* events are accepted (default: wiki blog news reviews |
| 45 | # deals coupons trade community live media codes games tools sources). |
| 46 | #SEARCH_EVENT_OWNERS=wiki,blog,news |
| 47 | |
| 48 | # Largest accepted request body (direct PUT and deliveries), bytes. |
| 49 | #SEARCH_MAX_BODY_BYTES=262144 |
| 50 | |
| 51 | # Ranking: freshness weighting of full-text relevance (README "Ranking"). |
| 52 | # score = relevance × (1 + WEIGHT × 2^(−age_days / HALF_LIFE_DAYS)); age from published_at, else |
| 53 | # updated_at. WEIGHT 0 turns it off. |
| 54 | #SEARCH_FRESHNESS_WEIGHT=1 |
| 55 | #SEARCH_FRESHNESS_HALF_LIFE_DAYS=30 |
| 56 | |
| 57 | # Search Fabric (README "Search Fabric"): the web ladder through OpenVibe.AI. |
| 58 | # AI's internal origin; unset uses the AI manifest's internalOrigin. Needs OV_OAUTH_CLIENT_SECRET above. |
| 59 | #OV_AI_INTERNAL_URL=http://127.0.0.1:4700 |
| 60 | # off leaves the paid/free web providers off; the open index and cached answers still answer. |
| 61 | #SEARCH_WEB=on |
| 62 | # Paid DeepSeek calls per day across all callers; past it the provider stands down. |
| 63 | #SEARCH_WEB_DAILY=500 |
| 64 | # Owners whose documents the ladder's own open index reads first. |
| 65 | #SEARCH_OPEN_INDEX_OWNERS=sources |
| 66 | |
| 67 | # Semantic ranking (SF-2, README "Semantic ranking"): every public document gets one local |
| 68 | # `bge-small-en-v1.5` embedding (384 dimensions) through OpenVibe.AI's POST /api/v1/embed, and a |
| 69 | # query's keyword and vector ranks are fused with reciprocal rank fusion (k = 60). AI must serve |
| 70 | # the embedding through its local provider (AI_LOCAL_EMBED_MODEL=bge-small-en-v1.5) and Network must |
| 71 | # grant this principal `ai.run.create` with namespace `ai.embed` for audience openvibe.ai. |
| 72 | # The job is on unless SEARCH_EMBED=0. At most SEARCH_EMBED_PER_MIN documents are embedded per |
| 73 | # rolling minute (batches of 32); SEARCH_EMBED_INTERVAL_MS is how often a pass starts. |
| 74 | #SEARCH_EMBED=1 |
| 75 | #SEARCH_EMBED_MODEL=bge-small-en-v1.5 |
| 76 | #SEARCH_EMBED_DIM=384 |
| 77 | #SEARCH_EMBED_PER_MIN=120 |
| 78 | #SEARCH_EMBED_INTERVAL_MS=60000 |
| 79 | # Restore-drill mode: background work stays off (the drill also blanks OV_OAUTH_CLIENT_SECRET). |
| 80 | #SEARCH_DRILL=1 |
| 81 | |
| 82 | # Code search (server/code): GET /api/v1/search/code merges public code from GitHub, Sourcegraph and |
| 83 | # our own forge. Keys stay server-side; the owner console at /console/code-sources shows the variable |
| 84 | # name and whether it is set, never the value. SEARCH_CODE=off turns the public route off. |
| 85 | #GITHUB_CODE_TOKEN= # required for GitHub; 10 API requests/minute |
| 86 | #SOURCEGRAPH_TOKEN= # optional; Sourcegraph Cloud answers public searches without one |
| 87 | #FORGE_TOKEN= # optional; only needed if the forge starts requiring auth |
| 88 | #FORGE_CODE_REPOS= # optional owner/repo list; default: newest pushed public repos |
| 89 | #SEARCH_CODE_TIMEOUT_MS=8000 |
| 90 | #SEARCH_CODE_CACHE_MS=60000 |
| 91 | #SEARCH_FORGE_MAX_REPOS=20 |
| 92 | #SEARCH_GITHUB_PER_MINUTE=10 |
| 93 | #SEARCH_SOURCEGRAPH_PER_MINUTE=30 |
| 94 | #SEARCH_FORGE_PER_MINUTE=60 |
| 95 | # Deep mode: POST /api/v1/search/code/deep, signed in; two ai.complete runs (rewrite + answer) through |
| 96 | # OpenVibe.AI, which is the metered AI path. SEARCH_CODE_DEEP=off hides it; the budget caps are hard. |
| 97 | #SEARCH_CODE_DEEP=1 |
| 98 | #SEARCH_CODE_AI_URL=http://127.0.0.1:4700 |
| 99 | #SEARCH_CODE_DEEP_QUERIES=4 |
| 100 | #SEARCH_CODE_DEEP_FILES=6 |
| 101 | #SEARCH_CODE_DEEP_CHARS=24000 |
| 102 | #SEARCH_CODE_DEEP_TOKENS=800 |
| 103 | #SEARCH_CODE_DEEP_WAIT_MS=25000 |
| 104 | #SEARCH_CODE_DEEP_TIMEOUT_MS=120000 |
| 105 | |
| 106 | # Saved searches per signed-in person. |
| 107 | #SEARCH_SAVED_MAX_PER_SUBJECT=50 |
| 108 | # Notifications of new matches through OpenVibe.Network (README "Saved searches"): off unless 1, and |
| 109 | # then only with OV_OAUTH_CLIENT_SECRET above. Network must grant the principal `search` |
| 110 | # network.notifications.push (own service `search`) and identity.subject.resolve. |
| 111 | #SEARCH_SAVED_NOTIFY=1 |
| 112 | #SEARCH_SAVED_NOTIFY_INTERVAL_MS=900000 |
| 113 | #SEARCH_SAVED_NOTIFY_BATCH=100 |
| 114 | |
| 115 | # Per-actor limits (server/actor-limits.js): requests one caller (a service principal, a signed-in |
| 116 | # person, else an address) may make to a read route per minute and per hour; past them 429 |
| 117 | # rate_limited with Retry-After. Indexing, suggest and saved-search changes have their own (README). |
| 118 | #SEARCH_LIMITS_MINUTE=120 |
| 119 | #SEARCH_LIMITS_HOUR=3000 |
| 120 | |
| 121 | # IndexNow (openvibe-shared/indexnow): Search publishes no pages of its own to submit, so only the |
| 122 | # key file is served, at /<key>.txt, when INDEXNOW_KEY is set. Unset: off (nothing mounted, nothing sent). |
| 123 | #INDEXNOW_KEY= |
| 124 | |
| 125 | # Removal purge queue (README "Removals, caches and the CDN"). Every removal is recorded for |
| 126 | # its owner (GET /api/v1/owners/:owner/removals). The Cloudflare purge of a formerly public URL |
| 127 | # runs only when CLOUDFLARE_PURGE_TOKEN is set (inert otherwise). The token needs only |
| 128 | # Zone → Cache Purge → Purge on the zones below. Never commit it: /etc/openvibe/search.env (0600). |
| 129 | #CLOUDFLARE_PURGE_TOKEN= |
| 130 | # host=zone id pairs; a URL uses the zone of its host or nearest parent domain. |
| 131 | #CLOUDFLARE_ZONE_IDS=openvibe.wiki=<zone id>,openvibe.blog=<zone id>,openvibe.network=<zone id> |
| 132 | # Paths on the removed URL's host purged with it (default /sitemap.xml; `none` for none). |
| 133 | #CLOUDFLARE_PURGE_RELATED_PATHS=/sitemap.xml,/feed.atom,/feed.json |
| 134 | #CLOUDFLARE_PURGE_INTERVAL_MS=5000 |
| 135 |