Skip to content

feat: OPENAI_BASE_URL for OpenAI-compatible endpoints + secret-free mock E2E - #993

Merged
icereed merged 1 commit into
mainfrom
e2e-mock-llm
Jul 8, 2026
Merged

feat: OPENAI_BASE_URL for OpenAI-compatible endpoints + secret-free mock E2E#993
icereed merged 1 commit into
mainfrom
e2e-mock-llm

Conversation

@icereed

@icereed icereed commented Jul 7, 2026

Copy link
Copy Markdown
Owner

What

Two tightly coupled changes:

1. OPENAI_BASE_URL now works without Azure

Previously OPENAI_BASE_URL was only honored when OPENAI_API_TYPE=azure. It is now respected for the plain openai provider too (both the LLM and the vision path), enabling any OpenAI-compatible endpoint: OpenRouter, LiteLLM, vLLM, … (long-standing community ask, related to #979).

2. Secret-free E2E mock mode

npm run test:e2e:mock (env E2E_LLM_MODE=mock) starts a WireMock container serving canned OpenAI-compatible completions (web-app/e2e/mocks/) and points paperless-gpt at it via the new OPENAI_BASE_URL support. The main document-processing flow (upload → Generate Suggestions → Apply → History → Undo) runs deterministically with zero API keys and zero cost.

Each stub matches a distinctive phrase from its prompt template in default_prompts/; a low-priority catch-all answers anything else.

Why

Part 2/3 of the contributor-friendly CI rework: this is the E2E tier that will run automatically on every PR including forks — no secrets involved, so no security gate needed. Real-LLM E2E moves behind a maintainer approval gate in the follow-up PR.

Verified

Locally with OPENAI_API_KEY/MISTRAL_API_KEY/ANTHROPIC_API_KEY explicitly unset:

Starting WireMock LLM mock container...
WireMock LLM mock container started
  1 passed (1.0m)

go test ./... passes. Existing test:e2e behavior is unchanged (mock mode is opt-in via env var).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a mock mode for end-to-end tests, allowing document-processing flows to run without real API keys.
    • Added support for OpenAI-compatible endpoints in app configuration, including clearer Azure usage guidance.
  • Documentation

    • Expanded setup guides with instructions for mock E2E runs and updated environment variable details.
  • Tests

    • Added canned mock responses for common document tasks so automated tests can run consistently and deterministically.

…e mock E2E

Backend: OPENAI_BASE_URL is now respected for the plain openai provider
(LLM and vision paths), not only for Azure. This enables OpenAI-compatible
endpoints like OpenRouter, LiteLLM and vLLM — and mock servers in tests.

E2E: new mock mode (E2E_LLM_MODE=mock) starts a WireMock container with
canned chat-completion stubs and points paperless-gpt at it. The main
document-processing flow now runs deterministically with zero API keys:

    npm run test:e2e:mock

This is the basis for running E2E on every fork PR in CI without exposing
any secrets. Verified locally: 1 passed (1.0m) with all LLM API key env
vars unset.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 02df098c-accb-4b4f-8029-a1675027d7b9

📥 Commits

Reviewing files that changed from the base of the PR and between befe34c and 60c3c2c.

📒 Files selected for processing (13)
  • README.md
  • main.go
  • web-app/e2e/README.md
  • web-app/e2e/mocks/README.md
  • web-app/e2e/mocks/correspondent.json
  • web-app/e2e/mocks/created-date.json
  • web-app/e2e/mocks/custom-fields.json
  • web-app/e2e/mocks/default.json
  • web-app/e2e/mocks/document-type.json
  • web-app/e2e/mocks/tags.json
  • web-app/e2e/mocks/title.json
  • web-app/e2e/test-environment.ts
  • web-app/package.json

📝 Walkthrough

Walkthrough

This PR adds OPENAI_BASE_URL support for non-Azure OpenAI client configuration in main.go, introduces a WireMock-based mock LLM mode for E2E tests (with mock response fixtures for correspondent, dates, custom fields, document types, tags, and titles), and updates documentation and the npm test script accordingly.

Changes

OpenAI-compatible base URL and E2E mock mode

Layer / File(s) Summary
OpenAI-compatible base URL support
main.go, README.md
createLLM and createVisionLLM now append openai.WithBaseURL when OPENAI_API_TYPE is not azure and OPENAI_BASE_URL is set; README's environment-variable docs expanded accordingly.
WireMock mock LLM mode wiring
web-app/e2e/test-environment.ts
Adds isMockLlmMode() helper, conditionally starts a WireMock container with mounted mock mappings, and sets OPENAI_API_KEY/OPENAI_BASE_URL for the paperless-gpt container in mock mode.
Mock fixtures, npm script, and docs
web-app/e2e/mocks/*.json, web-app/package.json, web-app/e2e/README.md, web-app/e2e/mocks/README.md
Adds static WireMock JSON response fixtures for correspondent, created-date, custom-fields, default, document-type, tags, and title requests; adds test:e2e:mock npm script; documents mock mode usage.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Developer
  participant setupTestEnvironment
  participant WireMockContainer
  participant PaperlessGptContainer

  Developer->>setupTestEnvironment: run test:e2e:mock (E2E_LLM_MODE=mock)
  setupTestEnvironment->>setupTestEnvironment: isMockLlmMode() returns true
  setupTestEnvironment->>WireMockContainer: start container, mount mocks/ mappings
  WireMockContainer-->>setupTestEnvironment: admin mappings endpoint ready
  setupTestEnvironment->>PaperlessGptContainer: set OPENAI_API_KEY=mock-key, OPENAI_BASE_URL=http://llm-mock:8080/v1
  PaperlessGptContainer->>WireMockContainer: POST /v1/chat/completions
  WireMockContainer-->>PaperlessGptContainer: static mock completion response
Loading

Possibly related PRs

  • icereed/paperless-gpt#358: Both PRs modify main.go's createLLM() and createVisionLLM() to adjust OpenAI client configuration based on OPENAI_API_TYPE and OPENAI_BASE_URL.
  • icereed/paperless-gpt#379: Both PRs modify web-app/e2e/test-environment.ts's setupTestEnvironment to configure LLM environment variables for E2E test containers.
  • icereed/paperless-gpt#97: Both PRs update README.md to document OPENAI_BASE_URL configuration.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main changes: broader OPENAI_BASE_URL support and secret-free mock E2E runs.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch e2e-mock-llm

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@icereed
icereed merged commit d358eac into main Jul 8, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant