- Go 100%
- weekly в /quota дополнен windowStart/windowEnd/ideal/rel (считается на момент запроса) - якорь окна — понедельник 20:00 МСК; плавающий weekly.resetAt Z.AI больше не участвует в расчёте - guard: первые 2 часа окна rel = 100 (лечит W200 сразу после сброса; ideal теперь float без раннего округления) - поллер логирует сырые значения weekly при изменении + mismatch окна с resetAt > 15 мин - тесты: weeklyWindow, weeklyIdealRel (точка Вт 11:00 → 22), обогащение в Store.Get, лог поллера |
||
|---|---|---|
| config | ||
| middleware | ||
| proxy | ||
| quota | ||
| .gitignore | ||
| go.mod | ||
| go.sum | ||
| main.go | ||
| README.md | ||
api-proxy
Локальный Go-прокси для API ai-helper. Проксирует запросы агентов OpenClaw с localhost:8085/ai-helper/* на https://asvdev.ru/api/openclaw/*, автоматически подставляя Bearer-токен.
Запуск
cd ~/web/golang/api-proxy
./api-proxy
Конфигурация
Файл config.yaml (не в git):
upstream: https://asvdev.ru
port: 8085
token: "<token>"
logRequests: true
Переменные окружения имеют приоритет:
API_PROXY_UPSTREAMAPI_PROXY_PORTAPI_PROXY_TOKENAPI_PROXY_LOG_REQUESTS
Использование агентами
Все запросы выполнять к http://localhost:8085/ai-helper/... вместо прямого обращения к https://asvdev.ru/api/openclaw/.... Прокси пробрасывает все HTTP-методы (GET, POST, PUT, DELETE), заголовки и тело запроса, включая multipart/form-data.
Примеры
# Health check
curl http://localhost:8085/health
# Health upstream через прокси
curl http://localhost:8085/ai-helper/health
# Список задач
curl http://localhost:8085/ai-helper/tasks
# Создать задачу
curl -X POST http://localhost:8085/ai-helper/tasks \
-H "Content-Type: application/json" \
-d '{"title":"Тест","description":"Проверка прокси"}'
# Загрузить отчёт
curl -X POST http://localhost:8085/ai-helper/reports \
-F "file=@report.md" \
-F "task_id=123"
Квоты Z.AI (GET /quota)
Если в конфиге задан zaiToken (плюс zaiQuotaURL, по умолчанию
https://api.z.ai/api/monitor/usage/quota/limit, и zaiQuotaInterval, по
умолчанию 5m), прокси раз в 5 минут опрашивает квоты Z.AI и отдаёт кэш на
GET http://localhost:8085/quota. Потребитель — quota-tray.
{
"ok": true,
"fetchedAt": "2026-09-08T11:00:00+03:00",
"stale": false,
"fiveHour": {"percent": 2, "resetAt": "2026-09-08T14:00:00+03:00"},
"weekly": {
"percent": 2, "resetAt": "2026-09-14T20:05:00+03:00",
"windowStart": "2026-09-07T20:00:00+03:00",
"windowEnd": "2026-09-14T20:00:00+03:00",
"ideal": 9, "rel": 22
},
"mcp": {"percent": 19, "resetAt": "2026-09-11T20:05:00+03:00"},
"level": "pro", "error": ""
}
Недельное окно — фиксированное расписание «понедельник 20:00 МСК → понедельник
20:00 МСК» (не плавающий weekly.resetAt от Z.AI; тот используется только для
отображения и сверки — расхождение больше 15 минут пишется в журнал поллера).
ideal — идеальный нарастающий расход к текущему моменту
(elapsed/168ч×100), rel — относительный расход (percent/ideal×100,
кап 999); в первые 2 часа окна показывается 100. Диагностика сброса — в
журнале сервиса: поллер логирует сырые значения weekly при каждом изменении.
Systemd
systemctl --user status api-proxy
systemctl --user restart api-proxy
systemctl --user stop api-proxy
Автозапуск при загрузке включён через loginctl enable-linger sergey.