Frontier Intelligence
Provides monitoring and observability capabilities through Grafana dashboards for runtime metrics and system health visualization.
Ingests content from Habr as a source for trend analysis and knowledge extraction, processing articles through the enrichment pipeline.
Integrates LangChain for orchestration of enrichment tasks including relevance filtering, concept extraction, and workspace routing.
Stores and queries concept graphs with workspace isolation, enabling graph-based knowledge representation and relationship analysis.
Uses OpenAI SDK for LLM integration via gpt2giga-proxy, powering relevance scoring, concept extraction, and semantic analysis.
Serves as canonical storage for raw data, metadata, and trend clusters with workspace isolation across all major tables.
Collects and exposes runtime metrics for monitoring system performance and operational health.
Provides stream-based messaging for ingest pipelines and supports caching and queue management for processing tasks.
Ingests content from RSS/Atom feeds as source material for trend detection and knowledge base population.
Performs gap analysis to identify missing signals by comparing expected topic distributions against actual content.
Ingests content from Telegram channels using Telethon with account rotation and proxy support for data collection.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Frontier Intelligencesummarize recent AI trends for my research project"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Frontier Intelligence
Recent Docs
Актуализация health-эндпоинтов и формулировок (reindex, workspace vs MCP-клиент): этот файл,
CLAUDE.md,AGENTS.md,docs/security-git-preflight.md,docs/server-git-workflow.md(2026-04-18).Rollout summary for the multi-connector production upgrade: CHANGELOG-2026-03-28.md
Source connector model, runtime tables, proxy rules, and live starter bundle: source-connectors-runbook.md
Server-side operational notes and common container issues: ops-server-troubleshooting.md
End-to-end pipeline verification checklist: pipeline-e2e-checklist.md
Security and first-git preflight: security-git-preflight.md
Server-first git workflow: server-git-workflow.md
Current Runtime
Runtime LLM integration uses
openai==1.54.4againstgpt2giga-proxy.Current production-safe routing:
GIGACHAT_MODEL=GigaChat-2GIGACHAT_MODEL_LITE=GigaChat-2GIGACHAT_MODEL_RELEVANCE=GigaChat-2GIGACHAT_MODEL_CONCEPTS=GigaChat-2GIGACHAT_MODEL_MCP_SYNTHESIS=GigaChat-2GIGACHAT_MODEL_PRO=GigaChat-2-ProGIGACHAT_VISION_MODEL=GigaChat-2-Pro
GigaChat-2-Litemust not be used in runtime config until it appears inGET /v1/modelson the active proxy/upstream.X-Session-IDand/tokens/countare best-effort optimizations. If the current SDK/proxy pair rejects them, the pipeline should continue working without cache or token-count support.For Balanced rollout keep
INDEXING_MAX_CONCURRENCY=1on this contour unless live metrics show enough headroom.Git / сервер (2026-04-18): рабочее дерево на сервере
/opt/frontier-intelligence— первая зафиксированная база; общая история — в Git remote после push. В git не попадают только рантайм-пути (.env,sessions/,searxng/settings.yml, данные Docker volumes). Qdrant:frontier_docs(dense + sparse),trend_clusters— вторичный индекс для стабильных trend-кластеров из PostgreSQL.Crawl/Vision →
stream:posts:reindex: полностью в коде (shared/reindex.py,worker/tasks/reindex_task.py, публикация изvision_taskиcrawl4ai). Массовый догон — операция (scripts/enqueue_reindex_enriched_posts.py); при работе смотриXLEN stream:posts:reindexиXINFO GROUPS. Под нагрузку можно временно поднятьGIGACHAT_MIN_REQUEST_INTERVAL_MS(например5000) — параметр уже читается изshared/config.py/ compose, это тюнинг окружения, а не «недореализованная фича».
Быстрая проверка HTTP (на хосте с проброшенными портами compose)
В текущем docker-compose.yml нет единого публичного «монолитного» API на :8000 (в отличие от старых стеков). Типовые проверки:
curl -sS http://127.0.0.1:8100/healthz # MCP
curl -sS http://127.0.0.1:8101/api/health # Admin
curl -sS http://127.0.0.1:8100/metrics # метрики MCP (Prometheus)Прочие сервисы: PaddleOCR http://127.0.0.1:8008/readyz, Prometheus 9090, Grafana 3000 — см. docs/security-git-preflight.md и docker compose ps.
Персональная система мониторинга и синтеза трендов.
Собирает сигналы из множества источников, обрабатывает через LangChain/GigaChat,
хранит в векторной базе и графе знаний, отдаёт через MCP в Codex/Claude-проекты.
Один сервис — несколько рабочих пространств (workspace).
Каждый Codex/Claude-проект подключается к одному MCP, но работает со своей изолированной базой данных.
Все настройки — источники, категории, веса, расписания — управляются через Admin UI.
Концепция Workspace
Один стек frontier-intelligence
│
├── workspace: disruption → automotive, hmi, future mobility, ev
│ └── Codex Project: visionary-designer
│
├── workspace: ai_trends → LLM, agents, AI tools, research, inference
│ └── Внешний MCP-клиент: ai-researcher (по желанию; данные и конфиг уже в стеке)
│
└── workspace: design → design systems, UX patterns, visual culture
└── Внешний MCP-клиент: design-director (по желанию; данные и конфиг уже в стеке)Уточнение:
ai_trends,design, а такжеai_research/ai_products_mediaзаданы вconfig/workspaces.ymlи привязаны к источникам вconfig/sources.yml(workspace_id, мосты, веса). «Будущий» во внешних гайдах означал только отдельный Codex/Claude-проект, подключаемый к этому MCP, а не отсутствие бэкенда.
Изоляция на уровне данных, не инфраструктуры:
Каждый документ, тренд, концепт помечен
workspace_idQdrant payload фильтрует по workspace при каждом запросе
Neo4j:
(:Workspace)— отдельный узел-корень для каждого пространстваPostgreSQL:
workspace_id TEXT NOT NULLво всех основных таблицах
Cross-workspace сигналы:
get_frontier_briefможет тянуть из нескольких workspace одновременноТренд из
ai_trendsможет попасть вdisruptionесли релевантен обоимУправляется через Admin UI: настройка cross-workspace bridges
Статус реализации
Компонент | Статус | Заметки |
Core infra (postgres, redis, qdrant, neo4j, gpt2giga-proxy) | ✅ Работает | |
Ingest: telegram, rss, habr, web | ✅ Работает | Album dedup, account rotation, DB proxy |
Worker: relevance → concepts → valence → embeddings → Qdrant | ✅ Работает | Hybrid dense + BM25 sparse via fastembed |
Worker: Neo4j concept graph | ✅ Работает | Inline write from enrichment; separate |
Admin UI: workspaces, sources, pipeline, search | ✅ Работает | |
MCP: search, observability, clusters, source health, ingest_url | ✅ Работает | REST tools on |
Vision pipeline (S3, GigaChat Vision, PaddleOCR) | ✅ Работает |
|
Semantic/trend/emerging clusters | ✅ Работает | PostgreSQL is canonical; stable trend clusters are mirrored to Qdrant |
Missing signals | ✅ Работает | SearXNG gap analysis persists |
Prometheus + Grafana dashboards | ✅ Работает | Runtime dashboard provisioned |
Архитектура
┌──────────────────────────────────────────────────────────────────────┐
│ SOURCES LAYER │
│ │
│ ┌──────────────────┐ ┌─────────────┐ ┌────────────────────────┐ │
│ │ Telegram │ │ RSS / Atom │ │ Web (crawl4ai) │ │
│ │ Telethon │ │ feedparser │ │ Habr, Yanko, кастом │ │
│ │ 2 аккаунта │ │ │ │ │ │
│ │ MTProxy/SOCKS5│ │ │ │ │ │
│ └────────┬─────────┘ └──────┬──────┘ └──────────┬────────────┘ │
└───────────┼──────────────────-┼──────────────────── ┼──────────────┘
└──────────────────-▼─────────────────────┘
Redis Stream: stream:posts:parsed
payload: {content, source_id, workspace_id, ...}
│
┌─────────────────────────────────▼────────────────────────────────────┐
│ PROCESSING LAYER │
│ LangChain + GigaChat via gpt2giga-proxy │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ EnrichmentTask (LangChain RunnableBranch) │ │
│ │ → Relevance filter: score + category (GigaChat) │ │
│ │ → Tagging & workspace routing │ │
│ │ → Concept extraction → Neo4j (NER/NEL) │ │
│ │ → Embeddings (EmbeddingsGigaR, 2560d) → Qdrant │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Vision Pipeline (посты с медиа и альбомы) │ │
│ │ → GigaChat Vision: labels, OCR, scene, design signals │ │
│ │ → S3/Cloud.ru: медиа + vision_summary_v1.json (gzip) │ │
│ │ → Album Assembler: event-driven агрегация (4 фазы) │ │
│ │ → Vision vectors → Qdrant, visual concepts → Neo4j │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Trend Detection (два параллельных пайплайна) │ │
│ │ Reactive (cron 30 мин): burst_score — всплески частоты │ │
│ │ Stable (cron сутки): HDBSCAN семантическая кластеризация │ │
│ │ → TrendCluster {title, insight, opportunity, │ │
│ │ burst_score, coherence, novelty} │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ Missing Signals (cron сутки) │ │
│ │ → SearXNG: "нормальное" распределение тем по workspace │ │
│ │ → Gap analysis: что должно быть, но отсутствует в базе │ │
│ └────────────────────────────────────────────────────────────────┘ │
└─────────────────────────┬────────────────────────────────────────────┘
│
┌───────────────┼────────────┬──────────────┐
▼ ▼ ▼ ▼
Qdrant Neo4j PostgreSQL S3/Cloud.ru
hybrid RAG GraphRAG raw + meta media + vision
dense+BM25 community posts, images,
dim=2560 detection clusters, album summaries,
per-workspace NER/NEL indexing, OCR results
workspaces workspaces
│ │ │
┌─────────▼───────────────▼────────────▼────────────────────────────────┐
│ MCP SERVER │
│ │
│ search_frontier search_balanced list_clusters │
│ list_sources_health get_pipeline_stats get_signal_timeline │
│ list_missing_signals get_source_details ingest_url │
│ │
│ все инструменты: workspace-aware, GigaChat pre-synthesis внутри │
└───────────────────────────────────┬────────────────────────────────────┘
│
┌───────────────┼──────────────────┐
▼ ▼ ▼
Codex Project Codex Project Codex Project
visionary- ai-researcher design-director
designer (будущий) (будущий)Технологический стек
Компонент | Образ / Библиотека | Роль |
gpt2giga-proxy | локальная сборка, порт 8090 | GigaChat через OpenAI API интерфейс |
LangChain / gigachain | pip | Оркестрация цепочек обработки |
Redis | redis:7-alpine | Event bus (Streams), кэш эмбеддингов TTL 7д |
PostgreSQL | postgres:16-alpine | Посты, TrendCluster, IndexingStatus |
Qdrant | qdrant/qdrant:latest | Hybrid search dense 2560d + sparse BM25 |
Neo4j | neo4j:5.15-community | GraphRAG, NER/NEL, community detection |
S3 / Cloud.ru | boto3, path-style | Медиафайлы, vision summaries gzip |
crawl4ai | локальная сборка, 2GB mem | Web-краулинг источников |
SearXNG | searxng/searxng | Self-hosted поиск для missing signals |
Prometheus + Grafana | standard | Метрики пайплайна и дашборды |
Admin UI | FastAPI + Vanilla JS | Управление всем: workspace, источники, темы |
Не используется из telegram-assistant: Supabase стек (kong/postgrest/studio/meta), Caddy, JWT/QR-auth, Mini App, мультитенантность (RLS), Telegram Bot, SaluteSpeech.
Admin UI — центр управления
Все настройки системы живут в Admin UI, не в конфигурационных файлах.
config/ содержит только дефолты при первом запуске — после этого источник правды это БД.
API workspaces: PATCH /api/workspaces/{id} — частичное обновление (Pydantic exclude_unset); relevance_threshold сливается в JSON relevance_weights без удаления весов по категориям (technology, design, …). POST /api/workspaces при upsert делает то же слияние.
Приёмка после смены порога/категорий: логи worker на relevance_category_unknown; GET /api/pipeline/stats; кэш workspace в worker обновляется с шагом до ~90 с.
Кластеры vs category: семантические trend_clusters и поле posts.category — разные оси; кластер не должен жёстко подменяться ненадёжной классификацией поста (см. комментарий в модели TrendCluster).
Разделы
/ Dashboard
├── Статистика по workspace (документов, трендов, сигналов)
├── Pipeline health (очереди, latency, ошибки)
└── Последние TrendCluster по каждому workspace
/workspaces Управление рабочими пространствами
├── Создать / редактировать workspace
├── Категории и веса relevance: {automotive: 0.9, hmi: 0.8}
├── Cross-workspace bridges (какие ws делятся сигналами)
└── Design lenses для интерпретации (automotive, ai, design)
/sources Источники данных
├── Список всех источников с workspace и статусом
├── Добавить источник: [TG | RSS | Habr | Web]
│ ├── Workspace: [disruption | ai_trends | design]
│ ├── Категории: [automotive] [hmi] [design] [tech]
│ ├── Расписание: [15 мин | 1 час | 1 день]
│ ├── Telegram аккаунт: [0 | 1]
│ └── [Сохранить] [Тест-запрос]
└── Управление TG аккаунтами и прокси
/clusters Семантические кластеры, тренды, emerging/missing signals
├── Фильтр: workspace / категория / pipeline / период
├── TrendCluster card: title + insight + opportunity
└── Timeline: динамика кластера по времени
/search Поиск по базе
├── search_frontier
└── search_balanced
/pipeline Управление обработкой
├── Статус IndexingStatus по постам
├── Ручной запуск semantic/signal analysis
└── DLQ: проблемные документыЧто управляется через UI (не через конфиги)
Настройка | Где в UI |
Workspace: категории и веса | /workspaces |
Cross-workspace bridges | /workspaces |
Design lenses per workspace | /workspaces |
Список источников, расписания | /sources |
TG аккаунты, MTProxy / SOCKS5 | /sources |
Релевантность: threshold (0.6) | /workspaces |
Trend detection: окно, параметры | /pipeline |
Missing signals: темы для gap analysis | /signals |
База данных
PostgreSQL
-- Рабочие пространства
CREATE TABLE workspaces (
id TEXT PRIMARY KEY, -- 'disruption' | 'ai_trends' | 'design'
name TEXT NOT NULL,
categories TEXT[],
relevance_weights JSONB, -- {"automotive": 0.9, "hmi": 0.8}
design_lenses TEXT[], -- интерпретационные углы
cross_workspace TEXT[], -- workspace_ids для cross-signal
created_at TIMESTAMPTZ DEFAULT now()
);
-- Источники
CREATE TABLE sources (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
workspace_id TEXT NOT NULL REFERENCES workspaces(id),
type TEXT NOT NULL, -- 'telegram' | 'rss' | 'habr' | 'web'
name TEXT NOT NULL,
url TEXT,
tg_channel TEXT,
tg_account INTEGER DEFAULT 0,
categories TEXT[],
enabled BOOLEAN DEFAULT true,
schedule TEXT DEFAULT '*/30 * * * *',
last_parsed TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT now()
);
-- Документы
CREATE TABLE posts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
workspace_id TEXT NOT NULL REFERENCES workspaces(id),
source_id UUID REFERENCES sources(id),
external_id TEXT,
content TEXT NOT NULL,
url TEXT,
grouped_id BIGINT, -- Telegram album ID
has_media BOOLEAN DEFAULT false,
published_at TIMESTAMPTZ,
ingested_at TIMESTAMPTZ DEFAULT now(),
relevance_score FLOAT,
categories TEXT[],
UNIQUE(source_id, external_id)
);
-- Медиа (content-addressed)
CREATE TABLE media_objects (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
file_sha256 TEXT UNIQUE NOT NULL,
s3_key TEXT NOT NULL, -- media/{sha256[:2]}/{sha256}
mime TEXT,
size_bytes BIGINT,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE post_media_map (
post_id UUID REFERENCES posts(id),
file_sha256 TEXT REFERENCES media_objects(file_sha256),
PRIMARY KEY (post_id, file_sha256)
);
-- Альбомы (из telegram-assistant Phase 1-4)
CREATE TABLE media_groups (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
workspace_id TEXT NOT NULL REFERENCES workspaces(id),
source_id UUID REFERENCES sources(id),
grouped_id BIGINT NOT NULL,
album_kind TEXT, -- 'photo' | 'video' | 'mixed'
items_count INTEGER,
caption_text TEXT,
cover_media_id UUID REFERENCES media_objects(id),
posted_at TIMESTAMPTZ,
meta JSONB DEFAULT '{}'::jsonb, -- vision_summary, labels, OCR, s3_key
UNIQUE(source_id, grouped_id)
);
CREATE TABLE media_group_items (
group_id UUID REFERENCES media_groups(id),
post_id UUID REFERENCES posts(id),
position INTEGER,
media_object_id UUID REFERENCES media_objects(id),
media_kind TEXT,
meta JSONB DEFAULT '{}'::jsonb,
PRIMARY KEY (group_id, position)
);
-- Статус индексирования
CREATE TABLE indexing_status (
post_id UUID PRIMARY KEY REFERENCES posts(id),
embedding_status TEXT DEFAULT 'pending',
graph_status TEXT DEFAULT 'pending',
vision_status TEXT DEFAULT 'pending',
processing_started_at TIMESTAMPTZ,
processing_completed_at TIMESTAMPTZ,
error_message TEXT,
retry_count INTEGER DEFAULT 0
);
-- Тренд-кластеры
CREATE TABLE trend_clusters (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
workspace_id TEXT NOT NULL REFERENCES workspaces(id),
cluster_key TEXT NOT NULL,
pipeline TEXT NOT NULL, -- 'reactive' | 'stable'
title TEXT NOT NULL,
summary TEXT,
-- Слой Insight → Opportunity → Concept
insight TEXT, -- "UI перестает быть экраном → становится пространством"
opportunity TEXT, -- "in-car navigation как spatial layer"
time_horizon TEXT, -- "2-4 года"
keywords JSONB,
burst_score FLOAT,
coherence FLOAT,
novelty FLOAT,
category TEXT,
doc_ids UUID[],
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
UNIQUE(workspace_id, cluster_key)
);
-- Missing signals
CREATE TABLE missing_signals (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
workspace_id TEXT NOT NULL REFERENCES workspaces(id),
topic TEXT NOT NULL,
expected_context TEXT, -- почему тема должна быть
gap_score FLOAT, -- насколько сильно отсутствует
opportunity TEXT, -- что из этого следует
detected_at TIMESTAMPTZ DEFAULT now()
);
-- Обогащение постов
CREATE TABLE post_enrichment (
post_id UUID REFERENCES posts(id),
kind TEXT NOT NULL, -- 'tags'|'vision'|'ocr'|'concepts'
data JSONB,
enrichment_provider TEXT,
updated_at TIMESTAMPTZ DEFAULT now(),
PRIMARY KEY (post_id, kind)
);Qdrant — коллекции
# Основная: hybrid search per workspace
# dense (EmbeddingsGigaR, 2560d) + sparse (BM25)
# Все запросы фильтруются по workspace_id
Collection("frontier_docs",
vectors={
"dense": {"size": 2560, "distance": "Cosine"},
"sparse": {} # BM25
},
payload_schema={
"workspace_id": "keyword", # фильтр по умолчанию
"source_type": "keyword",
"category": "keyword",
"published_at": "datetime",
"relevance_score": "float",
"concepts": "keyword[]",
"tags": "keyword[]",
"valence": "keyword",
"signal_type": "keyword",
"source_region": "keyword",
"source_score": "float"
}
)
# Тренд-кластеры
Collection("trend_clusters",
# PostgreSQL is source of truth; Qdrant is a searchable secondary index.
# Dense vector is the centroid of member post vectors.
vectors={"dense": {"size": 2560, "distance": "Cosine"}},
payload_schema={
"workspace_id": "keyword",
"pipeline": "keyword",
"signal_stage": "keyword",
"keywords": "keyword[]",
"burst_score": "float",
"signal_score": "float",
"detected_at": "datetime",
"doc_count": "integer",
"source_count": "integer"
}
)Neo4j — граф концептов
// Узлы
(:Workspace {id, name, categories[]})
(:Concept {name, category, first_seen, mentions})
(:Document {id, url, published_at, source_type, has_media})
(:Source {name, type, workspace_id})
(:TrendCluster {id, title, insight, opportunity, burst_score})
(:Album {grouped_id, album_kind, items_count})
// Связи
(:Workspace) -[:CONTAINS]-> (:Concept)
(:Document) -[:MENTIONS {weight}]->(:Concept)
(:Concept) -[:RELATED_TO {strength, co_occ}]->(:Concept)
(:Concept) -[:EVOLVED_FROM {year}]->(:Concept)
(:Document) -[:FROM_SOURCE]-> (:Source)
(:TrendCluster)-[:CONTAINS {rank}]-> (:Concept)
(:Album) -[:CONTAINS {position}]->(:Document)
// Cross-workspace связи
(:Concept) -[:BRIDGES {strength}]->(:Concept)MCP Tools
Текущая реализация — REST tools в mcp/server.py + SSE gateway в mcp/mcp_gateway.py.
Общие правила:
почти все аналитические инструменты принимают
workspace;поиск использует Qdrant hybrid dense + sparse и
workspace_idfilter;synthesize=trueвключает GigaChat-синтез там, где он поддержан;Admin UI тоже ходит в эти tools через внутренний
mcp:8100.
Текущие tools:
Tool | Назначение |
| Hybrid search по |
| Growth/counter-signal/RU verification/competitor-aware search |
| Semantic search по Qdrant |
| Поиск по Vision labels/OCR/scenes в |
| Neo4j concept graph / concept-centered subgraph |
| Multi-workspace brief из overview, clusters, weak/emerging, missing signals |
| Поставить URL в |
| Workspace registry |
| Source score, health, last run, quality tier |
| Статусы ingest/enrichment и recent posts |
| Сводка workspace: posts, sources, clusters |
| Semantic/trend/emerging clusters |
| Emerging signals по стадиям |
| SearXNG gap-analysis findings |
| Полная карточка semantic/trend/emerging/missing |
| Missing-signal details + external evidence |
| Source runs and recent posts |
| Evidence posts for a cluster |
| Time-series points for semantic/trend/emerging entities |
Processing Pipeline
As-built (текущий код)
Цепочка фактически такая (см. worker/main.py, ingest, crawl4ai):
ingest (Telegram / др.)
→ stream:posts:parsed
├→ EnrichmentTask: пост в PostgreSQL, релевантность, концепты, теги,
│ эмбеддинг по тексту поста → Qdrant, концепты → Neo4j,
│ post_enrichments (concepts, tags), stream:posts:enriched (observer stream),
│ при наличии linked_urls → stream:posts:crawl
├→ VisionTask (параллельно): GigaChat Vision → post_enrichments (vision) → stream:posts:reindex
└→ ReindexTask: stream:posts:reindex → enriched text embedding → Qdrant patch + Neo4j concepts
crawl4ai сервис
→ stream:posts:crawl → crawl → post_enrichments (kind='crawl') → stream:posts:reindexurlв событии — permalink поста в Telegram (валидация источника).linked_urls— внешние HTTP(S) ссылки из текста и Telethon entities (безt.me/ Twitter/X), до 10 шт.; только они уходят в crawl4ai.Crawl/Vision reindex: после сохранения
post_enrichments(kind='crawl'|'vision')сервисы публикуютstream:posts:reindex;ReindexTaskв worker обновляет canonical Qdrant point enriched-текстом и дописывает crawl/vision concepts в Neo4j.Ни
AlbumAssemblerTask, ни отдельный legacyGraphTaskнаstream:posts:enrichedв этом репозитории не подключены; альбомы на стороне ingest сворачиваются в одинPostParsedEventсgrouped_idи несколькимиmedia_urls, а граф обновляется inline + черезReindexTask.
Паттерны полного альбомного пайплайна можно смотреть в telegram-assistant и в локальном архиве docs/old_docs ilyasni-telegram-assistant.git/ — переносить только совместимое со стеком Frontier Intelligence (workspace_id, stream:posts:*, без Supabase/Caddy/Bot из legacy).
Redis Streams (сводка)
Stream | Consumer |
|
|
|
|
|
|
|
|
| observer stream для downstream-интеграций; отдельного worker-task нет |
EnrichmentTask (логика)
Релевантность (GigaChat) → при прохождении порога: концепты, эмбеддинг текста поста, upsert в Qdrant, концепты в Neo4j, post_enrichments; при linked_urls — сообщение в stream:posts:crawl. Нерелевантные посты помечаются dropped, точка в Qdrant удаляется при наличии.
Vision (текущий)
ingest/sources/telegram_source.py загружает медиа в S3 → stream:posts:vision → worker/tasks/vision_task.py: скачивание из S3 → GigaChat Vision (labels, scene, ocr_text в JSON) → при заданном PADDLEOCR_URL дополнительно PaddleOCR POST /v1/ocr/upload (тот же контракт, что в telegram-assistant services/paddleocr) → в enrichment попадают paddle_ocr_text и объединённый ocr_text → post_enrichments (kind='vision'), indexing_status.vision_status. Сервис: docker compose --profile paddleocr up -d paddleocr, в .env у worker: PADDLEOCR_URL=http://paddleocr:8008.
Проверка e2e после деплоя
Деплой: правки в рабочей копии → Sync → Server (
scripts/sync-push.ps1или Task); на сервере при смене Dockerfile/зависимостей —docker compose build, иначеdocker compose restartдляworker,ingest,crawl4ai,admin. Новая схема БД: с рабочей машины можно одним шагом.\scripts\push-and-remote-migrate.ps1(rsync через WSL + SSH +scripts/server-apply-sql-migrations.shв Postgres-контейнере и restart сервисов). Либо только на сервере:cd /opt/frontier-intelligence && bash scripts/server-apply-sql-migrations.sh. Альтернатива с хоста:bash scripts/apply-postgres-migrations.shпри доступномpsqlиDATABASE_URL. Существующая БД не обновляется от одногоinit.sql.PostgreSQL:
SELECT post_id, kind FROM post_enrichments WHERE kind IN ('vision','crawl') ORDER BY updated_at DESC LIMIT 20;Логи:
worker— строкиEnriched,Reindex done;crawl4ai—Crawl enrichment saved; worker vision —Vision done.Qdrant: точки появляются для релевантных постов (
indexing_status.embedding_status = 'done'), не для dropped. Crawl/Vision enrichment патчит существующую точку черезstream:posts:reindex; existing enriched rows can be queued withpython scripts/enqueue_reindex_enriched_posts.py --kind crawl --kind vision --limit 1000. Stable trend clusters mirror totrend_clustersafter cluster/signal analysis; existing rows can be backfilled withpython scripts/sync_trend_clusters_to_qdrant.py.Redis: при недоступности
docker exec, при открытом порте с хоста —redis-cli(длина стримов, необязательно).Admin API:
/pipeline/stats, повторная постановкаPOST /pipeline/reprocess/{post_id}(передаётmedia_urlsиlinked_urls, извлечённые изcontent).
Trend Detection
Reactive (cron 30 мин):
Посты за последние N часов
burst_score = (current_freq - baseline) / baseline
GigaChat: title + insight + opportunity для топ-кластеров
→ TrendCluster {pipeline: "reactive", burst_score: 3.7}
Stable (cron сутки):
Embeddings из Qdrant за 7-30 дней
HDBSCAN кластеризация
GigaChat: title + insight + opportunity + time_horizon
coherence = avg cosine similarity внутри кластера
novelty = 1 - overlap с предыдущим периодом
GraphRAG: связать кластеры с существующим графом
→ TrendCluster {pipeline: "stable", coherence: 0.91, novelty: 0.88}
Missing Signals (cron сутки):
SearXNG: поиск по теме workspace → "нормальный" корпус
Сравнение с frontier_docs по workspace
Gap: темы с высоким expected, низким actual presence
GigaChat: gap → opportunity формулировка
→ missing_signals tableTelegram: обход блокировок
# Два слоя, автоматическая ротация при сбое
PROXY_CONFIGS = [
# MTProxy — встроен в протокол Telegram, сложнее заблокировать
{"type": ProxyType.MTPROTO,
"host": MTPROXY_HOST, "port": 443, "secret": MTPROXY_SECRET},
# SOCKS5 — WireGuard LXC на Proxmox (fallback)
{"type": ProxyType.SOCKS5,
"host": "10.0.0.1", "port": 1080},
]
# 2 аккаунта: ротация при FloodWaitError / SessionRevokedError
# iter_messages() — эффективнее get_messages() для Telegram API
# Redis negative cache: album_seen:{channel_id}:{grouped_id}, TTL 6ч
# Управление через Admin UI /sources:
# - добавить/сменить MTProxy (host, port, secret)
# - добавить/сменить SOCKS5
# - назначить источник на аккаунт [0|1]
# - статус аккаунтов, последняя активностьСтруктура репозитория
frontier-intelligence/
│
├── docker-compose.yml
├── docker-compose.host-fixes.yml
├── .env.example
├── .env.balanced.example
├── .cursor/rules/
├── Makefile
├── pyproject.toml
│
├── ingest/
│ ├── Dockerfile
│ ├── main.py # APScheduler, конфиг из БД (не из файлов)
│ ├── account_rotator.py # MTProxy/SOCKS5/xray, 2 аккаунта
│ ├── scheduler.py # расписания из sources table
│ ├── sources/
│ │ ├── base.py
│ │ ├── telegram_source.py # Telethon, iter_messages(), album-aware
│ │ ├── rss_source.py
│ │ ├── web_source.py
│ │ ├── api_source.py
│ │ └── email_source.py
│
├── worker/
│ ├── Dockerfile
│ ├── main.py # supervisor enrichment + vision + reindex
│ ├── tasks/
│ │ ├── enrichment_task.py # relevance/concepts/valence/embed/Qdrant/Neo4j
│ │ ├── reindex_task.py # crawl/vision enrichment → Qdrant patch + Neo4j
│ │ └── vision_task.py # S3 media → GigaChat Vision + PaddleOCR
│ ├── chains/
│ │ ├── relevance_chain.py
│ │ ├── concept_chain.py
│ │ ├── relevance_concepts_chain.py
│ │ └── valence_chain.py
│ ├── services/
│ │ ├── semantic_clustering.py
│ │ ├── missing_signals.py
│ │ └── searxng_client.py
│ ├── integrations/
│ │ ├── qdrant_client.py # hybrid search, workspace filter
│ │ └── neo4j_client.py # concepts graph
│ ├── gigachat_client.py # LangChain GigaChat + EmbeddingsGigaR
│ └── prompts/
│ ├── relevance.txt
│ ├── concepts.txt
│ ├── relevance_concepts.txt
│ └── valence.txt
│
├── mcp/
│ ├── Dockerfile
│ ├── Dockerfile.gateway
│ ├── server.py # REST MCP tools
│ ├── mcp_gateway.py # SSE gateway
│ └── tools/
│ ├── search_frontier.py
│ ├── search_balanced.py
│ ├── search_trend_clusters.py
│ ├── search_by_vision.py
│ ├── graph.py
│ ├── frontier_brief.py
│ ├── observability.py
│ └── ingest_url.py
│
├── admin/
│ ├── Dockerfile
│ ├── backend/
│ │ ├── main.py
│ │ ├── scheduler.py
│ │ ├── manual_jobs.py
│ │ ├── services/
│ │ └── routers/
│ │ ├── workspaces.py # CRUD workspace + настройки
│ │ ├── sources.py # CRUD источников + TG аккаунты
│ │ ├── pipeline.py # статус, DLQ, ручной запуск
│ │ ├── clusters.py # semantic/trend/emerging/missing
│ │ └── search.py # поиск через MCP tools
│ └── frontend/
│ └── index.html
│
├── shared/
│ ├── events/
│ │ ├── posts_parsed_v1.py
│ │ ├── posts_vision_v1.py
│ │ ├── albums_parsed_v1.py
│ │ └── album_assembled_v1.py
│ └── models/
│
├── storage/
│ ├── postgres/init.sql
│ ├── postgres/migrations/
│ ├── qdrant/collections.py
│ └── neo4j/constraints.cypher
│
├── config/ # Дефолты при первом запуске
│ ├── workspaces.yml # стартовые workspace
│ ├── sources.yml # стартовые источники
│ └── enrichment_policy.yml
│
├── searxng/
│ ├── settings.example.yml # tracked template
│ └── settings.yml # ignored/server-local secret_key
│
├── prometheus/
│ ├── prometheus.yml
│ ├── alerts.yml
│ └── alertmanager.yml
├── grafana/dashboards/
│ └── frontier-runtime.json
│
└── scripts/
├── sync-push.ps1 / sync-pull.ps1
├── server-build-stack.sh
├── server-deploy-rebuild.sh
├── server-ensure-searxng-secret.sh
├── run_semantic_clustering.py
├── sync_trend_clusters_to_qdrant.py
└── init_storage.pyПеременные окружения
Полная форма — в ../.env.example. В git хранить только example-файлы; реальные .env, Telethon sessions и SearXNG secret_key остаются на сервере.
# PostgreSQL
POSTGRES_DB=frontier
POSTGRES_USER=frontier
POSTGRES_PASSWORD=<server-only-secret>
# GigaChat
GIGACHAT_CREDENTIALS=<server-only-secret>
GIGACHAT_SCOPE=GIGACHAT_API_PERS
GIGACHAT_BASE_URL=https://gigachat.devices.sberbank.ru/api/v1
# False — как в telegram-assistant при MITM; True — прод с доверенным CA в контейнере
GIGACHAT_VERIFY_SSL_CERTS=False
GIGACHAT_EMBEDDINGS_MODEL=EmbeddingsGigaR
EMBED_DIM=2560
GIGACHAT_MODEL=GigaChat-2
GIGACHAT_MODEL_PRO=GigaChat-2-Pro
GIGACHAT_VISION_MODEL=GigaChat-2-Pro
# S3 / Cloud.ru
S3_ENDPOINT_URL=https://s3.cloud.ru
S3_BUCKET_NAME=<server-bucket>
S3_REGION=ru-central-1
S3_ACCESS_KEY_ID=<server-only-secret>
S3_SECRET_ACCESS_KEY=<server-only-secret>
# Telegram аккаунт 0
TG_API_ID_0=<server-only-id>
TG_API_HASH_0=<server-only-secret>
# Telegram аккаунт 1
TG_API_ID_1=
TG_API_HASH_1=
# ── Telethon → Telegram DC (SOCKS5 или MTProxy) ─────────────────────────────
# gpt2giga-proxy (порт 8090) — только HTTP-доступ к GigaChat для worker; в Telethon НЕ подставлять.
# Удобная одна строка: TG_SOCKS5=HOST:PORT:USER:PASS (или TG_PROXY_DSN=…)
# Либо поля: TG_PROXY_HOST / TG_PROXY_PORT / TG_PROXY_USER / TG_PROXY_PASS
# Либо WG_SOCKS_HOST / WG_SOCKS_PORT (+ USER/PASS при необходимости) — см. .env.example
# MTProxy (имеет приоритет над SOCKS5 в env, если заданы host+secret):
MTPROXY_HOST=
MTPROXY_PORT=443
MTPROXY_SECRET=
# Жёстко: не стартовать ingest без прокси в environment (proxy_config только в БД не считается):
# TG_REQUIRE_PROXY=1
# После смены прокси в .env пересоздать контейнер:
# docker compose --profile core --profile ingest up -d --force-recreate ingest
# В логах ingest ожидать «Telegram proxy: SOCKS5 …» или «MTProxy …», а не прямой DC без прокси.
# Neo4j
NEO4J_PASSWORD=<server-only-secret>
# Сервисы
MCP_PORT=8100
ADMIN_PORT=8101
GRAFANA_PASSWORD=<server-only-secret>
# SearXNG
SEARXNG_URL=http://searxng:8080
# searxng/settings.yml не коммитится; secret_key генерируется на сервере.Docker Compose профили
core — postgres, redis, qdrant, neo4j, gpt2giga-proxy
ingest — ingest сервис (TG + RSS + Habr)
worker — LangChain worker (enrichment + vision + trends + signals)
mcp — MCP сервер (8100)
admin — Admin UI (8101)
crawl — crawl4ai (web источники)
searxng — self-hosted поиск (missing signals, стартует вместе с `worker` profile)
monitor — prometheus + grafana
Запуск:
docker compose \
--profile core \
--profile ingest \
--profile worker \
--profile mcp \
--profile admin \
up -dЕсли на хосте docker compose build падает с AppArmor / runc или BuildKit (security.insecure / entitlement), см. docs/server-docker-apparmor.md; быстрый путь — scripts/server-build-ingest-fix.sh (DOCKER_BUILDKIT=0), опционально override docker-compose.build-host-fix.yml.
As-Built Runtime
Фактическая цепочка на сервере:
1. Core infrastructure
postgres + redis + qdrant + neo4j + gpt2giga-proxy
scripts/init_storage.py: Qdrant collections, Neo4j constraints, workspace bootstrap
2. Ingest
telegram_source.py (2 accounts, MTProxy/SOCKS5/xray, iter_messages, album-aware)
rss_source.py / web_source.py / api_source.py / email_source.py
all sources emit PostParsedEvent into stream:posts:parsed
3. Worker enrichment
EnrichmentTask: relevance → concepts → valence → EmbeddingsGigaR
writes PostgreSQL post_enrichments/indexing_status, Qdrant frontier_docs, Neo4j concepts
4. Vision
ingest uploads media to S3 and emits stream:posts:vision
VisionTask: S3 media → GigaChat Vision → optional PaddleOCR → post_enrichments(kind='vision')
ReindexTask patches Qdrant/Neo4j after vision and crawl enrichments
no separate AlbumAssemblerTask in this repository
5. Admin UI and scheduler
CRUD sources/workspaces, pipeline reprocess, source scoring
scheduled/manual semantic clustering and signal analysis
6. Clusters and signals
semantic_clusters, trend_clusters, emerging_signals, missing_signals in PostgreSQL
missing signals use SearXNG through server-local settings.yml
7. MCP
REST tools on 8100, SSE gateway on 8102
search_frontier/search_balanced/search_trend_clusters/search_by_vision
get_concept_graph/get_frontier_brief plus observability and cluster/source tools
8. Observability
Prometheus + Alertmanager + Grafana frontier-runtime dashboardРеференс (telegram-assistant)
Старый проект используется только как справка. Переносить код напрямую нельзя без адаптации под workspace_id, текущие Redis Streams, SQLAlchemy async и отсутствие Supabase/Caddy/JWT/QR-auth.
Что смотреть | Статус в Frontier Intelligence |
Telethon iter_messages, account rotation, proxy handling | Adapted in |
Vision/OCR ideas | Adapted in |
gpt2giga-proxy contour | Kept as local |
crawl4ai pattern | Kept as |
Album assembler phases | Reference only; current ingest collapses albums into post/media events |
Grafana album dashboard | Reference only; current dashboard is |
EmbeddingsGigaR dim=2560 | Current env is |
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ilyasni/frontier-intelligence'
If you have feedback or need assistance with the MCP directory API, please join our Discord server