ollama-proxy/AGENTS.md
Atte149 98bbc96bf5 docs: separate opencode vs openlama provider isolation
- opencode (global config) sees marg/fireworks only, no ocp
- openlama (OPENCODE_CONFIG=openlama.json) sees ocp only via enabled_providers
- Verified: opencode run -m ocp/... → Model not found; openlama run -m ocp/... → OK
- openlama launcher sets OPENCODE_CONFIG + NO_PROXY + execs opencode
2026-06-19 14:18:14 +03:00

106 lines
No EOL
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AGENTS.md — ollama-proxy
## Контекст
`ollama-proxy` — Go-прокси для Ollama Cloud (`https://ollama.com`). Балансирует запросы по нескольким API-ключам с round-robin и failover на 429/5xx. Слушает `127.0.0.1:11435`, экспонирует нативный Ollama API (`/api/*`) и OpenAI-совместимый (`/v1/*`) passthrough. Деплой — systemd unit `ollama-proxy.service`. Используется opencode через кастомный провайдер `ocp`.
## Стек
- Go 1.22 (используется `log/slog`, `net/http`, `net/http/httputil`)
- Единственная внешняя зависимость: `golang.org/x/term` (prompt без echo в `accounts add`)
- Go 1.18 из apt НЕ подходит — нужен `~/.local/go/bin/go` (Go 1.22.10). Перед сборкой: `export PATH="$HOME/.local/go/bin:$PATH"`
- Сборка: `make build``./ollama-proxy`
- Тесты: `go test ./...` (43 теста, включая integration-тесты с `httptest`)
- Линт: `go vet ./...`, `gofmt -l .`
## Структура
```
main.go — точка входа, делегирует в cli.Run
internal/config/
accounts.go — Account, AccountsFile, JSON load/save (chmod 0600, atomic)
server.go — ServerConfig (addr, base_url, cooldown, retries, log_level)
internal/log/logger.go — slog JSON logger с configurable level
internal/proxy/
balancer.go — round-robin + per-account cooldown (RWMutex)
handler.go — HTTP handler: reverse-proxy, Authorization подмена, SSE flush
retry.go — документация стриминг-инварианта
internal/cli/
root.go — dispatch подкоманд (serve / accounts / version)
accounts.go — add / list / remove / set-base-url
serve.go — запуск HTTP-сервера с signal handling
systemd/ollama-proxy.service — systemd unit
```
## Конфигурация
- Аккаунты: `~/.config/ollama-proxy/accounts.json` (XDG_CONFIG_HOME, chmod 0600, atomic write)
- Флаги `serve`: `--addr`, `--base-url`, `--cooldown`, `--retries`, `--log-level`
- Env vars: `OLLAMA_PROXY_ADDR`, `OLLAMA_PROXY_BASE_URL`, `OLLAMA_PROXY_COOLDOWN`, `OLLAMA_PROXY_RETRIES`, `OLLAMA_PROXY_LOG_LEVEL`
## Типичные задачи
- **Добавить аккаунт:** `ollama-proxy accounts add --name <alias>` (промпт) или `... add <key> --name <alias>`
- **Перезапустить после правки аккаунтов:** `sudo systemctl restart ollama-proxy` (прокси читает accounts.json при старте; runtime-обновления не поддерживаются)
- **Посмотреть логи:** `journalctl -u ollama-proxy -f` — JSON-структурированные (account, account_id, path, status, latency_ms, stream)
- **Проверить, что прокси жив:** `curl http://127.0.0.1:11435/api/version` → должен вернуть JSON от ollama.com
- **Проверить список моделей:** `curl http://127.0.0.1:11435/v1/models | jq '.data | length'` (~35 моделей)
- **Запустить opencode с пулом:** `openlama` (обёртка в `~/.local/bin/openlama`, выставляет NO_PROXY и запускает opencode)
- **Обновить список моделей в opencode-конфиге:** `curl -sS http://127.0.0.1:11435/v1/models | jq -r '.data[].id'` → обновить `models` блок в `~/.config/opencode/opencode.json`
## Интеграция с opencode
**Два отдельных конфига:** `opencode` видит только marg/fireworks, `openlama` видит только ocp.
- `~/.config/opencode/opencode.json` — глобальный конфиг с `marg` + `fireworks` (без `ocp`)
- `~/.config/opencode/openlama.json` — отдельный конфиг с `ocp` + `"enabled_providers": ["ocp"]`. Содержит те же instructions/mcp/plugins/agent что глобальный, но только провайдер `ocp`.
- `~/.local/bin/openlama` — обёртка, выставляет `OPENCODE_CONFIG=~/.config/opencode/openlama.json` + `NO_PROXY=127.0.0.1,localhost,::1` + `exec opencode "$@"`
openlama.json (ключевая часть):
```json
{
"enabled_providers": ["ocp"],
"provider": {
"ocp": {
"npm": "@ai-sdk/openai-compatible",
"name": "Ollama Cloud (pool)",
"options": {
"baseURL": "http://127.0.0.1:11435/v1",
"apiKey": "proxy"
},
"models": {
"gpt-oss:20b": { "name": "gpt-oss:20b" },
"...": { "name": "..." }
}
}
}
}
```
`OPENCODE_CONFIG` мерджится с глобальным конфигом, но `enabled_providers: ["ocp"]` перекрывает глобальный — `marg`/`fireworks` скрыты.
**Модель не сделана дефолтной** — выбирается через `/models` в TUI.
**ВАЖНО: NO_PROXY.** Если в окружении установлен `HTTP_PROXY`/`HTTPS_PROXY` (например `http://127.0.0.1:2080`), opencode (Bun runtime) направит запросы к прокси через HTTP-прокси → 502 Bad Gateway. Нужно явно исключить localhost:
```sh
# В ~/.config/environment.d/no-proxy-local.conf (systemd/desktop sessions):
NO_PROXY=127.0.0.1,localhost,::1
no_proxy=127.0.0.1,localhost,::1
```
Или запускать opencode с `NO_PROXY=127.0.0.1,localhost opencode ...`.
**Модели в конфиге:** opencode НЕ умеет динамически резолвить модели через `/v1/models` для `@ai-sdk/openai-compatible``models: {}` даёт `ProviderModelNotFoundError`. Нужно явно перечислить модели. Обновить список: `curl -sS http://127.0.0.1:11435/v1/models | jq -r '.data[].id'` → вставить в `models` блок.
## WARN
- **Никогда** не запускай прокси на `0.0.0.0` без auth — он не имеет аутентификации, любой может использовать твои ключи
- `accounts.json` содержит ключи в plaintext — файл chmod 0600, не коммить в git
- После правки `accounts.json` нужен `sudo systemctl restart ollama-proxy` (прокси не перечитывает файл в рантайме)
- Если локальная `ollama` запущена на 11434 — это НЕ конфликтует (прокси на 11435), но `OLLAMA_HOST=127.0.0.1:11435` нужно явно указывать
- Стриминг-инвариант: после первого flush-а 2xx ответа переключение аккаунта НЕ происходит. Mid-stream ошибки → truncated response клиенту. Это by design (нельзя дублировать вывод)
- 5xx НЕ вызывает cooldown аккаунта (только 429). 5xx → failover на следующий аккаунт, но без penalty
## План отката
- `sudo systemctl stop ollama-proxy && sudo systemctl disable ollama-proxy`
- `sudo rm /usr/local/bin/ollama-proxy /etc/systemd/system/ollama-proxy.service && sudo systemctl daemon-reload`
- Убрать блок `ocp` из `~/.config/opencode/opencode.json`