Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ WEB_HOST=0.0.0.0

# INTERNAL port of the web server inside the container (default: 9090).
# It is the same in both synchronizers; what differs is the port published on the
# host (9091 for 9RTKSync, 9092 for OminiRTKSync).
# host (9091 for 9RTKSync, 9092 for OmniRTKSync).
WEB_PORT=9090

# ------------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ side. The same goes for the gateways: each one has its own.
| OmniRoute | `20128` | `8082` |
| LiteLLM | `4000` | `8083` |
| 9RTKSync (dashboard) | `9090` | `9091` |
| OminiRTkSync (dashboard) | `9090` | `9092` |
| OmniRTkSync (dashboard) | `9090` | `9092` |
| LiteLlmRTKSync (dashboard) | `9090` | `9093` |

The article stack (`claudegravity`) keeps **`20128`**, the default 9Router port.
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ services:
- 9rtksync-net
restart: unless-stopped
ports:
# Porta interna 9090 (igual no OminiRTKSync); publicada em 9091 no host.
# Porta interna 9090 (igual no OmniRTKSync); publicada em 9091 no host.
# O bind em 127.0.0.1 mantem o painel e o SQLite fora da internet.
- "127.0.0.1:9091:9090"
volumes:
Expand Down
2 changes: 1 addition & 1 deletion docs/wiki/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ out and produce `BrokenPipeError` in the logs.
| :--- | :--- | :--- |
| `ENABLE_WEB_DASHBOARD` | `1` | `0` runs the synchronizer headless, with no HTTP server at all. |
| `WEB_HOST` | `0.0.0.0` | Listen interface **inside** the container. Keep the published port bound to `127.0.0.1` on the host. |
| `WEB_PORT` | `9090` | Internal port. Identical in both synchronizers; the published host port is what differs (`9091` here, `9092` for OminiRTKSync). |
| `WEB_PORT` | `9090` | Internal port. Identical in both synchronizers; the published host port is what differs (`9091` here, `9092` for OmniRTKSync). |

---

Expand Down
4 changes: 2 additions & 2 deletions docs/wiki/Egress-And-Multi-Session.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ the only component that can actually apply it to a request.

## The sibling gateway, for comparison

