Skip to content

Latest commit

 

History

History
88 lines (71 loc) · 5.19 KB

File metadata and controls

88 lines (71 loc) · 5.19 KB

CodeBuddy2API — Agent Guide

Project Overview

FastAPI proxy service that wraps CodeBuddy's official API into an OpenAI-compatible interface (/v1/chat/completions). Includes a Web admin UI, OAuth2-based credential auto-acquisition, and hot-reloadable config.

Run / Dev

uv sync --extra dev     # install deps
python web.py            # run dev server (Hypercorn ASGI)
./run_docker_in_server.sh deploy  # build + run via Docker (tagged by git hash)

Entry point is web.py. No separate dev/watch mode — just restart.

Verify (run after every change)

ruff check .          # lint
mypy src/             # type check
pytest                # tests (no test files yet)

Config

  • Single source of truth: config/config.yaml (auto-created from the checked-in config.example.yaml on first run). Legacy config/config.json is auto-migrated once. No .env / env vars.
  • server.password is required — service returns 500 if unset
  • All log params (level/rotation/retention/compression) live under logging.* and are read live by src/core/logging.py; changing them via the UI rebuilds the loguru handlers
  • Default API endpoint is codebuddy.cn — configurable, used dynamically everywhere
  • Credentials stored as JSON files in .codebuddy_creds/; token manager auto-rotates them
  • Settings changes via Web UI persist to config/config.yaml (full overwrite) and hot-reload without restart
  • The Settings API still speaks flat CODEBUDDY_* keys for frontend compatibility; src/core/config.py translates flat ↔ nested internally

Architecture

web.py                    → FastAPI app, lifespan, mounts all routers
config.py                 → Config loading/hot-reload/save (singleton module, auto-loads on import)
src/
  auth.py                 → Bearer token auth (password == CODEBUDDY_PASSWORD)
  http_client.py          → HTTP client pool + lifecycle manager (imports lifecycle_manager for web.py)
  sse_utils.py            → SSE parsing, formatting, OpenAI compatibility converter
  stream_handler.py       → SSE connection manager, response aggregator, stream/non-stream service
  request_processor.py    → Request validation + payload prep, credential selection
  codebuddy_router.py     → Route definitions only (~240 lines, delegates to other modules)
  codebuddy_api_client.py → CodeBuddy header generation, message conversion
  codebuddy_token_manager.py → Credential loading, rotation, state persistence
  codebuddy_auth_router.py → OAuth2 PKCE flow for auto-acquiring CodeBuddy tokens
  keyword_replacer.py     → Replaces competitor names in responses
  frontend_router.py      → Serves frontend/admin.html
  settings_router.py      → GET/POST /api/settings, /api/stats
  usage_stats_manager.py  → Singleton, in-memory thread-safe counters
  models.py               → Pydantic request/response models
frontend/admin.html       → Single-file Web UI

Key Gotchas

  • No requirements.txt — deps are in pyproject.toml + uv.lock. Use uv sync, not pip
  • src/core/config.pysrc/core/logging.py have a circular import: config calls apply_log_level at end of its import; logging reads config lazily inside functions. Don't add top-level config imports to logging.py
  • CodeBuddy's API is stream-only; non-stream requests are assembled by buffering SSE chunks in stream_handler.py
  • keyword_replacer.py mutates responses to swap competitor names — be aware when debugging response content issues
  • Endpoint URLs (Host, X-Domain) are extracted dynamically from the codebuddy.api_endpoint config
  • authenticate is defined once in src/auth.py — other modules import from there

Docker

  • Deploy via run_docker_in_server.sh (subcommands: build/deploy/start/images/rm-image/help). No docker-compose. deploy = build + start + cleanup; build only builds the image.
  • Image is tagged by the git commit hash prefix (IMAGE_TAG_LENGTH, default 8); the full hash is baked in as the org.opencontainers.image.revision label via the CODEBUDDY2API_GIT_COMMIT_HASH build-arg.
  • Volume mounts (bind, under DATA_ROOT, default $REPO_ROOT/data): config//app/config, creds//app/.codebuddy_creds, logs//app/logs.
  • On first deploy the script copies config.example.yaml into DATA_ROOT/config/config.yaml and rewrites server.host to 0.0.0.0 (set SKIP_CONFIG_ADAPT=1 to skip). creds_dir stays .codebuddy_creds, which resolves to the mounted /app/.codebuddy_creds.
  • deploy waits for /health before cleaning old images (IMAGE_RETENTION_COUNT, default 5).

API Routes

Route Auth Purpose
POST /codebuddy/v1/chat/completions Bearer (password) Core chat proxy
GET /codebuddy/v1/models Bearer List configured models
GET /codebuddy/v1/credentials Bearer List loaded credentials
POST /codebuddy/v1/credentials/delete Bearer Delete credential by index
GET /codebuddy/auth/start None Begin OAuth2 flow
GET /codebuddy/auth/poll None Poll auth status
GET /api/settings Bearer Read config
POST /api/settings Bearer Update + persist + hot-reload config
GET /api/stats Bearer Usage counters
GET /health None Health check