# Server configuration fields For initial setup, run `openviking-server init`, then run `openviking-server doctor` after saving the configuration. The OpenViking server reads `ov.conf`. The default path is: ```text ~/.openviking/ov.conf ``` Use an environment variable or startup option to select another file: ```bash export OPENVIKING_CONFIG_FILE=/path/to/ov.conf openviking-server --config /path/to/ov.conf ``` The server reads the file at startup. Restart the server after changing models, retrieval, storage, or `server` settings, then run `openviking-server doctor`. Studio's **Server configuration** page offers **Save and restart** for a single-worker `openviking-server` process. The existing ROOT-only `GET /api/v1/admin/configuration?source=file` includes restart capability and instance identity. Only ROOT can request a restart (`POST /api/v1/admin/restart`, body `{"revision":""}`). The server validates the current file and its revision, returns HTTP 202, drains active requests, stops its managed Bot, then replaces itself using the original interpreter, arguments, environment and working directory. Studio waits for a new service instance before reporting success. **Save configuration** alone continues to save without restarting. Multi-worker or embedded ASGI applications report restart as unsupported; restart these through the deployment platform. Startup can still fail because of external dependencies even after schema validation. If the address, port or ROOT credential changes, update Studio's connection settings to reconnect. Account and cluster overrides continue to take precedence over file defaults. Configurations containing environment references are read-only in the Studio form. Use file mode to edit the original text; quoted/unquoted references, escapes and formatting are saved as submitted. Windows `%VAR%` references and dollar/percent literals (including `\u0024` and `\u0025`) also use file mode to avoid introducing new references during form serialization. ## Configuration Structure This outline shows common top-level groups, not a runnable configuration. For a first deployment, start with the [minimal example](#minimal-example) and supply your models and credentials. Merge later snippets into the same `ov.conf`. ```json { "embedding": {}, "vlm": {}, "query_planner": {}, "rerank": {}, "retrieval": {}, "storage": {}, "server": {}, "memory": {}, "parsers": {}, "encryption": {}, "log": {}, "telemetry": {} } ``` Optional sections use their defaults when omitted. Unknown fields in `ov.conf` and persisted account settings are ignored for upgrade compatibility, except in the `gateway` section. Known fields still validate types and values. Misspelled field names are also ignored, but the server logs a warning listing every field it did not apply. ## Top-Level Settings | Setting | Type / values | Default | Purpose | |---|---|---|---| | `default_account` | string | `"default"` | Default account for the service context | | `default_user` | string | `"default"` | Default user for the service context | | `embedding` | object | built-in local dense model | Dense, sparse, and hybrid embedding; defaults to `local` / `bge-small-zh-v1.5-f16` | | `vlm` | object | empty config | Content understanding, summaries, and memory extraction; configure a working model before using these capabilities | | `query_planner` | object / `null` | `null` | Model for retrieval intent analysis and recall rewriting. Falls back to `vlm` when omitted or empty; recall rewrite in `auto` mode requires a configured cluster `query_planner` or an account-level `query_planner` or `vlm` override | | `rerank` | object | disabled | Retrieval result reranking | | `retrieval` | object | see below | Ranking and intent-analysis behavior | | `grep` | object | built-in defaults | Text search engine | | `glob` | object | built-in defaults | Path glob engine | | `storage` | object | local | Workspace, file system, and vector database | | `queue_workers` | object | see below | Runtime concurrency for QueueFS consumer workers | | `server` | object | local development | HTTP, authentication, uploads, and observability | | `memory` | object | see below | Memory and skill extraction on session commit | | `parsers` | object | parser defaults | PDF, code, image, audio, video, and text parsing | | `semantic` | object | built-in defaults | Abstract and overview generation limits | | `parser_api` | object | disabled | Third-party file parser API | | `compile_api` | object | disabled | External Compile task API | | `connector` | object | disabled | External Connector ingestion service | | `encryption` | object | disabled | File and secret encryption | | `git` | object | local | Version backend: `local` or `s3` | | `log` | object | console | Log level, format, and file output | | `telemetry` | object | disabled | OpenTelemetry tracing | | `oauth` | object | disabled | MCP OAuth 2.1 | | `gateway` | object | disabled | OpenViking Gateway, the model API gateway that adds OpenViking memory to API-key clients. Unknown keys in this section are errors. See the [configuration reference](../guides/22-gateway-operations.md#configuration-reference) | | `prompts` | object | built-in templates | Custom prompt template directory | | `ingest` | object | built-in defaults | Conversation-log ingestion | | `output_language_override` | string | `""` | Force summary/memory language; empty means auto-detect | | `allow_private_networks` | boolean | `false` | Allow fetching private-network resources | `auto_generate_l0`, `auto_generate_l1`, `default_search_mode`, and `default_search_limit` are deprecated compatibility fields. They are accepted when loading older configuration files but have no runtime effect. ## Model Settings API-based `embedding`, `vlm`, `query_planner`, and `rerank` configurations reuse some field names, but each module has its own schema. Use only fields supported by the applicable module below. ```json { "embedding": { "dense": { "provider": "volcengine", "model": "doubao-embedding-vision-251215", "api_base": "https://ark.cn-beijing.volces.com/api/v3", "api_key": "", "dimension": 1024, "input": "multimodal" } }, "vlm": { "provider": "volcengine", "model": "doubao-seed-2-0-code-preview-260215", "api_base": "https://ark.cn-beijing.volces.com/api/v3", "api_key": "", "temperature": 0, "max_retries": 3, "thinking": false }, "query_planner": { "provider": "volcengine", "model": "doubao-seed-2-0-code-preview-260215", "api_base": "https://ark.cn-beijing.volces.com/api/v3", "api_key": "", "thinking": false }, "rerank": { "provider": "vikingdb", "ak": "", "sk": "", "host": "api-vikingdb.vikingdb.cn-beijing.volces.com", "model_name": "doubao-seed-rerank", "model_version": "251028", "threshold": 0.1, "max_input_tokens": 0 } } ``` | Field / path | Applies to | Purpose | |---|---|---| | `provider`, `model`, `api_base`, `api_key` | Embedding, VLM, Query Planner, Rerank | Model service, endpoint, and credential | | `api_version` | Embedding, VLM, Query Planner | API version for providers such as Azure | | `extra_headers` | Embedding, VLM, Query Planner, Rerank | Additional request headers | | `extra_request_body` | VLM, Query Planner | Additional completion request fields | | `extra_body` | `embedding.dense` / `sparse` / `hybrid` | Additional embedding request fields | | `timeout` | VLM, Query Planner, Rerank | Per-request timeout in seconds | | `embedding.max_retries`, `vlm.max_retries`, `query_planner.max_retries` | Embedding, VLM, Query Planner | Retry count; Rerank has no `max_retries` field | ### `embedding.dense` | Field | Type / values | Purpose | |---|---|---| | `provider` | `openai`, `volcengine`, `azure`, `ollama`, `local`, etc. | Dense embedding service | | `dimension` | integer, `> 0` | Vector dimension; must match model output and existing collections | | `input` | `"text"` / `"multimodal"` | Input type | | `encoding_format` | `"float"` / `"base64"` | OpenAI-compatible vector encoding | Changing the model or `dimension` can make existing vector collections incompatible and may require migration or reindexing. ### `rerank` | Field | Type / values | Default | Purpose | |---|---|---|---| | `provider` | `vikingdb`, `cohere`, `openai`, `litellm`, `jev` / `null` | `null` | Rerank service; inferred from credentials when omitted | | `model` | string / `null` | `null` | OpenAI-compatible, LiteLLM, or Jev rerank model | | `mode` | `noul`, `choice`, or `null` | `noul` | Jev rerank mode; `null` also uses `noul` | | `threshold` | number | `0.1` | Minimum score considered relevant | | `max_input_tokens` | integer; `0` or `>= 128` | `0` | Maximum estimated tokens per query-document pair; `0` disables truncation | | `log_payloads` | boolean | `false` | Log complete rerank request and response payloads; may expose query and document content | Rerank has no separate `enabled` field. It becomes available when the required provider credentials are configured. `jev` supports direct TypeSafe access (`https://api.typesafe.ai`, model `jev-latest`) and Vercel AI Gateway's TypeSafe-compatible endpoint (`https://ai-gateway.vercel.sh/typesafe`, model `typesafe-ai/jev`) through the existing `api_base` and `model` fields; both speak the same protocol. Its default `noul` mode scores each candidate independently. The optional `choice` mode compares all candidates and returns relative probabilities; set `threshold` to `0` when using it. Setting `provider` explicitly requires the credentials that provider needs: `ak` and `sk` for `vikingdb`, `api_key` for `cohere` and `jev`, `api_key` and `api_base` for `openai`, `model` for `litellm`. An incomplete block is rejected when the configuration loads. ## Retrieval Settings ```json { "retrieval": { "enable_intent": true } } ``` ### `retrieval` | Field | Type / values | Default | Purpose | |---|---|---|---| | `enable_intent` | boolean | `true` | Run intent analysis/query planning when `session_id` is present | Search and Find requests default to `limit: 10`; override the limit on each API or SDK request. `retrieval.enable_intent` controls LLM query planning for session-aware Search, while result reranking is enabled only when `rerank` has a usable provider configuration. ## Storage Settings ```json { "storage": { "workspace": "./data", "skip_process_lock": false, "agfs": { "backend": "local" }, "vectordb": { "backend": "local" }, "parse_output": { "mode": "agfs" } } } ``` ### `storage` | Field | Type / common values | Default | Purpose | |---|---|---|---| | `workspace` | path | `"./data"` | OpenViking workspace | | `agfs.backend` | `local`, `memory`, `s3` | `local` | File and metadata backend | | `vectordb.backend` | `local`, `cuvs`, `http`, `volcengine`, `vikingdb` | `local` | Vector database backend | | `vectordb.dimension` | integer | follows Embedding | Vector collection dimension | | `parse_output.mode` | `agfs`, `local` | `agfs` | Backend for intermediate parser artifacts | | `parse_output.local_root` | path or `null` | system temp directory | Root directory used by local parser artifacts | | `skip_process_lock` | boolean | `false` | Skip the workspace process lock; use only when accepting concurrent-write risk | Remote backends also require endpoint, bucket/collection, credentials, and timeout fields. See [Configuration](../guides/01-configuration.md#storage) for complete examples. `parse_output.mode=local` avoids writing parser intermediates to shared AGFS. The same worker must commit the required bytes to the formal resource tree before enqueueing downstream work. Artifacts are temporary and are removed after the content commit; provision `local_root` with enough space for concurrent imports. ## Queue Worker Settings ### `queue_workers.external_parse` | Field | Type | Default | Description | |---|---|---:|---| | `max_concurrent` | integer | `4` | Number of complete ExternalParse jobs consumed concurrently; must be greater than `0`; requires a server restart after changes | This setting controls queue-job concurrency. It is separate from `vlm.media.max_concurrent`, which limits audio/video VLM calls, and does not limit individual Understanding API HTTP requests. ### `queue_workers.add_resource` | Field | Type | Default | Description | |---|---|---:|---| | `max_concurrent` | integer | `4` | Number of complete AddResource jobs consumed concurrently; must be greater than `0`; requires a server restart after changes | | `file_operation_concurrency` | integer | `16` | Maximum concurrent file-level commit and fallback comparison operations within one AddResource job; must be greater than `0`; requires a server restart after changes | | `file_vectorization_concurrency` | integer | `8` | Number of files concurrently read, prepared, and enqueued within one directory AddResource job when `processing_mode="vectors_only"`; must be greater than `0`; values above the internal safety limit of `64` are capped; requires a server restart after changes | `max_concurrent` controls independent AddResource jobs. `file_operation_concurrency` controls file commit and fallback comparison work within one AddResource job, while `file_vectorization_concurrency` controls files within one vectors-only directory job. ### `queue_workers.reindex` | Field | Type | Default | Description | |---|---|---:|---| | `max_concurrent` | integer | `4` | Number of complete Reindex root jobs consumed concurrently; must be greater than `0`; requires a server restart after changes | This setting limits independent asynchronous reindex requests. URI-overlapping requests remain protected by path locks, while VLM and embedding work continue to use their respective concurrency limits. ### `queue_workers.session_commit` | Field | Type | Default | Description | |---|---|---:|---| | `max_concurrent` | integer | `8` | Number of SessionCommit jobs consumed concurrently; must be greater than `0`; requires a server restart after changes | ### `queue_workers.external_task` | Field | Type | Default | Description | |---|---|---:|---| | `max_concurrent` | integer | `10` | Number of external asynchronous tasks consumed concurrently; must be greater than `0`; requires a server restart after changes | ## Compile API Settings | Field | Type | Default | Description | |---|---|---:|---| | `base_url` | string | `""` | External service base URL, including `http://` or `https://`; a non-empty value enables external Compile | | `gateway_token` | string | `""` | Optional service credential used by OV to call the Compile Gateway | | `http_timeout_seconds` | number | `10` | Timeout for one HTTP request | | `poll_interval_ms` | integer | `30000` | External task polling interval | When `base_url` is configured, OV sends the current user's OV API key in `X-API-Key`. It sends `X-Gateway-Token` only when `gateway_token` is configured. ## Reindex Settings ### `reindex` | Field | Type | Default | Description | |---|---|---:|---| | `file_vectorization_concurrency` | integer | `8` | Number of files concurrently read, fingerprinted, and prepared by one resource/skill reindex task; must be greater than `0`; values above the internal safety limit of `64` are capped; requires a server restart after changes | ## HTTP Server Settings ```json { "server": { "host": "127.0.0.1", "port": 1933, "workers": 1, "executor_threads": 0, "auth_mode": "dev", "cors_origins": ["http://localhost:5173"], "profile_enabled": false, "temp_upload": { "default_mode": "local" } } } ``` ### `server` | Field | Type / values | Default | Purpose | |---|---|---|---| | `host` | IP / hostname | `"127.0.0.1"` | Listen address | | `port` | integer | `1933` | Listen port | | `workers` | integer | `1` | Worker process count | | `executor_threads` | non-negative integer | `0` | Maximum threads in each worker process's default asyncio executor; `0` uses Python's default sizing policy | | `timeout_keep_alive` | integer (seconds) | `5` | Idle HTTP keep-alive timeout; raise it above the upstream's idle-connection lifetime | | `auth_mode` | `dev`, `api_key`, `trusted` / `null` | `null` | Auth mode; null is inferred from `root_api_key` | | `root_api_key` | string / `null` | `null` | Root key; setting it defaults auth to `api_key` | | `cors_origins` | string[] | `["*"]` | Allowed origins | | `profile_enabled` | boolean | `false` | Allow performance profiles | | `with_bot` | boolean | `false` | Enable the VikingBot API proxy | | `bot_api_url` | URL | `http://localhost:18790` | VikingBot OpenAPI endpoint | | `public_base_url` | URL / `null` | `null` | Externally visible base URL | | `upload_signed_ttl_seconds` | integer | `600` | Signed upload and download URL lifetime | | `temp_upload.default_mode` | `"local"` / `"shared"` | `"local"` | Temporary upload storage | ### Encryption and API Key Hashing File encryption and API key hashing are configured in the top-level `encryption` section, not under `server`: ```json { "encryption": { "enabled": false, "api_key_hashing": { "enabled": false } } } ``` | Field | Type / values | Default | Purpose | |---|---|---|---| | `encryption.enabled` | boolean | `false` | Enable file-level AES encryption | | `encryption.api_key_hashing.enabled` | boolean | `false` | Store API keys with Argon2id | See [Encryption](../guides/08-encryption.md) for provider and key-management settings. ### Authentication Modes | Value | Use case | |---|---| | `dev` | Local-only development without API keys | | `api_key` | Validate root/user/admin keys | | `trusted` | Trust an upstream gateway to inject account/user identity | ## Memory Settings ```json { "memory": { "custom_templates_dir": "", "experimental_memory_switch": false, "eager_prefetch": true, "prefetch_search_topn": 5, "extraction_enabled": true, "session_skill_extraction_enabled": false, "link_enabled": false } } ``` ### `memory` | Field | Type / values | Default | Purpose | |---|---|---|---| | `custom_templates_dir` | path | `""` | Custom memory template directory; a matching `memory_type` overrides the loaded template | | `experimental_memory_switch` | boolean | `false` | Enable experimental templates | | `eager_prefetch` | boolean | `true` | Search and read memories before extraction | | `prefetch_search_topn` | integer, `>= 1` | `5` | Results read during prefetch | | `extraction_enabled` | boolean | `true` | Extract long-term memories on session commit | | `session_skill_extraction_enabled` | boolean | `false` | Also extract reusable skills | | `link_enabled` | boolean | `false` | Generate and resolve memory links | Automatic commits require a separate policy; enabling memory extraction does not make sessions commit automatically. See `memory.session_auto_commit` in [Configuration](../guides/01-configuration.md) and the [Sessions API](../api/05-sessions.md). For template loading order and when changes take effect, see the [Prompt Guide](../guides/10-prompt-guide.md). ## Parser Settings Parsers live under `parsers`: ```json { "parsers": { "pdf": {}, "code": { "code_summary_mode": "ast", "extract_functions": true, "extract_classes": true, "max_token_limit": 50000 }, "image": {}, "audio": {}, "video": {}, "markdown": {}, "anydoc": { "enabled": true }, "html": {}, "text": {}, "directory": { "preserve_structure": true, "max_files": null, "max_depth": 10, "max_concurrent": 4 }, "feishu": { "domain": "https://open.feishu.cn", "max_rows_per_sheet": 1000, "max_records_per_table": 1000, "download_images": true }, "webfeed": {} } } ``` `parsers.directory.max_files` defaults to `null`, meaning no file-count limit. Set it to a positive integer to limit the number of files per directory import. `parsers.directory.max_concurrent` is shared by all directory imports in the server event loop. With the default value `4`, one directory can run four Understanding jobs concurrently, while multiple concurrent directories still run at most four in total. `max_files` and `max_depth` apply when Understanding directory routing is enabled. Each `DirectoryParser` scan applies these limits independently before submitting its own Understanding requests. A nested ZIP starts a new directory scan and does not share the outer scan's file-count or depth budget. When Understanding is disabled, native OpenViking directory parsing does not apply these two limits. When a local directory is added through the client, the complete directory ZIP is subject to the `/resources/temp_upload` size limit. After extraction, `DirectoryParser` does not impose a common per-file byte limit. Each selected file follows the limits and upload behavior of its assigned built-in parser or Understanding API backend. | Setting | Purpose | |---|---| | `pdf` | PDF text, image, and layout parsing | | `code` | Repository file types, ignore rules, and network safety | | `image` | Image understanding and OCR | | `audio`, `video` | Audio/video parsing | | `markdown`, `html`, `text` | Text document chunking | | `anydoc` | Office and EPUB conversion; `enabled=false` rejects those formats | | `directory` | Directory scanning and ignore rules | | `feishu` | Feishu/Lark access and parsing | | `webfeed` | Sitemap, RSS, and Atom ingestion | Provider-, parser-, storage-, and encryption-specific fields are documented in [Configuration](../guides/01-configuration.md). ## Minimal Example ```json { "embedding": { "dense": { "provider": "volcengine", "model": "doubao-embedding-vision-251215", "api_base": "https://ark.cn-beijing.volces.com/api/v3", "api_key": "", "dimension": 1024, "input": "multimodal" } }, "vlm": { "provider": "volcengine", "model": "doubao-seed-2-0-code-preview-260215", "api_base": "https://ark.cn-beijing.volces.com/api/v3", "api_key": "", "thinking": false }, "storage": { "workspace": "./data" }, "server": { "host": "127.0.0.1", "port": 1933 } } ```