[OminiRTkSync](https://github.com/pathbit/OminiRTkSync) documents the same idea
[OmniRTkSync](https://github.com/pathbit/OmniRTkSync) documents the same idea
for OmniRoute, which stores it differently: a `proxy_registry` of endpoints,
a `proxy_assignments` table binding them by `scope` (`global`, `provider`,
`account`) and a `proxy_scope_rotation` row per scope. There, a single proxy at
Expand Down Expand Up @@ -248,7 +248,7 @@ requisição.

## O gateway irmão, para comparação

O [OminiRTkSync](https://github.com/pathbit/OminiRTkSync) documenta a mesma
O [OmniRTkSync](https://github.com/pathbit/OmniRTkSync) documenta a mesma
ideia para o OmniRoute, que a guarda de outro jeito: um `proxy_registry` de
endereços, uma tabela `proxy_assignments` que os vincula por `scope` (`global`,
`provider`, `account`) e uma linha de `proxy_scope_rotation` por escopo. Lá, um
Expand Down
4 changes: 2 additions & 2 deletions docs/wiki/Home.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ queries the SQLite database.
## The sibling project

If you run [OmniRoute](https://github.com/diegosouzapw/OmniRoute) instead of 9Router, use
[OminiRTKSync](https://github.com/pathbit/OminiRTkSync), which targets that gateway's relational
[OmniRTKSync](https://github.com/pathbit/OmniRTkSync), which targets that gateway's relational
schema. The two projects share the same dashboard, logging, authentication and configuration
contract; only the database layer and the provider set differ.

Both synchronizers listen on **port 9090 inside their container**. The published host ports
differ so they can run side by side: `9091` for 9RTKSync, `9092` for OminiRTKSync.
differ so they can run side by side: `9091` for 9RTKSync, `9092` for OmniRTKSync.

---

Expand Down
4 changes: 2 additions & 2 deletions docs/wiki/Installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ services:
- 9rtksync-net
restart: unless-stopped
ports:
# Internal port 9090 (same in OminiRTKSync); published on 9091.
# Internal port 9090 (same in OmniRTKSync); published on 9091.
# The 127.0.0.1 bind keeps the panel and the SQLite file off the internet.
- "127.0.0.1:9091:9090"
volumes:
Expand Down Expand Up @@ -197,7 +197,7 @@ Same for the gateways.
| OmniRoute | `20128` | `8082` |
| LiteLLM | `4000` | `8083` |
| 9RTKSync panel | `9090` | `9091` |
| OminiRTkSync panel | `9090` | `9092` |
| OmniRTkSync panel | `9090` | `9092` |
| LiteLlmRTKSync panel | `9090` | `9093` |

The article stack (`claudegravity`) keeps **`20128`**, 9Router's default port.
Expand Down
4 changes: 2 additions & 2 deletions docs/wiki/Licensing-And-Capacity.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ formula, but only one of them is solved by money.
| How it grows | buy an account, with a new holder | move up a tier, redistribute budget |
| Saturation signal | `rateLimitedUntil`, `modelLock_*` in SQLite | 429 plus the proxy's own spend log |

The sibling [OminiRTkSync](https://github.com/pathbit/OminiRTkSync) sizes exactly
The sibling [OmniRTkSync](https://github.com/pathbit/OmniRTkSync) sizes exactly
like this column — same shape, same `[A MEDIR]`, different storage format for
the expiry. The LiteLLM-facing sibling is the one where the question changes
shape entirely: there the ceiling is declared at **three** levels and the rule is
Expand Down Expand Up @@ -754,7 +754,7 @@ chega a existir daquele lado: o que a API publica é teto **por minuto**
(RPM / ITPM / OTPM por tier), não capacidade de janela
`[FONTE: https://platform.claude.com/docs/en/api/rate-limits — lido em 12/09/2026]`.
Não carregue número de uma coluna para a outra. O irmão
[OminiRTkSync](https://github.com/pathbit/OminiRTkSync) dimensiona igual a esta
[OmniRTkSync](https://github.com/pathbit/OmniRTkSync) dimensiona igual a esta
coluna: mesma forma, mesmo `[A MEDIR]`, formato de expiração diferente.

## Uma restrição que não é de capacidade
Expand Down
2 changes: 1 addition & 1 deletion docs/wiki/Troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ while `LOG_TO_STDOUT=1`.
## Both synchronizers fight over the same port

They listen on **9090 inside their own container** by design. Only the published host port
differs: `9091` for 9RTKSync, `9092` for OminiRTKSync. If you changed `WEB_PORT`, change it in
differs: `9091` for 9RTKSync, `9092` for OmniRTKSync. If you changed `WEB_PORT`, change it in
one container only — there is no reason for the internal ports to differ.

---
Expand Down
2 changes: 1 addition & 1 deletion docs/wiki/Upstream-Fixes.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ both call sites through it.

## What we fixed on our side

[OminiRTKSync](https://github.com/pathbit/OminiRTkSync) was itself writing `expires_at` as a
[OmniRTKSync](https://github.com/pathbit/OmniRTkSync) was itself writing `expires_at` as a
numeric epoch in text (`str(expires_at_ms)`) and `test_status = 'ok'` — a value OmniRoute does not
recognise as healthy. Both are fixed; it now writes ISO-8601 and `'active'`, the gateway's native
formats.
Expand Down
2 changes: 1 addition & 1 deletion src/nine_rtksync/identidade.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Tudo o que diferencia este painel dos irmãos, e nada além disso.

Os três sincronizadores -- 9RTKSync, OminiRTkSync e LiteLlmRTKSync -- são a
Os três sincronizadores -- 9RTKSync, OmniRTkSync e LiteLlmRTKSync -- são a
mesma aplicação. O que muda entre eles é cor, nome, logo, identidade visual e
com quem cada um conversa. Este arquivo é a fronteira: depois dele, nenhum outro
módulo do pacote escreve uma cor em hexadecimal, o nome do produto, o nome do
Expand Down
2 changes: 1 addition & 1 deletion tests/test_cartoes_do_painel.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Os seis cartões existem, sempre, e na mesma ordem dos painéis irmãos.

A regra do dono é uma só: "as telas têm cards diferentes entre LiteLlmRTKSync,
OminiRTkSync e etc, tem que ter todos os cards iguais". O que pode mudar é o
OmniRTkSync e etc, tem que ter todos os cards iguais". O que pode mudar é o
CONTEÚDO; a existência e a ordem, não.

Isto já quebrou uma vez em silêncio: este painel listava conexões e combos e não
Expand Down
2 changes: 1 addition & 1 deletion tests/test_documentacao_bate_com_codigo.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

- a página de saída de rede do 9RTKSync descrevia o gateway do irmão, com
campos que não existem aqui;
- a wiki do OminiRTkSync anunciava uma resposta de `/healthz` que o servidor
- a wiki do OmniRTkSync anunciava uma resposta de `/healthz` que o servidor
nunca devolveu;
- o README do LiteLlmRTKSync citava uma rota `POST /api/sync` inexistente.
"""
Expand Down
4 changes: 2 additions & 2 deletions tests/test_identidade_isolada.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@

PROIBIDOS = [
(re.compile(r"#[0-9a-fA-F]{6}\b"), "cor fora de identidade.py"),
(re.compile(r"9RTKSync|OminiRTKSync|OminiRTkSync|LiteLlmRTKSync"), "nome de produto literal"),
(re.compile(r"9RTKSync|OmniRTKSync|OmniRTkSync|LiteLlmRTKSync"), "nome de produto literal"),
(re.compile(r"9Router|OmniRoute|LiteLLM"), "nome de gateway literal"),
(re.compile(r"9rtk-|ominirtk-|litellmrtk-"), "prefixo de container literal"),
(re.compile(r"9rtk-|omnirtk-|litellmrtk-"), "prefixo de container literal"),
Comment on lines +46 to +48

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject obsolete spellings in the identity guard

Replacing the old alternatives removes the regression protection for the exact typo this change fixes: if a shared package module later contains OminiRTkSync, OminiRTKSync, or an ominirtk- container prefix, test_nenhum_modulo_escreve_identidade_a_mao now passes. Keep the obsolete forms as additional forbidden aliases so the typo cannot silently return outside identidade.py.

Useful? React with 👍 / 👎.

(
re.compile(r"bi-lightning-charge-fill|bi-signpost-split-fill|bi-speedometer2"),
"ícone do produto literal",
Expand Down
10 changes: 5 additions & 5 deletions tests/test_irmaos_identicos.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Os módulos comuns são o MESMO texto nos três irmãos, byte a byte.

9RTKSync, OminiRTkSync e LiteLlmRTKSync são a mesma aplicação. O que muda entre
9RTKSync, OmniRTkSync e LiteLlmRTKSync são a mesma aplicação. O que muda entre
eles é cor, nome, logo, identidade visual e a quem cada um se conecta — e isso
mora inteiro em `identidade.py` (o que é identidade) e em `gateway.py` (o que é
domínio do gateway). Todo o resto tem de ser o mesmo arquivo, ou "são quase
Expand Down Expand Up @@ -40,7 +40,7 @@
RAIZ = pathlib.Path(__file__).resolve().parent.parent

# Nome do diretório de cada irmão ao lado deste repositório.
IRMAOS = ("9RTKSync", "OminiRTkSync", "LiteLlmRTKSync")
IRMAOS = ("9RTKSync", "OmniRTkSync", "LiteLlmRTKSync")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Recognize sibling checkouts under the former directory name

When an existing multi-repository workspace pulls this rename, Git updates the checkout contents but does not rename its OminiRTkSync directory. This new constant therefore makes test_irmaos_identicos treat that sibling as absent and skip every comparison; the analogous loop in test_rotas_simetricas.py silently continues as well. Discover the sibling under both directory names, or explicitly migrate/fail on the former name, so existing workspaces do not lose the cross-project parity checks.

Useful? React with 👍 / 👎.


# Módulos que têm de ser o mesmo texto nos três, relativos a `src/<pacote>/`.
IDENTICOS = (
Expand Down Expand Up @@ -99,9 +99,9 @@

# O que cada produto troca de propósito, e que não conta como divergência.
IDENTIDADE = (
("nine_rtksync", "omini_rtksync", "litellm_rtksync"),
("9RTKSync", "OminiRTKSync", "OminiRTkSync", "LiteLlmRTKSync"),
("9rtk", "ominirtk", "litellmrtk"),
("nine_rtksync", "omni_rtksync", "litellm_rtksync"),
("9RTKSync", "OmniRTKSync", "OmniRTkSync", "LiteLlmRTKSync"),
("9rtk", "omnirtk", "litellmrtk"),
("9Router", "OmniRoute", "LiteLLM"),
)

Expand Down
2 changes: 1 addition & 1 deletion tests/test_rotas_simetricas.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import unittest

RAIZ = pathlib.Path(__file__).resolve().parent.parent
IRMAOS = ("9RTKSync", "OminiRTkSync", "LiteLlmRTKSync")
IRMAOS = ("9RTKSync", "OmniRTkSync", "LiteLlmRTKSync")

# Rotas que o produto TEM de servir, independentemente do gateway por trás.
# Entram aqui as que algum pedido explícito criou -- assim o teste também
Expand Down
2 changes: 1 addition & 1 deletion tools/valida_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
VARIAVEIS_DE_TERCEIROS = {
# litellm/proxy/hooks/__init__.py:31, LiteLLM 1.102.0
"LEGACY_MULTI_INSTANCE_RATE_LIMITING",
# Flag dos composes do 9RTKSync e do OminiRTkSync. A pagina de encadeamento
# Flag dos composes do 9RTKSync e do OmniRTkSync. A pagina de encadeamento
# precisa nomea-la porque ela e uma armadilha: quem le `REQUIRE_API_KEY=false`
# conclui que nao precisa de chave, enquanto o 9Router autoriza por peer e
# responde 401 a qualquer vizinho de rede. O nome nunca vai existir no fonte
Expand Down
Loading