Tududi: add task tracke application
Linting / YAML Lint (push) Has been cancelled
Linting / Ansible Lint (push) Has been cancelled

This commit is contained in:
av
2026-07-04 16:56:01 +03:00
parent 8ec0327851
commit 5cd66d01bc
11 changed files with 846 additions and 162 deletions
+71
View File
@@ -0,0 +1,71 @@
{# Конфиг Bifrost ИСТОЧНИК ПРАВДЫ. Рендерится в config_dir/config.json (app-dir
Bifrost смонтирован на /app/data), Bifrost читает его при старте.
source_of_truth=config.json: на каждом старте секции этого файла авторитетно
перезаписывают состояние в config.db (git выигрывает у правок через UI).
Раскладка каталогов (по требованию «конфиги/данные раздельно»):
- config_dir -> /app/data : сам config.json (app-dir Bifrost по умолчанию);
- data_dir -> /app/store : config.db + logs.db (пути заданы явно ниже).
Несекретные настройки (base URL провайдера, имя модели) заданы здесь прямо
строками они больше нигде не переиспользуются. Секреты (ключ DeepSeek,
encryption_key) рендерятся строками из vars/secrets.yml, поэтому готовый
config.json секретный файл (плейбук пишет его на 0600).
Провайдер deepseek заведён как КАСТОМНЫЙ OpenAI-совместимый
(base_provider_type=openai + network_config.base_url) нативного провайдера
deepseek у Bifrost нет. ВАЖНО: Bifrost сам дописывает к base_url путь
/v1/chat/completions, поэтому base_url задаём БЕЗ хвостового /v1.
Роутинг декларативно через governance.routing_rules (требует включённого
config_store). tududi ходит на drop-in эндпоинт /openai и шлёт ЗАХАРДКОЖЕННОЕ
имя модели gpt-4o-mini «голым». Правило ловит его по cel и подменяет на
реальную модель deepseek/deepseek-v4-pro. Фолбэка нет единственный провайдер.
Чтобы сменить бэкенд-модель, правим ТОЛЬКО этот файл, конфиг tududi не трогаем.
Эти Jinja-комментарии в готовый config.json не попадают (на выходе чистый JSON). #}
{
"$schema": "https://www.getbifrost.ai/schema",
"encryption_key": {{ bifrost_encryption_key | to_json }},
"client": {
"enable_logging": true
},
"providers": {
"deepseek": {
"keys": [
{ "name": "deepseek-primary", "value": {{ bifrost_deepseek_api_key | to_json }}, "models": ["*"], "weight": 1.0 }
],
"network_config": { "base_url": "https://api.deepseek.com", "max_retries": 2 },
"custom_provider_config": {
"base_provider_type": "openai",
"allowed_requests": { "chat_completion": true, "chat_completion_stream": true }
}
}
},
"config_store": {
"enabled": true,
"type": "sqlite",
"config": { "path": "/app/store/config.db" },
"source_of_truth": "config.json"
},
"logs_store": {
"enabled": true,
"type": "sqlite",
"config": { "path": "/app/store/logs.db" }
},
"governance": {
"routing_rules": [
{
"id": "tududi-gpt4omini-to-deepseek-pro",
"name": "Tududi gpt-4o-mini -> DeepSeek v4 Pro",
"enabled": true,
"cel_expression": "model == 'gpt-4o-mini'",
"targets": [
{ "provider": "deepseek", "model": "deepseek-v4-pro", "weight": 1 }
],
"scope": "global",
"priority": 0
}
]
}
}
+33
View File
@@ -0,0 +1,33 @@
# Bifrost — LLM-gateway (github.com/maximhq/bifrost). Единый OpenAI-совместимый
# шлюз для AI-фич других приложений (сейчас — tududi). За ним провайдер DeepSeek.
# Клиенты ходят в него по имени bifrost_app:8080 в общей web_proxy_network и про
# провайдера/модель ничего не знают — роутинг решает config.json.
# See versions: https://hub.docker.com/r/maximhq/bifrost/tags
#
# В контейнере Bifrost слушает 8080 (дефолт). Наружу host-порт НЕ пробрасываем:
# веб-UI (Dashboard + Logs) и API доступны только через Caddy
# (bifrost.vakhrushev.me, за Authelia forward_auth) и внутри web_proxy_network.
#
# App-dir Bifrost по умолчанию — /app/data; туда монтируется config_dir с
# config.json (источник правды, с секретами, 0600). SQLite-сторы config.db /
# logs.db вынесены в data_dir -> /app/store (пути заданы явно в config.json).
services:
bifrost_app:
image: maximhq/bifrost:v1.6.2 # проверь актуальный стабильный тег в releases
container_name: bifrost_app
restart: unless-stopped
user: "{{ owner_create_result.uid }}:{{ owner_create_result.group }}"
networks:
- "web_proxy_network"
volumes:
# App-dir: config.json (рендерит плейбук).
- "{{ config_dir }}:/app/data"
# Сторы, создаёт и держит сам Bifrost — бекапить не нужно (config.db
# восстанавливается из config.json, logs.db — просто логи запросов).
- "{{ data_dir }}:/app/store"
networks:
web_proxy_network:
external: true