Add OpenAI-compatible LLM provider (URL/model/key configurable)

- New provider 'openai' calls any OpenAI-compatible /chat/completions endpoint
  (OpenAI, OpenRouter, Together, Groq, NVIDIA, vLLM, Ollama, ...), set via
  OPENAI_BASE_URL / OPENAI_API_KEY / OPENAI_MODEL. Now the default; auto-detects.
- Robustness for models that degenerate (e.g. Kimi repetition loops): anti-
  repetition sampling (temperature + frequency penalty), and a schema-aware
  retry — call_json(require_keys=...) retries a fresh sample on degenerate or
  unparseable output (LLMRetryable). Relevance requires 'signals', synth 'briefs'.
- response_format=json_object (toggle via OPENAI_JSON_MODE); base URL accepts a
  full /chat/completions URL or a /v1 base.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-24 10:19:52 -04:00
parent b4e3ed9d9b
commit 2374ef137d
6 changed files with 135 additions and 22 deletions

View File

@@ -1,12 +1,20 @@
# Copy to .env and fill in. The loop runs WITHOUT a key using a mock reasoner.
# --- LLM provider ---
# LLM_PROVIDER: gemini | anthropic (auto-detected from whichever key is set,
# Gemini preferred, if left blank). Provider with a missing key => mock reasoner.
LLM_PROVIDER=gemini
# LLM_PROVIDER: openai | gemini | anthropic (auto-detected from whichever key is
# set if blank; OpenAI-compatible preferred). Provider w/ a missing key => mock.
LLM_PROVIDER=openai
# OpenAI-compatible endpoint — works with OpenAI, OpenRouter, Together, Groq,
# vLLM, Ollama, LM Studio, etc. Just point these three at any /chat/completions API:
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_API_KEY=
OPENAI_MODEL=gpt-4o-mini
OPENAI_JSON_MODE=1 # set 0 if the endpoint rejects response_format=json_object
# Other providers:
GEMINI_API_KEY=
GEMINI_MODEL=gemini-2.5-flash
ANTHROPIC_API_KEY=
LLM_MODEL=claude-sonnet-4-6