Skip to main content

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.

Imagens de entrada nos CLIs de texto

claude_cli e codex_cli aceitam imagens em files= como Data URI Base64 ({'src': 'data:image/png;base64,...'}). Qualquer anexo que não seja imagem levanta ProviderError.

import base64
from pathlib import Path

src = 'data:image/png;base64,' + base64.b64encode(Path('foto.png').read_bytes()).decode()
r = aigen.generate_text(
    'Descreva a imagem',
    model='gpt-6.1-sol:codex_cli',
    files=[{'src': src}],
)

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 com messages= nesta versão.
  • No Claude com thinking ativo, use tool_choice='auto' ou 'none'; escolhas 'required' ou nomeadas são rejeitadas cedo pelo aigen porque a API Anthropic não aceita essa combinação.
  • Passe a mesma lista tools em 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.

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.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ai-generator 0.6.0
File Size Uploaded
ai_generator-0.6.0.tar.gz 120.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ai-generator 0.6.0
File Interpreter ABI Platform
ai_generator-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 283.5 kB

Release files / ai_generator-0.6.0.tar.gz

Download URL ai_generator-0.6.0.tar.gz
Size 120.9 kB
Tags Source
SHA-256 checksum
How to use checksums
80de52a7c46dfe63fe568de9184f4bba4f1b16e6e8c0fc9b965d2777b85b5a3f
BLAKE2b-256 checksum
How to use checksums
0d7583c47aa7de9612eabc840bb25a85f0ba8c945e4f8b336cbf272ae2eda7a4
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.6.0-py3-none-any.whl

Download URL ai_generator-0.6.0-py3-none-any.whl
Size 162.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cb08468cde9c346a0f1dd1aae8fd171ae3ffec9c14a4f4d7358505eab1f504fa
BLAKE2b-256 checksum
How to use checksums
0ff7006dd002bb490f493c873cab8b64b06994915d281e129f786f58ef6ce981
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.1

Release history Release notifications | RSS feed

0.6.1

2 release files

This release

0.6.0 This release

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page