aigen
Roteador multi-provider para chamadas de IA com retorno consistente.
O caller escolhe explicitamente a key model:provider; o pacote instancia o
provider correspondente, executa a chamada e devolve um dataclass padronizado
com resposta, metadados técnicos e tokens reportados pelo provider.
Decisões de produto como tiers, créditos, planos, cobrança, limites comerciais
ou cálculo de custo não pertencem ao aigen. Quem chama o pacote pode usar
total_tokens, input_tokens, output_tokens e reasoning_tokens para fazer
qualquer cálculo externo.
Instalação
SDKs de provider são extras opcionais. Instale só os que usar:
pip install "ai-generator[openai]" # OpenAI, Groq, z.ai, Kimi, Alibaba, DeepSeek
pip install "ai-generator[gemini]" # Google Gemini
pip install "ai-generator[claude]" # Anthropic Claude
pip install "ai-generator[cerebras]" # Cerebras
pip install "ai-generator[all]" # tudo
# Desenvolvimento:
pip install -e ".[all]"
Providers HTTP puros funcionam só com o core (httpx, requests).
Uso
Sempre passe model='model:provider'.
import aigen
r = aigen.generate_text(
'Resuma o texto X',
model='gemini-3.8-flash:gemini',
)
print(r.content)
print(r.total_tokens)
Outras mídias usam o mesmo padrão:
img = aigen.generate_image('um gato astronauta', model='gpt-image-2:openai')
video = aigen.generate_video('clipe contínuo de...', model='bytedance/seedance-1.5-pro:kie')
music = aigen.generate_music('lo-fi chill', model='music-3.0:minimax')
text = aigen.transcribe(audio_url, model='whisper-large-v3:groq')
audio = aigen.synthesize('Olá', model='elevenlabs/text-to-speech-turbo-2-5:kie')
vecs = aigen.generate_embeddings(['texto a'], model='text-embedding-3-large:openai')
ranked = aigen.rerank('query', ['doc a', 'doc b'], model='cohere/rerank-4-pro:openrouter')
Imagem pelo Codex CLI
O comando aigen-image usa o login local do Codex e invoca o skill $imagegen.
Não requer OPENAI_API_KEY:
aigen-image "Um gato astronauta em Marte"
aigen-image --output assets/hero.png "Banner horizontal futurista para uma landing page"
cat prompt.txt | aigen-image --output assets/hero.png
O padrão é salvar em ./image.png. O modelo disponível neste provider é
gpt-image-2:codex_cli.
Vídeo com first frame ou imagens de referência na fal.ai aceita bytes, caminho
local, URL ou Data URI. Arquivos locais e bytes são enviados como Data URI Base64:
from pathlib import Path
first_frame = aigen.generate_video(
'A personagem olha para a câmera',
model='google/gemini-omni-flash/image-to-video:fal',
first_frame_image=Path('personagem.png').read_bytes(),
)
references = aigen.generate_video(
'Image 1 é a personagem; Image 2 define o figurino',
model='minimax/h3-max/reference-to-video:fal',
reference_images=[
Path('personagem.png').read_bytes(),
Path('figurino.jpg').read_bytes(),
],
)
seedance_text = aigen.generate_video(
'Plano cinematográfico contínuo com áudio ambiente',
model='bytedance/seedance-2.5/text-to-video:fal',
)
omni_text = aigen.generate_video(
'Farol ao entardecer com ondas quebrando nas pedras',
model='google/gemini-omni-flash:fal',
)
first_frame_image e reference_images são mutuamente exclusivos.
O Gemini Omni Flash direto retorna o MP4 em videos[0].data. O
provider_task_id permite estender o vídeo em novos trechos, até 40 segundos:
clip = aigen.generate_video(
'Plano cinematográfico de uma cidade ao amanhecer',
model='gemini-omni-1.1-flash:gemini',
duration=10,
resolution='720p',
aspect_ratio='16:9',
)
extended = aigen.generate_video(
'Continue a cena por mais dez segundos',
model='gemini-omni-1.1-flash:gemini',
duration=10,
previous_interaction_id=clip.provider_task_id,
)
Entry genérico:
r = aigen.generate(prompt, mode='text', model='glm-5.2:zai')
r = aigen.generate(prompt, mode='video', model='bytedance/seedance-1.5-pro:kie')
r = aigen.generate(prompt, mode='video', model='bytedance/seedance-2.0-mini/text-to-video:atlascloud')
r = aigen.generate(audio_url, mode='stt', model='whisper-large-v3:groq')
mode: text · image · video · music · stt · tts · embedding · rerank.
Tool calling
generate_text aceita tools em um formato neutro e mensagens OpenAI-like. O
caller continua responsável por executar as funções; o aigen traduz chamadas,
resultados e histórico para cada provider.
import json
import aigen
TOOLS = [{
'name': 'get_weather',
'description': 'Consulta o clima atual de uma cidade',
'parameters': {
'type': 'object',
'properties': {
'city': {'type': 'string'},
},
'required': ['city'],
'additionalProperties': False,
},
}]
def get_weather(city):
return {'city': city, 'temp_c': 28}
messages = [{'role': 'user', 'content': 'Como está o tempo em São Paulo?'}]
for _ in range(8):
response = aigen.generate_text(
model='gemini-3.8-flash:gemini',
messages=messages,
tools=TOOLS,
tool_choice='auto',
)
messages.append(response.assistant_message)
if not response.tool_calls:
print(response.raw_content)
break
for call in response.tool_calls:
if call.arguments is None:
result = {
'ok': False,
'error': 'invalid_arguments',
'arguments_raw': call.arguments_raw,
}
elif call.name == 'get_weather':
result = {'ok': True, 'data': get_weather(**call.arguments)}
else:
result = {'ok': False, 'error': f'unknown_tool: {call.name}'}
messages.append({
'role': 'tool',
'tool_call_id': call.id,
'content': json.dumps(result, ensure_ascii=False),
})
else:
raise RuntimeError('limite de tool calls excedido')
Contrato de tools
Cada tool precisa de name string não vazia e parameters como JSON Schema.
Nomes duplicados e listas vazias são rejeitados com ProviderBadRequest.
tool_choice aceita:
'auto': o modelo decide entre texto e tools;'none': desabilita chamadas naquele request;'required': exige ao menos uma chamada;{'name': 'get_weather'}: exige uma função específica.
tool_choice exige uma lista tools não vazia, e uma função nomeada precisa
existir nessa lista.
Cada item de response.tool_calls contém id, name, arguments e
arguments_raw. O parse de arguments é estrito: JSON inválido resulta em
arguments=None e nunca deve ser executado. arguments_raw preserva o valor
original para diagnóstico.
O modelo pode retornar várias chamadas no mesmo turno. Execute todas e acrescente
uma mensagem role='tool' para cada id; os adapters Claude e Gemini agrupam
automaticamente resultados paralelos no formato nativo esperado.
response.assistant_message deve ser acrescentada ao histórico sem alterações.
Ela preserva metadados opacos necessários ao replay de thinking do Claude e
thought signatures do Gemini, mas continua serializável com json.dumps.
Suporte e limitações
- Suportado pela API Claude, Gemini e adapters OpenAI-compatible non-stream.
- Providers CLI (
claude_cli,codex_cli) não expõem este contrato. - Tool calling em adapters configurados com streaming ainda não é suportado.
files=não pode ser combinado commessages=nesta versão.- No Claude com thinking ativo, use
tool_choice='auto'ou'none'; escolhas'required'ou nomeadas são rejeitadas cedo peloaigenporque a API Anthropic não aceita essa combinação. - Passe a mesma lista
toolsem todas as etapas do loop.
Contrato
Sucesso retorna o dataclass do tipo. Falha levanta exception tipada.
| Mídia | Função | Retorno |
|---|---|---|
| Texto | generate_text |
TextResponse |
| Imagem | generate_image |
ProviderResponse |
| Vídeo | generate_video |
VideoResponse |
| Música | generate_music |
TTMResponse |
| STT | transcribe |
STTResponse |
| TTS | synthesize |
TTSResponse |
| Embedding | generate_embeddings |
EmbeddingResponse |
| Rerank | rerank |
RerankResponse |
Texto retorna content, raw_content, input_tokens, output_tokens,
total_tokens, reasoning_tokens, response_time, model, tool_calls,
finish_reason e assistant_message. finish_reason='tool_calls' indica que o
caller deve executar as funções e continuar o loop. Outras mídias seguem o mesmo
padrão de resposta padronizada e metadados técnicos quando o provider fornece.
Áudio segue o modelo do VideoResult (url ou data, conforme o provider):
TTS retorna audio: AudioResult (url/data/mime_type/duration) e TTM
retorna tracks: list[TrackResult] (mais title, image_url e lyrics).
Erros
ProviderError
├─ ProviderAuthError
├─ ProviderBadRequest
├─ ProviderBlocked
└─ ProviderRetryable
├─ ProviderRateLimit
└─ ProviderTimeout
Cada exception carrega .provider, .model, .status_code, .response_time
e .raw_error.
Catálogo
O catálogo em aigen/constants/{text,image,audio,video,embedding,rerank}.py contém fatos técnicos:
providers suportados, variável de ambiente da API key, modelos conhecidos e
capabilities. O dispatch considera capabilities.tools quando o campo está
declarado para o modelo. O catálogo não contém preço, crédito, tier ou regra de
cobrança.
Para registrar um modelo novo de um provider já suportado:
import aigen
aigen.register_model('text', 'openai', 'gpt-5.4')
O catálogo runtime default pode remover modelos e voltar ao estado inicial:
aigen.unregister_model('text', 'openai', 'gpt-5.4')
aigen.reset_registry()
Para manter configurações isoladas, crie um registry próprio e passe-o às factories de provider:
registry = aigen.CatalogRegistry()
registry.register_model('text', 'openai', 'gpt-custom')
provider = aigen.get_text_provider(
'gpt-custom:openai',
catalog_registry=registry,
)
Providers novos exigem implementação de classe e registro no código do pacote.
API keys
Cada provider lê a key de uma variável de ambiente (api_key_env no catálogo).
Defaults incluem 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,
DEAPI_API_KEY e ATLASCLOUD_API_KEY.
Logs
O pacote usa logging.getLogger(__name__) e não configura handler. Para ver logs,
o app habilita logging no boot:
import logging
logging.basicConfig(level=logging.INFO)
Stats de fim de chamada podem ser desligadas com LOG_PROVIDER_STATS=0.
Metadata
Release files for ai-generator 0.5.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ai_generator-0.5.2.tar.gz | 116.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ai_generator-0.5.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 275.2 kB
Release files / ai_generator-0.5.2.tar.gz
| Download URL | ai_generator-0.5.2.tar.gz |
|---|---|
| Size | 116.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
16144fefb236acdb62a739bc198ae8b06b6579fe4617c938fda1bb6b72473cb2
|
|
BLAKE2b-256 checksum How to use checksums |
cb92b0b4e72dd7a5baca664710d1bd649674558b0a8a23fdc5e032ab51493384
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.1
|
Release files / ai_generator-0.5.2-py3-none-any.whl
| Download URL | ai_generator-0.5.2-py3-none-any.whl |
|---|---|
| Size | 158.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
41a3fe343487dfea50b05214050b5045b1cd270949abed05bfdc09de441a4dd5
|
|
BLAKE2b-256 checksum How to use checksums |
9c3cab448fce665d4e5842ad12ae78afc2e223ef907c297a0080fe55f252238c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.1
|