Roteador de chamadas LLM por model/tier, multi-provider, com retorno consistente.
Project description
aigen
Roteador de chamadas LLM por model/tier, multi-provider, com call/return consistente.
Você escolhe um tier (basic/advanced/pro) ou uma key model:provider;
o pacote resolve o provider, instancia, chama e devolve sempre um dataclass
padronizado. Trocar de modelo ou provider = editar config, não código.
Instalação
SDKs de provider são extras opcionais — instale só os que usar:
pip install "aigen[openai]" # OpenAI, Groq, z.ai, Kimi, Alibaba, DeepSeek (openai-compat)
pip install "aigen[gemini]" # Google Gemini
pip install "aigen[claude]" # Anthropic Claude
pip install "aigen[cerebras]" # Cerebras
pip install "aigen[all]" # tudo
# Desenvolvimento (editável):
pip install -e "/Users/ssjunior/Dev/llm-router[all]"
Providers que falam HTTP puro (Kie, Minimax, imagens da Alibaba/z.ai, STT da Groq)
funcionam só com o core (httpx, requests).
Uso
Passe tier ('basic'/'advanced'/'pro') ou model ('model:provider'). tier
default é 'basic'; model= sobrepõe. prompt é o 1º posicional; o resto é keyword.
(stt/tts não têm tabela de tier — exigem model=.)
import aigen
# por tier (resolve via constants/tiers.py)
r = aigen.generate_text('Resuma o texto X', tier='basic')
print(r.content) # JSON parseado (dict/list) ou str
print(r.total_tokens)
# por key explícita
r = aigen.generate_text('Resuma X', model='gemini-2.5-flash:gemini', system_instruction='...')
# timeout por chamada (texto) — default LLM_REQUEST_TIMEOUT (900s)
r = aigen.generate_text('Resuma X', tier='basic', timeout=60)
Outras mídias
img = aigen.generate_image('um gato astronauta', tier='pro', files=[...])
video = aigen.generate_video('clipe contínuo de...', tier='basic', task='text_to_video')
music = aigen.generate_music('lo-fi chill', tier='pro', instrumental=True)
text = aigen.transcribe(audio_url, model='whisper-large-v3:groq') # stt/tts exigem model=
Entry genérico (fila/worker)
Recebe o payload e o mode e despacha — mesma engine, mesmo tratamento de erro.
payload é o 1º posicional; mode é keyword com default 'text':
r = aigen.generate(prompt) # mode='text'
r = aigen.generate(prompt, mode='video', tier='basic', task='image_to_video')
r = aigen.generate(audio_url, mode='stt', model='whisper-large-v3:groq')
mode: text · image · video · music · stt · tts.
task (só vídeo): text_to_video · image_to_video.
Contrato de retorno (uniforme)
Sucesso → retorna o dataclass do tipo. Falha → levanta exception tipada. Igual para todas as mídias.
| Mídia | Função | Retorno (sucesso) |
|---|---|---|
| Texto | generate_text |
TextResponse |
| Imagem | generate_image |
ProviderResponse |
| Vídeo | generate_video |
VideoResponse |
| Música | generate_music |
TTMResponse |
| STT | transcribe |
STTResponse |
| TTS | synthesize |
TTSResponse |
Taxonomia de erro
ProviderError # base — terminal
├─ ProviderBlocked # conteúdo barrado — .category: 'safety'|'copyright'|'other'
└─ ProviderRetryable # transitório (pode retry)
├─ ProviderRateLimit # 429
└─ ProviderTimeout # timeout / rede
Trata-se igual para qualquer mídia, num lugar só:
try:
r = aigen.generate_video(prompt, tier='basic')
use(r.videos)
except aigen.ProviderBlocked as e:
print('barrado:', e.category, e) # copyright / safety
except aigen.ProviderRetryable as e:
retry() # rede / ratelimit / timeout
except aigen.ProviderError as e:
fail(e) # terminal genérico
Cada exception carrega .provider, .model, .status_code, .response_time, .raw_error.
Configuração
Duas coisas distintas:
- Catálogo técnico (
aigen/constants/{text,image,audio,video}.py) — fatos sobre providers:api_key_env, capabilities, créditos. Muda raro. - Roteamento por tier (
aigen/tiers.py) — a decisão de qual modelo cada tier usa. Muda toda hora e difere por app.
O roteamento é app-owned: aigen/tiers.py traz só os defaults (pra funcionar
out-of-box); o app é o dono e sobrescreve no boot. Não edite o pacote instalado.
import aigen
# entry único — merge sobre os defaults (tiers não passados continuam valendo)
aigen.configure(
text={'basic': 'gemini-2.5-flash:gemini', 'pro': 'claude-sonnet-4-6:claude'},
image={'pro': 'gpt-image-2:openai'},
video={'basic': {'text_to_video': 'bytedance/seedance-1.5-pro:kie'}},
)
# replace=True → o app vira dono total daquela mídia (zera antes)
aigen.configure(text={'basic': 'glm-5.2:zai'}, replace=True)
# ajustes pontuais
aigen.set_tier('text', 'pro', 'gpt-5.4:openai')
# registrar provider/modelo novo no catálogo
aigen.register_provider('text', 'meu_provider', 'MEU_API_KEY', models={
'meu-modelo': {'tier': 'pro', 'base_credits': 8},
})
aigen.register_model('text', 'openai', 'gpt-5.4', {'tier': 'pro', 'base_credits': 8})
Lugar claro e visível: um arquivo de config no seu app (ex.
settings/ai_tiers.py) chamandoaigen.configure(...)no boot — versionado junto do app, perto do resto da config dele.
API keys
Cada provider lê a key de uma variável de ambiente (campo api_key_env no catálogo).
Defaults: GOOGLE_API_KEY, OPENAI_API_KEY, CLAUDE_API_KEY, GROQ_API_KEY,
CEREBRAS_API_KEY, ZAI_API_KEY, MOONSHOT_AI_API_KEY, DASHSCOPE_API_KEY,
DEEPSEEK_API_KEY, MINIMAX_API_KEY, KIE_API_KEY.
Logs
Cada chamada emite no início (antes de bloquear) e no fim. Útil pra não ficar no escuro durante esperas longas:
generate START | mode=text model=glm-5.2:zai timeout=900
Z.AI text | model=glm-5.2 in=812 out=145 reasoning=0 total=957 time=3.41s
O pacote só usa logging.getLogger(__name__) — não configura handler. Pra ver
na execução, o app habilita logging (uma vez, no boot):
import logging
logging.basicConfig(level=logging.INFO) # console (stderr), ao vivo
# logging.basicConfig(level=logging.INFO, filename='aigen.log') # só arquivo
Sem isso, INFO vai pro vazio. As stats de fim podem ser desligadas com
LOG_PROVIDER_STATS=0; o log START fica.
Providers de texto
gemini · openai · claude (API e CLI) · codex_cli · groq · cerebras · deepseek · zai · kimi · minimax · alibaba · kie
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ai_generator-0.1.0.tar.gz.
File metadata
- Download URL: ai_generator-0.1.0.tar.gz
- Upload date:
- Size: 39.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b80cdd1d1b2461d0b9d7ddf1136a254f9b2a21c49693ec0115ef327adf265e7
|
|
| MD5 |
733c8ec8ec0adf74c724e71e487272b9
|
|
| BLAKE2b-256 |
e7de5e7ae8d134d87399c2cb85d77a44127fb147796f79c5c4b73b2bd45c89f1
|
File details
Details for the file ai_generator-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ai_generator-0.1.0-py3-none-any.whl
- Upload date:
- Size: 58.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b698bdbec3dd974d03b9e2ded7e8ad7268c80d5d9f7116c51853ebfc3bcea34d
|
|
| MD5 |
325e696d4f8e0b6fab17c9b305ed9d3a
|
|
| BLAKE2b-256 |
0aa3209ed21da9218ef0037446d9c553b353ce0515bfb5b89e33148afc61bd50
|