diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 6a58cdd8..f80ca521 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -309,9 +309,13 @@ export default withMermaid( { text: "OpenSearch for search", link: "/self-hosting/govern/advanced-search" }, { text: "Plane AI", - link: "/self-hosting/govern/plane-ai", collapsed: true, - items: [{ text: "AWS OpenSearch embedding", link: "/self-hosting/govern/aws-opensearch-embedding" }], + items: [ + { text: "Get started", link: "/self-hosting/govern/plane-ai/getting-started" }, + { text: "Custom LLM models", link: "/self-hosting/govern/plane-ai/custom-llm" }, + { text: "Semantic search", link: "/self-hosting/govern/plane-ai/semantic-search" }, + { text: "AWS OpenSearch embedding", link: "/self-hosting/govern/aws-opensearch-embedding" }, + ], }, { text: "External secrets", link: "/self-hosting/govern/external-secrets" }, { text: "External reverse proxy", link: "/self-hosting/govern/reverse-proxy" }, diff --git a/docs/self-hosting/govern/aws-opensearch-embedding.md b/docs/self-hosting/govern/aws-opensearch-embedding.md index 5219843c..34176ac0 100644 --- a/docs/self-hosting/govern/aws-opensearch-embedding.md +++ b/docs/self-hosting/govern/aws-opensearch-embedding.md @@ -232,4 +232,4 @@ EMBEDDING_MODEL=cohere/embed-v4.0 OPENSEARCH_EMBEDDING_DIMENSION=1536 ``` -Restart Plane and complete the remaining steps in [Enable Plane AI](/self-hosting/govern/plane-ai#configure-an-embedding-model). +Restart Plane and complete the remaining steps in [Set up semantic search](/self-hosting/govern/plane-ai/semantic-search). diff --git a/docs/self-hosting/govern/environment-variables.md b/docs/self-hosting/govern/environment-variables.md index 5fd32f38..9c0dc59e 100644 --- a/docs/self-hosting/govern/environment-variables.md +++ b/docs/self-hosting/govern/environment-variables.md @@ -237,7 +237,7 @@ These settings are required for semantic search and Plane AI Chat. Configure one | **BR_AWS_SECRET_ACCESS_KEY** | AWS secret access key for Bedrock Titan embedding | Conditional | | **BR_AWS_REGION** | AWS region for Bedrock Titan embedding | Conditional | -For setup instructions, supported models, and IAM permissions, see [Enable Plane AI](/self-hosting/govern/plane-ai). +For setup instructions, supported models, and IAM permissions, see [Plane AI](/self-hosting/govern/plane-ai/getting-started). ### API settings @@ -293,37 +293,37 @@ For setup instructions, supported models, and IAM permissions, see [Enable Plane ### Plane Intelligence (PI) settings -| Variable | Description | Default Value | -| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -| **OPENAI_API_KEY** | API key for OpenAI services used by Plane Intelligence. | | -| **OPENAI_BASE_URL** | Custom base URL for OpenAI-compatible API endpoints. | | -| **CLAUDE_API_KEY** | API key for Anthropic Claude services used by Plane Intelligence. | | -| **CLAUDE_BASE_URL** | Custom base URL for Claude API endpoints. | | -| **GROQ_API_KEY** | API key for Groq services used by Plane Intelligence. | | -| **GROQ_BASE_URL** | Custom base URL for Groq API endpoints. | | -| **COHERE_API_KEY** | API key for Cohere services used by Plane Intelligence. | | -| **COHERE_BASE_URL** | Custom base URL for Cohere API endpoints. | | -| **CUSTOM_LLM_ENABLED** | Enable a custom OpenAI-compatible LLM provider. Set to `true` to enable. | false | -| **CUSTOM_LLM_MODEL_KEY** | Model key identifier for the custom LLM. | gpt-oss-120b | -| **CUSTOM_LLM_BASE_URL** | Base URL for the custom LLM API endpoint. | | -| **CUSTOM_LLM_API_KEY** | API key for the custom LLM provider. | | -| **CUSTOM_LLM_NAME** | Display name for the custom LLM in the Plane UI. | GPT-OSS-120B | -| **CUSTOM_LLM_DESCRIPTION** | Description of the custom LLM shown in the Plane UI. | A self-hosted OpenAI-compatible model | -| **CUSTOM_LLM_MAX_TOKENS** | Maximum token limit for the custom LLM. | 128000 | -| **EMBEDDING_MODEL** | Model key for generating embeddings (e.g. `cohere/embed-v4.0`). Required for PI API startup when Plane AI is enabled. | | -| **OPENSEARCH_ML_MODEL_ID** | OpenSearch ML model ID for the deployed embedding model. | | -| **OPENSEARCH_EMBEDDING_DIMENSION** | Vector dimension for `knn_vector` fields; must match the embedding model and stay aligned with the API service. See [Plane AI](/self-hosting/govern/plane-ai). | 1536 | -| **BR_AWS_ACCESS_KEY_ID** | AWS access key for Amazon Bedrock integration. | | -| **BR_AWS_SECRET_ACCESS_KEY** | AWS secret key for Amazon Bedrock integration. | | -| **BR_AWS_SESSION_TOKEN** | AWS session token for Amazon Bedrock integration (for temporary credentials). | | -| **FASTAPI_APP_WORKERS** | Number of FastAPI workers for the PI service. | 1 | -| **PLANE_OAUTH_STATE_EXPIRY_SECONDS** | Expiry time (in seconds) for PI OAuth state tokens. | 82800 | -| **CELERY_VECTOR_SYNC_ENABLED** | Enable periodic vector synchronization for AI-powered search. | 0 | -| **CELERY_VECTOR_SYNC_INTERVAL** | Interval (in seconds) for vector synchronization. | 3 | -| **CELERY_WORKSPACE_PLAN_SYNC_ENABLED** | Enable periodic workspace plan synchronization. | 0 | -| **CELERY_WORKSPACE_PLAN_SYNC_INTERVAL** | Interval (in seconds) for workspace plan synchronization. | 86400 | -| **CELERY_DOCS_SYNC_ENABLED** | Enable periodic documents synchronization for AI indexing. | 0 | -| **CELERY_DOCS_SYNC_INTERVAL** | Interval (in seconds) for documents synchronization. | 86400 | +| Variable | Description | Default Value | +| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | +| **OPENAI_API_KEY** | API key for OpenAI services used by Plane Intelligence. | | +| **OPENAI_BASE_URL** | Custom base URL for OpenAI-compatible API endpoints. | | +| **CLAUDE_API_KEY** | API key for Anthropic Claude services used by Plane Intelligence. | | +| **CLAUDE_BASE_URL** | Custom base URL for Claude API endpoints. | | +| **GROQ_API_KEY** | API key for Groq services used by Plane Intelligence. | | +| **GROQ_BASE_URL** | Custom base URL for Groq API endpoints. | | +| **COHERE_API_KEY** | API key for Cohere services used by Plane Intelligence. | | +| **COHERE_BASE_URL** | Custom base URL for Cohere API endpoints. | | +| **CUSTOM_LLM_ENABLED** | Enable a custom OpenAI-compatible LLM provider. Set to `true` to enable. | false | +| **CUSTOM_LLM_MODEL_KEY** | Model key identifier for the custom LLM. | gpt-oss-120b | +| **CUSTOM_LLM_BASE_URL** | Base URL for the custom LLM API endpoint. | | +| **CUSTOM_LLM_API_KEY** | API key for the custom LLM provider. | | +| **CUSTOM_LLM_NAME** | Display name for the custom LLM in the Plane UI. | GPT-OSS-120B | +| **CUSTOM_LLM_DESCRIPTION** | Description of the custom LLM shown in the Plane UI. | A self-hosted OpenAI-compatible model | +| **CUSTOM_LLM_MAX_TOKENS** | Maximum token limit for the custom LLM. | 128000 | +| **EMBEDDING_MODEL** | Model key for generating embeddings (e.g. `cohere/embed-v4.0`). Required for PI API startup when Plane AI is enabled. | | +| **OPENSEARCH_ML_MODEL_ID** | OpenSearch ML model ID for the deployed embedding model. | | +| **OPENSEARCH_EMBEDDING_DIMENSION** | Vector dimension for `knn_vector` fields; must match the embedding model and stay aligned with the API service. See [Semantic search](/self-hosting/govern/plane-ai/semantic-search). | 1536 | +| **BR_AWS_ACCESS_KEY_ID** | AWS access key for Amazon Bedrock integration. | | +| **BR_AWS_SECRET_ACCESS_KEY** | AWS secret key for Amazon Bedrock integration. | | +| **BR_AWS_SESSION_TOKEN** | AWS session token for Amazon Bedrock integration (for temporary credentials). | | +| **FASTAPI_APP_WORKERS** | Number of FastAPI workers for the PI service. | 1 | +| **PLANE_OAUTH_STATE_EXPIRY_SECONDS** | Expiry time (in seconds) for PI OAuth state tokens. | 82800 | +| **CELERY_VECTOR_SYNC_ENABLED** | Enable periodic vector synchronization for AI-powered search. | 0 | +| **CELERY_VECTOR_SYNC_INTERVAL** | Interval (in seconds) for vector synchronization. | 3 | +| **CELERY_WORKSPACE_PLAN_SYNC_ENABLED** | Enable periodic workspace plan synchronization. | 0 | +| **CELERY_WORKSPACE_PLAN_SYNC_INTERVAL** | Interval (in seconds) for workspace plan synchronization. | 86400 | +| **CELERY_DOCS_SYNC_ENABLED** | Enable periodic documents synchronization for AI indexing. | 0 | +| **CELERY_DOCS_SYNC_INTERVAL** | Interval (in seconds) for documents synchronization. | 86400 | ::: details Community Edition diff --git a/docs/self-hosting/govern/plane-ai.md b/docs/self-hosting/govern/plane-ai.md deleted file mode 100644 index f58ea625..00000000 --- a/docs/self-hosting/govern/plane-ai.md +++ /dev/null @@ -1,317 +0,0 @@ ---- -title: Configure Plane AI -description: Configure Plane AI on your self-hosted Plane deployment. Set up LLM providers, embedding models, and semantic search for Plane's AI features. -keywords: plane ai, Plane ai, self-hosted ai, llm configuration, embedding models, semantic search, openai, anthropic, cohere ---- - -# Configure Plane AI - -Plane AI brings AI-powered features to your workspace, including natural language chat, duplicate detection, and semantic search across work items, pages, and projects. This guide walks you through configuring Plane AI on your self-hosted instance. - -For an overview of what Plane AI can do, see the [Plane AI](https://docs.plane.so/ai/pi-chat). - -## Before you begin - -You'll need: - -- A **separate database** for Plane AI. Plane AI requires its own database instance. -- An OpenSearch instance running version 2.19 or later (self-hosted or AWS OpenSearch) configured for [advanced search](/self-hosting/govern/advanced-search). -- At least one LLM provider API key or a custom OpenAI-compatible endpoint. -- At least one embedding model configured in OpenSearch. - -## Supported models - -### Large language models (LLMs) - -#### OpenAI - -Supported models: - -- GPT-5 -- GPT-4.1 -- GPT-5.2 - -#### Anthropic - -Supported models: - -- Claude Sonnet 4.0 -- Claude Sonnet 4.5 -- Claude Sonnet 4.6 - -You can provide API keys for both OpenAI and Anthropic, making all models available to users. If you provide only one key, users will only have access to that provider's models. - -:::tip -If you need to use an LLM that isn't from OpenAI or Anthropic — for example, an open-source model or a regional provider for compliance reasons — you can proxy it through [LiteLLM](https://docs.litellm.ai). LiteLLM exposes any LLM behind an OpenAI-compatible API, which Plane can then connect to using the `CUSTOM_LLM_*` variables with `CUSTOM_LLM_PROVIDER=openai`. -::: - -#### Custom models (self-hosted or third-party) - -Plane AI supports custom models through two backends: - -- **OpenAI-compatible endpoint** — any model exposed via an OpenAI-compatible API, including models served by Ollama, Groq, Cerebras, and similar runtimes. -- **AWS Bedrock** — models accessed directly through Amazon Bedrock using your AWS credentials. - -One custom model can be configured alongside your public provider keys. - -::: warning -The custom model should have at least 1 trillion parameters for all Plane AI features to work reliably. Larger, more capable models yield better results. -::: - -### Embedding models - -Embedding models power semantic search. Plane AI supports: - -| Provider | Supported models | Dimension | -| --------------- | -------------------------------------- | --------- | -| **Cohere** | `cohere/embed-v4.0` | 1536 | -| | `cohere/embed-english-v3.0` | 1024 | -| | `cohere/embed-english-v2.0` | 4096 | -| **OpenAI** | `openai/text-embedding-ada-002` | 1536 | -| | `openai/text-embedding-3-small` | 1536 | -| | `openai/text-embedding-3-large` | 3072 | -| **AWS Bedrock** | `bedrock/amazon.titan-embed-text-v1` | 1536 | -| | `bedrock/amazon.titan-embed-text-v2` | 1024 | -| | `bedrock/cohere.embed-english-v3` | 1024 | -| | `bedrock/cohere.embed-multilingual-v3` | 1024 | - -## Enable Plane AI services - -:::info Separate database required -Plane AI must use its own database — do not share the main Plane application database. A dedicated database keeps AI data (e.g. chat history) isolated and avoids schema conflicts. Set **PLANE_PI_DATABASE_URL** (or the equivalent for your deployment). See the [environment variables reference](/self-hosting/govern/environment-variables#plane-ai). -::: - -:::tip -For other deployment methods such as Coolify, Portainer, Docker Swarm, and Podman Quadlets, use the same [environment variables](/self-hosting/govern/environment-variables#plane-ai) defined for Docker Compose Setup. -::: - -:::tabs key:deployment-method - -== Docker Compose {#docker-compose} - -Open the `/opt/plane/plane.env` file in your preferred editor and set the replica count for Plane AI services to `1`: - -```bash -PI_API_REPLICAS=1 -PI_BEAT_REPLICAS=1 -PI_WORKER_REPLICAS=1 -PI_MIGRATOR_REPLICAS=1 -``` - -== Kubernetes {#kubernetes} - -Open your `values.yaml` file and enable the Plane AI service by setting `services.pi.enabled` to `true`: - -```yaml -services: - pi: - enabled: true -``` - -This activates the Plane AI API, worker, beat-worker, and migrator workloads. Replica counts and resource limits for each workload can be configured through the [Plane AI values block](/self-hosting/methods/kubernetes#plane-ai-pi-deployment) in your `values.yaml`. - -::: - -:::tip Plane AI API startup checks -On start, the Plane AI container runs an embedding-dimension check against OpenSearch. **OpenSearch must be reachable** at `OPENSEARCH_URL`, and **`EMBEDDING_MODEL` must be set** in your environment or the service will not start. If existing index mappings or the deployed ML model disagree with **`OPENSEARCH_EMBEDDING_DIMENSION`**, startup fails until you align the configuration or rebuild indices (see [Changing the embedding dimension](#changing-the-embedding-dimension) below). -::: - -## Configure an LLM provider - -Configure at least one LLM provider. Add the relevant variables to `/opt/plane/plane.env`. - -### OpenAI - -```bash -OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx -``` - -### Anthropic - -```bash -CLAUDE_API_KEY=xxxxxxxxxxxxxxxx -``` - -### Custom model - -```bash -CUSTOM_LLM_ENABLED=true -CUSTOM_LLM_PROVIDER=openai # or 'bedrock' -CUSTOM_LLM_MODEL_KEY=your-model-key -CUSTOM_LLM_API_KEY=your-api-key -CUSTOM_LLM_NAME=Your Model Name -CUSTOM_LLM_MAX_TOKENS=128000 -``` - -**Additional required variables by provider:** - -- **OpenAI-compatible** (`openai`): `CUSTOM_LLM_BASE_URL` -- **AWS Bedrock** (`bedrock`): `CUSTOM_LLM_AWS_REGION` - -::: warning -For Bedrock, the IAM user must have `bedrock:InvokeModel` permission on the target model. -::: - -### Speech-to-text (optional) - -```bash -GROQ_API_KEY=your-groq-api-key -``` - -This enables voice input in Plane AI. It's not required for LLM or semantic search features. - -## Configure OpenSearch and an embedding model - -Plane AI uses OpenSearch for semantic indexing and retrieval. If you haven't set up OpenSearch yet, complete the [OpenSearch for advanced search](/self-hosting/govern/advanced-search) guide first, then return here. - -### Configure OpenSearch connection - -```bash -OPENSEARCH_URL=https://your-opensearch-instance:9200/ -OPENSEARCH_USERNAME=admin -OPENSEARCH_PASSWORD=your-secure-password -OPENSEARCH_INDEX_PREFIX=plane -``` - -### Configure an embedding model - -You must configure the `EMBEDDING_MODEL` so Plane AI knows which embedding model to construct queries for. Then configure exactly one embedding model deployment using one of these options. - -#### Option A: Use an existing OpenSearch model ID - -If you've already deployed an embedding model in OpenSearch, provide its model ID along with your chosen embedding model and dimension. This works with both self-hosted and AWS OpenSearch. - -```bash -OPENSEARCH_ML_MODEL_ID=your-model-id -EMBEDDING_MODEL=openai/text-embedding-3-small -OPENSEARCH_EMBEDDING_DIMENSION=1536 -``` - -For AWS OpenSearch, you must deploy the embedding model manually before setting this variable. See [Deploy an embedding model on AWS OpenSearch](/self-hosting/govern/aws-opensearch-embedding). - -#### Option B: Automatic deployment (self-hosted OpenSearch only) - -For self-hosted OpenSearch, Plane can automatically create and deploy the embedding model. Provide the model name and the corresponding provider credentials. - -**Cohere:** - -```bash -EMBEDDING_MODEL=cohere/embed-v4.0 -COHERE_API_KEY=your-cohere-api-key -OPENSEARCH_EMBEDDING_DIMENSION=1536 -``` - -**OpenAI:** - -```bash -EMBEDDING_MODEL=openai/text-embedding-3-small -OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx -OPENSEARCH_EMBEDDING_DIMENSION=1536 -``` - -**AWS Bedrock (Titan):** - -```bash -EMBEDDING_MODEL=bedrock/amazon.titan-embed-text-v1 -BR_AWS_ACCESS_KEY_ID=your-access-key -BR_AWS_SECRET_ACCESS_KEY=your-secret-key -BR_AWS_REGION=your-region -OPENSEARCH_EMBEDDING_DIMENSION=1536 -``` - -:::warning Required IAM permission for Bedrock Titan -The IAM user for `BR_AWS_ACCESS_KEY_ID` and `BR_AWS_SECRET_ACCESS_KEY` needs `bedrock:InvokeModel` permission on the Titan foundation model. Without it, embedding requests fail with a 403 error. - -Attach this policy to the IAM user: - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "bedrock:InvokeModel", - "Resource": "arn:aws:bedrock:::foundation-model/amazon.titan-embed-text-v1" - } - ] -} -``` - -Replace `` with your `BR_AWS_REGION` value. -::: - -:::info -Automatic embedding model deployment only works with self-hosted OpenSearch. For AWS OpenSearch, deploy the model manually and set `OPENSEARCH_ML_MODEL_ID` to that model’s ID. -::: - -## Restart Plane - -After updating the environment file, restart Plane. - -**Docker:** - -```bash -prime-cli restart -``` - -Or if you're managing containers directly: - -```bash -docker compose down -docker compose up -d -``` - -**Kubernetes:** - -```bash -helm upgrade --install plane-app plane/plane-enterprise \ - --namespace plane \ - -f values.yaml \ - --wait -``` - -## Vectorize existing data - -Generate embeddings for your existing content by running this command in the API container. - -**Docker:** - -```bash -docker exec -it plane-api-1 sh -python manage.py manage_search_index --background --vectorize document index --force -``` - -**Kubernetes:** - -```bash -API_POD=$(kubectl get pods -n plane --no-headers | grep api | head -1 | awk '{print $1}') -kubectl exec -n plane $API_POD -- python manage.py manage_search_index --background --vectorize document index --force -``` - -The `--background` flag processes vectorization through Celery workers. This is recommended for instances with large amounts of existing content. - -### Changing the embedding dimension - -If you update the model or manually override the dimension size by setting `OPENSEARCH_EMBEDDING_DIMENSION`, you must recreate your search indices so they adopt the new dimension size, then reindex and revectorize your workspace. Ensure that the model associated with your `OPENSEARCH_ML_MODEL_ID` and your `EMBEDDING_MODEL` configuration share this same dimension size. - -Run these commands inside your API container or pod after updating the environment variables and restarting the Plane services: - -```bash -# 1. Rebuild all search indices to apply the new dimension size -python manage.py manage_search_index index rebuild --force - -# 2. Reindex and revectorize all existing documents -python manage.py manage_search_index --background --vectorize document index --force -``` - -## After setup - -Once configured: - -- Plane AI is available across your workspace. -- New content (work items, pages, comments) is automatically vectorized in the background. -- Semantic search stays synchronized without manual intervention. - -## Environment variables reference - -See the [environment variables reference](/self-hosting/govern/environment-variables#plane-ai) for a complete list of AI-related configuration options. diff --git a/docs/self-hosting/govern/plane-ai/custom-llm.md b/docs/self-hosting/govern/plane-ai/custom-llm.md new file mode 100644 index 00000000..5f45a3bb --- /dev/null +++ b/docs/self-hosting/govern/plane-ai/custom-llm.md @@ -0,0 +1,103 @@ +--- +title: Custom LLM models +description: Connect a self-hosted or third-party LLM to Plane AI using an OpenAI-compatible endpoint or AWS Bedrock. +keywords: custom llm, self-hosted llm, ollama, litellm, groq, aws bedrock, plane ai custom model +--- + +# Custom LLM models + +Plane AI supports one custom LLM alongside OpenAI and Anthropic. Pick the provider type that fits your setup: + +| Provider type | Use when | +| --------------------- | ----------------------------------------------------------------------------------------------------- | +| **OpenAI-compatible** | Your model is served via an OpenAI Chat Completions API (Ollama, Groq, vLLM, LiteLLM, Cerebras, etc.) | +| **AWS Bedrock** | You're accessing models through Amazon Bedrock | + +:::warning +Use a model with at least 1 trillion parameters. Smaller models produce degraded output across Plane AI features. +::: + +:::tip No OpenAI-compatible API? +Proxy any model through [LiteLLM](https://docs.litellm.ai) — it exposes any LLM behind the OpenAI API. Then use the OpenAI-compatible setup below. +::: + +--- + +## OpenAI-compatible + +Add to `/opt/plane/plane.env`: + +```bash +CUSTOM_LLM_ENABLED=true +CUSTOM_LLM_PROVIDER=openai +CUSTOM_LLM_MODEL_KEY=your-model-id # model ID as the endpoint expects it +CUSTOM_LLM_BASE_URL=https://your-endpoint/v1 +CUSTOM_LLM_API_KEY=your-api-key # use any non-empty string if no key is required +CUSTOM_LLM_NAME=Your Model Name # display name shown to users +CUSTOM_LLM_MAX_TOKENS=128000 # optional, defaults to 128000 +``` + +**Examples:** + +```bash +# Groq +CUSTOM_LLM_MODEL_KEY=llama-3.3-70b-versatile +CUSTOM_LLM_BASE_URL=https://api.groq.com/openai/v1 +CUSTOM_LLM_API_KEY=gsk_xxxxxxxxxxxx + +# Ollama (local) +CUSTOM_LLM_MODEL_KEY=llama3 +CUSTOM_LLM_BASE_URL=http://localhost:11434/v1 +CUSTOM_LLM_API_KEY=ollama + +# LiteLLM proxy +CUSTOM_LLM_MODEL_KEY=your-litellm-model +CUSTOM_LLM_BASE_URL=http://litellm:4000/v1 +CUSTOM_LLM_API_KEY=your-litellm-master-key +``` + +--- + +## AWS Bedrock + +### Standard credentials + +Use for IAM user access with an explicit access key and secret. + +```bash +CUSTOM_LLM_ENABLED=true +CUSTOM_LLM_PROVIDER=bedrock +CUSTOM_LLM_MODEL_KEY=anthropic.claude-3-5-sonnet-20241022-v2:0 # Bedrock model ID +CUSTOM_LLM_API_KEY=your-aws-secret-access-key +CUSTOM_LLM_AWS_REGION=us-east-1 +AWS_ACCESS_KEY_ID=your-aws-access-key-id # standard AWS env var, picked up by boto3 +CUSTOM_LLM_NAME=Claude via Bedrock +``` + +:::warning IAM permission required +The IAM user must have `bedrock:InvokeModel` permission on the target model. +::: + +### Inference profile (IRSA / EKS Pod Identity) + +Use for Kubernetes deployments where the pod has an ambient IAM role. No static credentials needed. + +```bash +CUSTOM_LLM_ENABLED=true +CUSTOM_LLM_PROVIDER=bedrock +CUSTOM_LLM_MODEL_KEY=claude-sonnet-4-6 +CUSTOM_LLM_AWS_REGION=us-east-1 +BEDROCK_INFERENCE_PROFILE_ARN=arn:aws:bedrock:us-east-1:123456789012:application-inference-profile/xxxx +# or use BEDROCK_INFERENCE_PROFILE_ID=global.anthropic.claude-sonnet-4-6 +CUSTOM_LLM_NAME=Claude via Inference Profile +``` + +Plane AI activates inference profile mode automatically when a profile ARN or ID is set and ambient AWS credentials are present (`AWS_ROLE_ARN`, `AWS_WEB_IDENTITY_TOKEN_FILE`, `AWS_CONTAINER_CREDENTIALS_FULL_URI`, or `AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE`). + +--- + +After updating `/opt/plane/plane.env`, restart Plane: + +```bash +prime-cli restart +``` diff --git a/docs/self-hosting/govern/plane-ai/getting-started.md b/docs/self-hosting/govern/plane-ai/getting-started.md new file mode 100644 index 00000000..a65332cb --- /dev/null +++ b/docs/self-hosting/govern/plane-ai/getting-started.md @@ -0,0 +1,182 @@ +--- +title: Get started with Plane AI +description: Enable Plane AI on your self-hosted instance. Set up a dedicated database, configure OpenSearch, add an LLM API key, and connect PI to your Plane deployment. +keywords: plane ai setup, self-hosted ai, llm api key, openai, anthropic, opensearch, enable plane ai +--- + +# Get started with Plane AI + +Plane AI brings AI-powered features to your workspace, including natural language chat, duplicate detection, and search across work items, pages, and projects. This guide walks you through configuring Plane AI on your self-hosted instance. + +For an overview of what Plane AI can do, see [Plane AI](https://docs.plane.so/ai/pi-chat). + +Plane AI requires four things to work: + +1. **An LLM API key** (OpenAI or Anthropic) — powers AI responses. +2. **OpenSearch** — Search over your workspace data (issues, pages, docs) runs through OpenSearch indices. +3. **A dedicated database** — Plane AI must not share the main Plane application database. +4. **Read access to the main Plane database** — PI reads workspace data directly from the main Plane DB. + +For an overview of what Plane AI can do, see [Plane AI](https://docs.plane.so/ai/pi-chat). + +## Supported LLM providers + +### OpenAI (`OPENAI_API_KEY`) + +- GPT-5.4 +- GPT-5.2 + +### Anthropic (`CLAUDE_API_KEY`) + +- Claude Sonnet 4.5 +- Claude Sonnet 4.6 + +Set both keys to give users access to models from both providers. If only one is set, users only see that provider's models. + +:::tip Custom or self-hosted models +To use Ollama, Groq, LiteLLM, AWS Bedrock, or any OpenAI-compatible endpoint, see [Custom LLM models](/self-hosting/govern/plane-ai/custom-llm). +::: + +## Step 1 — Set up databases + +Plane AI needs two database connections: + +```bash +PLANE_PI_DATABASE_URL=postgresql://user:password@host:5432/plane-pi +FOLLOWER_POSTGRES_URI=postgresql://user:password@host:5432/plane +``` + +- **`PLANE_PI_DATABASE_URL`** — PI's own dedicated database. Must not be shared with the main Plane application database. +- **`FOLLOWER_POSTGRES_URI`** — Read connection to the main Plane database. PI reads workspace data (issues, pages, projects) directly from here. Can be a read replica. + +Both are checked at startup — PI will not start if either is unreachable. + +## Step 2 — Configure OpenSearch + +Add to `/opt/plane/plane.env`: + +```bash +OPENSEARCH_URL=https://your-opensearch-instance:9200/ +OPENSEARCH_USERNAME=admin +OPENSEARCH_PASSWORD=your-secure-password +``` + +If you haven't set up OpenSearch yet, see [OpenSearch for advanced search](/self-hosting/govern/advanced-search) first. + +## Step 3 — Add an LLM API key + +Add at least one to `/opt/plane/plane.env`: + +```bash +OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx +CLAUDE_API_KEY=xxxxxxxxxxxxxxxx +``` + +## Step 4 — Connect Plane AI to your Plane deployment + +Plane AI runs as a separate service and must be wired to your Plane deployment. Two things matter here: + +**In the Plane API env** (`/opt/plane/plane.env`), tell Plane where PI is reachable: + +```bash +PI_BASE_URL=https://plane.example.com +``` + +Plane builds the PI URL as `PI_BASE_URL + PI_BASE_PATH` — with the default `PI_BASE_PATH=/pi` this becomes `https://plane.example.com/pi`. + +**In the PI env** (`/opt/plane/plane.env`), set the OAuth redirect URI to match: + +```bash +PLANE_OAUTH_REDIRECT_URI=https://plane.example.com/pi/api/v1/oauth/callback/ +``` + +## Step 5 — Enable Plane AI services + +:::tip Other deployment methods +For Coolify, Portainer, Docker Swarm, and Podman Quadlets, use the same environment variables as Docker Compose — only the replica variables differ. +::: + +:::tabs key:deployment-method + +== Docker Compose {#docker-compose} + +In `/opt/plane/plane.env`, set replica counts to `1`: + +```bash +PI_API_REPLICAS=1 +PI_BEAT_REPLICAS=1 +PI_WORKER_REPLICAS=1 +PI_MIGRATOR_REPLICAS=1 +``` + +== Kubernetes {#kubernetes} + +In `values.yaml`, enable the Plane AI service: + +```yaml +services: + pi: + enabled: true +``` + +This activates the Plane AI API, worker, beat-worker, and migrator workloads. Configure replicas and resource limits through the [Plane AI values block](/self-hosting/methods/kubernetes#plane-ai-pi-deployment). + +::: + +## Step 6 — Restart Plane + +:::tabs key:deployment-method + +== Docker Compose {#docker-compose} + +```bash +prime-cli restart +``` + +Or directly: + +```bash +docker compose down +docker compose up -d +``` + +== Kubernetes {#kubernetes} + +```bash +helm upgrade --install plane-app plane/plane-enterprise \ + --namespace plane \ + -f values.yaml \ + --wait +``` + +::: + +--- + +## Optional + +### Voice input + +Enables speech-to-text in Plane AI chat. Get a key at [console.groq.com](https://console.groq.com). + +```bash +GROQ_API_KEY=your-groq-api-key +``` + +### File uploads + +Enables file attachments in Plane AI. + +```bash +AWS_S3_BUCKET_NAME=your-bucket-name +AWS_S3_REGION=us-east-1 +AWS_ACCESS_KEY_ID=your-access-key +AWS_SECRET_ACCESS_KEY=your-secret-key +``` + +For MinIO or S3-compatible storage, also add: + +```bash +AWS_S3_ENDPOINT_URL=http://your-minio-host:9000 +USE_MINIO=1 +``` diff --git a/docs/self-hosting/govern/plane-ai/semantic-search.md b/docs/self-hosting/govern/plane-ai/semantic-search.md new file mode 100644 index 00000000..d53bbd53 --- /dev/null +++ b/docs/self-hosting/govern/plane-ai/semantic-search.md @@ -0,0 +1,124 @@ +--- +title: Set up semantic search +description: Configure an embedding model for Plane AI semantic search, duplicate detection, and vector retrieval over work items and pages. +keywords: plane ai semantic search, opensearch, embedding model, vector search, cohere, openai embeddings, bedrock embeddings +--- + +# Set up semantic search + +Semantic search is optional. Without it, Plane AI uses BM25 keyword search. With it, you get vector similarity search, duplicate issue detection, and semantic retrieval over work items and pages. + +This builds on the OpenSearch connection configured in [Get started with Plane AI](/self-hosting/govern/plane-ai/getting-started). Make sure `OPENSEARCH_URL`, `OPENSEARCH_USERNAME`, and `OPENSEARCH_PASSWORD` are already set before continuing. + +## Supported embedding models + +| Provider | Model | Dimension | +| --------------- | -------------------------------------- | --------- | +| **Cohere** | `cohere/embed-v4.0` | 1536 | +| | `cohere/embed-english-v3.0` | 1024 | +| | `cohere/embed-english-v2.0` | 4096 | +| **OpenAI** | `openai/text-embedding-ada-002` | 1536 | +| | `openai/text-embedding-3-small` | 1536 | +| | `openai/text-embedding-3-large` | 3072 | +| **AWS Bedrock** | `bedrock/amazon.titan-embed-text-v1` | 1536 | +| | `bedrock/amazon.titan-embed-text-v2` | 1024 | +| | `bedrock/cohere.embed-english-v3` | 1024 | +| | `bedrock/cohere.embed-multilingual-v3` | 1024 | + +## Step 1 — Configure the embedding model + +`EMBEDDING_MODEL` is required for semantic search to activate. Without it, Plane AI runs in BM25 keyword-only mode. + +`OPENSEARCH_EMBEDDING_DIMENSION` must match the model's actual output dimension (see table above). It defaults to `1536` — only set it explicitly if your model uses a different value. A mismatch between the configured dimension and the model's real output breaks indexing. + +Two options depending on your OpenSearch setup. + +### Use an existing model ID + +Use this if you've already deployed an embedding model in OpenSearch — either via the [AWS OpenSearch embedding guide](/self-hosting/govern/aws-opensearch-embedding) or manually on self-hosted OpenSearch. + +```bash +EMBEDDING_MODEL=cohere/embed-v4.0 # must match the deployed model +OPENSEARCH_ML_MODEL_ID= # model ID returned by OpenSearch on deploy +# OPENSEARCH_EMBEDDING_DIMENSION=1024 # only if not using default 1536 +``` + +### Auto-deploy (self-hosted OpenSearch only) + +Plane AI can create and deploy the embedding model automatically when the migrator starts. Provide the model name and provider credentials — no manual OpenSearch setup needed. + +**Cohere:** + +```bash +EMBEDDING_MODEL=cohere/embed-v4.0 +COHERE_API_KEY=your-cohere-api-key +``` + +**OpenAI:** + +```bash +EMBEDDING_MODEL=openai/text-embedding-3-small +OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx +``` + +**AWS Bedrock:** + +```bash +EMBEDDING_MODEL=bedrock/amazon.titan-embed-text-v1 +BR_AWS_ACCESS_KEY_ID=your-access-key +BR_AWS_SECRET_ACCESS_KEY=your-secret-key +BR_AWS_REGION=us-east-1 +``` + +:::warning IAM permission required for Bedrock +The IAM user needs `bedrock:InvokeModel` on the target foundation model ARN, e.g.: +`arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v1` +::: + +:::info AWS managed OpenSearch +Auto-deploy requires direct ML access to OpenSearch. AWS managed OpenSearch restricts this, so deploy the model manually using the [AWS OpenSearch embedding guide](/self-hosting/govern/aws-opensearch-embedding), then use the model ID option above. +::: + +## Step 2 — Restart Plane + +After updating `/opt/plane/plane.env`, restart Plane: + +```bash +prime-cli restart +``` + +The Plane AI migrator runs automatically on start and handles embedding model deployment, index creation, and pipeline setup. + +## Step 3 — Vectorize existing data + +New content is indexed automatically. For existing work items and pages, run this in the API container: + +```bash +docker exec -it plane-api-1 sh +python manage.py manage_search_index --background --vectorize document index --force +``` + +## Changing the embedding model + +### Model only (same dimension) + +Update `EMBEDDING_MODEL` and provider credentials in `/opt/plane/plane.env`, restart Plane, then revectorize: + +```bash +docker exec -it plane-api-1 sh +python manage.py manage_search_index --background --vectorize document index --force +``` + +### Dimension change + +Update `EMBEDDING_MODEL`, `OPENSEARCH_EMBEDDING_DIMENSION`, and provider credentials in `/opt/plane/plane.env`, restart Plane, then rebuild and revectorize: + +```bash +# Rebuild indices with the new dimension +python manage.py manage_search_index index rebuild --force + +# Reindex and revectorize all existing documents +python manage.py manage_search_index --background --vectorize document index --force +``` + +`OPENSEARCH_EMBEDDING_DIMENSION` must match the actual output dimension of the model in `EMBEDDING_MODEL`. A mismatch breaks indexing silently.