From a5b656b47912e50a72d7ae7953e3ffb920cb4211 Mon Sep 17 00:00:00 2001 From: Andrew Goldis Date: Mon, 9 Nov 2026 21:26:28 -0700 Subject: [PATCH] feat: add the ai-queue-worker service [ENG-2181] On-prem webhooks no longer runs AI tasks. The new ai-queue-worker service consumes the ai-bmq queue; without it, AI explanations and chat stop. - Service in compose.currents.yml, same image repository and tag as the other services, same .env. Redis and MongoDB dependencies and the RustFS path-style setting are copied from webhooks. Compose files regenerated. - .env.example and the configuration reference list the LLM_* settings. - Docs: services list, ECR policy and image mirroring lists, changelog upgrade notes. The image exists only in the Currents release that contains currents-dev/currents#4874. Release this with that image tag. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_011baD3izoabUn31Y3WeQHMp --- docs/configuration.md | 18 ++++++++++++++++++ docs/container-images.md | 8 +++++--- on-prem/.env.example | 14 ++++++++++++++ on-prem/CHANGELOG.md | 10 ++++++++++ on-prem/README.md | 1 + on-prem/docker-compose.cache.yml | 14 ++++++++++++++ on-prem/docker-compose.database.yml | 17 +++++++++++++++++ on-prem/docker-compose.full.yml | 18 ++++++++++++++++++ on-prem/templates/compose.currents.yml | 11 +++++++++++ on-prem/templates/compose.mongodb.yml | 6 ++++++ on-prem/templates/compose.redis.yml | 6 ++++++ on-prem/templates/compose.rustfs.yml | 4 ++++ 12 files changed, 124 insertions(+), 3 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index a9fd5fa..136b099 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -94,6 +94,24 @@ Remote MCP lets coding agents use Currents tools over HTTP at `/mc | `OAUTH_JWKS_URL` | string | `/api/auth/jwks` | Where the API fetches its own signing keys to check access tokens. With a `.localhost` `APP_BASE_URL`, set `http://localhost:4000/api/auth/jwks`: the container cannot resolve `.localhost` names, so every token is rejected. Set the same when the container cannot reach or trust `APP_BASE_URL` (split DNS, an internal CA) | | `OAUTH_RATE_LIMIT_REGISTER_MAX`, `OAUTH_RATE_LIMIT_TOKEN_MAX`, `OAUTH_RATE_LIMIT_AUTHORIZE_MAX`, `OAUTH_RATE_LIMIT_USERINFO_MAX` | int | `5`, `20`, `30`, `60` | OAuth requests per client address per 60 seconds, on top of `BETTER_AUTH_RATE_LIMIT_MAX` | +### AI Explanations and Chat (Optional) + +The `ai-queue-worker` service runs the AI tasks (test explanations, chat) from the `ai-bmq` queue. It reads these variables from `.env`, as do all services. `webhooks` does not run AI tasks. + +| Variable | Type | Default | Description | +|----------|------|---------|-------------| +| `LLM_PROVIDER_URL` | string | `http://localhost:4001/v1` | Base URL of an OpenAI-compatible API | +| `LLM_API_KEY` | string | _(empty)_ | API key for the LLM provider | +| `LLM_MODEL` | string | `gpt-6-luna` | Model for chat and run-analysis sessions | +| `LLM_EXPLANATION_MODEL` | string | `gpt-6-luna` | Model for test and error explanations | +| `LLM_REASONING_EFFORT` | string | `medium` | `none`, `low`, `medium` or `high`; any other value falls back to `medium` | +| `LLM_EXPLANATION_REASONING_EFFORT` | string | `LLM_REASONING_EFFORT` | Reasoning effort for explanations; same values | +| `EXPLANATION_TRACE_TOOLS` | bool | `false` | `true`: error explanations read the Playwright trace of the failed attempt | +| `AI_QUEUE_CONCURRENCY` | int | `5` | AI tasks run at the same time | +| `USE_MOCK_AI` | bool | `false` | Return mock answers without calling an LLM (testing) | + +The service starts with the compose file. To run no worker, stop it with `docker compose stop ai-queue-worker`; AI tasks then wait in the queue. + ### SAML SSO (Optional) Enable SAML single sign-on by setting the two required variables and mounting your IdP metadata file into `./data/sso`. See [Enable SAML SSO](sso-saml.md) for the full walkthrough. SSO turns on automatically once both required variables are set — there is no separate enable flag. diff --git a/docs/container-images.md b/docs/container-images.md index e521ed4..9689f62 100644 --- a/docs/container-images.md +++ b/docs/container-images.md @@ -36,7 +36,9 @@ Create an IAM role in your AWS account with the following policy: "arn:aws:ecr:us-east-1:513558712013:currents/on-prem/writer/*", "arn:aws:ecr:us-east-1:513558712013:repository/currents/on-prem/writer", "arn:aws:ecr:us-east-1:513558712013:currents/on-prem/webhooks/*", - "arn:aws:ecr:us-east-1:513558712013:repository/currents/on-prem/webhooks" + "arn:aws:ecr:us-east-1:513558712013:repository/currents/on-prem/webhooks", + "arn:aws:ecr:us-east-1:513558712013:currents/on-prem/ai-queue-worker/*", + "arn:aws:ecr:us-east-1:513558712013:repository/currents/on-prem/ai-queue-worker" ] } ] @@ -76,7 +78,7 @@ TARGET_REGISTRY=your-registry.example.com/currents TAG=staging # or specific version tag # List of Currents services -SERVICES="api director change-streams scheduler writer webhooks" +SERVICES="api director change-streams scheduler writer webhooks ai-queue-worker" # Pull, tag, and push each image for service in $SERVICES; do @@ -155,7 +157,7 @@ SOURCE_REGISTRY=ghcr.io/currents-dev/currents- TARGET_REGISTRY=your-registry.example.com/currents/ TAG=staging -SERVICES="api director change-streams scheduler writer webhooks" +SERVICES="api director change-streams scheduler writer webhooks ai-queue-worker" for service in $SERVICES; do docker pull ${SOURCE_REGISTRY}${service}:${TAG} diff --git a/on-prem/.env.example b/on-prem/.env.example index a32d50a..a41cc50 100644 --- a/on-prem/.env.example +++ b/on-prem/.env.example @@ -184,6 +184,20 @@ OAUTH_DYNAMIC_CLIENT_REGISTRATION_ENABLED=true # OAUTH_RATE_LIMIT_AUTHORIZE_MAX=30 # OAUTH_RATE_LIMIT_USERINFO_MAX=60 +# ============================================================================= +# AI explanations and chat (Optional) +# ============================================================================= +# The ai-queue-worker service runs the AI tasks (test explanations, chat) and +# reads these settings. LLM_PROVIDER_URL is the base URL of an OpenAI-compatible API. +# LLM_PROVIDER_URL=https://llm.example.com/v1 +# LLM_API_KEY= +# LLM_MODEL= +# LLM_EXPLANATION_MODEL= +# LLM_REASONING_EFFORT= +# LLM_EXPLANATION_REASONING_EFFORT= +# EXPLANATION_TRACE_TOOLS= +# AI_QUEUE_CONCURRENCY=5 # AI tasks run at the same time + # ============================================================================= # SAML SSO (Optional) # ============================================================================= diff --git a/on-prem/CHANGELOG.md b/on-prem/CHANGELOG.md index 596e2b5..2df6a02 100644 --- a/on-prem/CHANGELOG.md +++ b/on-prem/CHANGELOG.md @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Unreleased] +### Compose File Changes +- New service `ai-queue-worker` in all three compose files. It runs the AI tasks (test explanations, chat) from the `ai-bmq` queue. Regenerate your compose file if you use custom templates. + +### Added +- Image `ai-queue-worker`. Pull or mirror it with the other images (see [Container Image Access](../docs/container-images.md)), and add the `currents/on-prem/ai-queue-worker` repository to your ECR policy. + +### Upgrade Notes +- `webhooks` no longer runs AI tasks. Without the `ai-queue-worker` service, AI explanations and chat stop. The service reads the same `.env` as the others; `LLM_PROVIDER_URL`, `LLM_API_KEY` and the other `LLM_*` settings apply to it (see AI Explanations and Chat in the [Configuration Reference](../docs/configuration.md)). +- If `.env` sets `AI_QUEUE_WORKER_ENABLED=true`, add `SLACK_AI_CALLBACK_WORKER_ENABLED=true` if you use Slack AI. In `webhooks` the first variable now only starts the Slack AI answer worker when the second is unset. The director still reads `AI_QUEUE_WORKER_ENABLED` to create the AI indexes in MongoDB, so keep it. + ## [2026-10-14-002] - 2026-10-27 Image-only update on `2026-10-14-001`: no compose file or environment variable changes. diff --git a/on-prem/README.md b/on-prem/README.md index 5b6fcc3..4138590 100644 --- a/on-prem/README.md +++ b/on-prem/README.md @@ -120,6 +120,7 @@ Utility for generating secrets and keys. - **write-worker** - Async write operations - **scheduler** - Scheduled tasks and startup migrations - **webhooks** - Webhook delivery service +- **ai-queue-worker** - Runs AI tasks (test explanations, chat) from the `ai-bmq` queue #### Data Services (optional, based on profile) diff --git a/on-prem/docker-compose.cache.yml b/on-prem/docker-compose.cache.yml index 1e0564f..e07878d 100644 --- a/on-prem/docker-compose.cache.yml +++ b/on-prem/docker-compose.cache.yml @@ -147,6 +147,20 @@ services: redis: condition: service_started required: false + # Runs the AI tasks from the ai-bmq queue. Reads the LLM_* settings from .env. + ai-queue-worker: + image: ${DC_CURRENTS_IMAGE_REPOSITORY:-currents-}ai-queue-worker:${DC_CURRENTS_IMAGE_TAG:-staging} + restart: unless-stopped + networks: + - default + env_file: + - .env + environment: + CURRENTS_ENV: onprem + depends_on: + redis: + condition: service_started + required: false traefik: hostname: traefik image: ${DC_TRAEFIK_IMAGE:-traefik:v3.3} diff --git a/on-prem/docker-compose.database.yml b/on-prem/docker-compose.database.yml index 158565c..a438fc3 100644 --- a/on-prem/docker-compose.database.yml +++ b/on-prem/docker-compose.database.yml @@ -169,6 +169,23 @@ services: redis: condition: service_started required: false + # Runs the AI tasks from the ai-bmq queue. Reads the LLM_* settings from .env. + ai-queue-worker: + image: ${DC_CURRENTS_IMAGE_REPOSITORY:-currents-}ai-queue-worker:${DC_CURRENTS_IMAGE_TAG:-staging} + restart: unless-stopped + networks: + - default + env_file: + - .env + environment: + CURRENTS_ENV: onprem + depends_on: + mongodb: + condition: service_healthy + required: false + redis: + condition: service_started + required: false traefik: hostname: traefik image: ${DC_TRAEFIK_IMAGE:-traefik:v3.3} diff --git a/on-prem/docker-compose.full.yml b/on-prem/docker-compose.full.yml index 4262cca..9b09fbd 100644 --- a/on-prem/docker-compose.full.yml +++ b/on-prem/docker-compose.full.yml @@ -175,6 +175,24 @@ services: redis: condition: service_started required: false + # Runs the AI tasks from the ai-bmq queue. Reads the LLM_* settings from .env. + ai-queue-worker: + image: ${DC_CURRENTS_IMAGE_REPOSITORY:-currents-}ai-queue-worker:${DC_CURRENTS_IMAGE_TAG:-staging} + restart: unless-stopped + networks: + - default + env_file: + - .env + environment: + CURRENTS_ENV: onprem + FILE_STORAGE_FORCE_PATH_STYLE: "true" + depends_on: + mongodb: + condition: service_healthy + required: false + redis: + condition: service_started + required: false # Enable RustFS storage routing in Traefik traefik: hostname: traefik diff --git a/on-prem/templates/compose.currents.yml b/on-prem/templates/compose.currents.yml index 1e8cc2e..b55d48a 100644 --- a/on-prem/templates/compose.currents.yml +++ b/on-prem/templates/compose.currents.yml @@ -116,6 +116,17 @@ services: CURRENTS_ENV: onprem EMAIL_TRANSPORTER: smtp + # Runs the AI tasks from the ai-bmq queue. Reads the LLM_* settings from .env. + ai-queue-worker: + image: ${DC_CURRENTS_IMAGE_REPOSITORY:-currents-}ai-queue-worker:${DC_CURRENTS_IMAGE_TAG:-staging} + restart: unless-stopped + networks: + - default + env_file: + - .env + environment: + CURRENTS_ENV: onprem + networks: default: null diff --git a/on-prem/templates/compose.mongodb.yml b/on-prem/templates/compose.mongodb.yml index e2cbbac..f476e66 100644 --- a/on-prem/templates/compose.mongodb.yml +++ b/on-prem/templates/compose.mongodb.yml @@ -86,3 +86,9 @@ services: mongodb: condition: service_healthy required: false + + ai-queue-worker: + depends_on: + mongodb: + condition: service_healthy + required: false diff --git a/on-prem/templates/compose.redis.yml b/on-prem/templates/compose.redis.yml index 6bb34fa..f705dd2 100644 --- a/on-prem/templates/compose.redis.yml +++ b/on-prem/templates/compose.redis.yml @@ -49,3 +49,9 @@ services: redis: condition: service_started required: false + + ai-queue-worker: + depends_on: + redis: + condition: service_started + required: false diff --git a/on-prem/templates/compose.rustfs.yml b/on-prem/templates/compose.rustfs.yml index 504ccb9..5043b89 100644 --- a/on-prem/templates/compose.rustfs.yml +++ b/on-prem/templates/compose.rustfs.yml @@ -153,3 +153,7 @@ services: webhooks: environment: FILE_STORAGE_FORCE_PATH_STYLE: "true" + + ai-queue-worker: + environment: + FILE_STORAGE_FORCE_PATH_STYLE: "true"